Accu Monitor voor Home Assistant 7 Standalone
Omdat een echt goede en betrouwbare accumonitor essentieel is, ben ik deze zelf gaan bouwen voor een naadloze integratie met Home Assistant. Dit project meet niet alleen nauwkeurig de laad- en ontlaadstromen, het voltage en de temperatuur van de omvormers (of fungeert als vorstbeveiliging), maar beschikt ook over een geavanceerde SOC (State of Charge) berekening en een cycli counter om de levensduur en de actuele status van de accu perfect in de gaten te houden.
Gebruikte Hardware en Sensoren
Microcontroller: WT32-ETH01 (voor een stabiele bekabelde LAN-verbinding, al is een reguliere ESP32 ook mogelijk. https://amzn.to/4cFqi6D
Spanningsregelaar: LM2596HVS Buck Converter (om de accuspanning veilig terug te brengen naar 5V. https://amzn.to/4kMhNc1
Stroommeting (Shunt): 100A 75mV DC 0,5 Class shunt. Let op: stem de shuntcapaciteit af op je eigen maximale laad-/ontlaadstroom (in mijn geval blijf ik onder de 50A. https://nl.aliexpress.com...BjH6&gatewayAdapt=glo2nld
Monitoringsmodule: INA226 IIC I2C Bi-Directional Interface (voor de communicatie tussen de shunt en de ESP https://amzn.to/4aD2Q7u
Beveiliging: Zekeringhouder met een zekering van 1 á 2 Ampère. https://amzn.to/46jYFvZ
Temperatuursensoren: DS18B20 sensoren (inclusief benodigde 4.7K Ohm weerstand https://amzn.to/4kOmVMS
Aansluitschema & Instructies
1. Voeding en Voltage Meting
Trek een draad vanaf de pluspool van de accu en plaats hier direct de 1A-2A zekering tussen.
Sluit deze draad na de zekering aan op de input van de Buck Converter.
Trek vanaf ditzelfde punt (na de zekering) ook een directe draad naar de -VBS input van de INA226 module. Hiermee wordt straks het exacte voltage van de accu gemeten.
Trek een draad vanaf de minpool van de accu naar de min-input van de Buck Converter.
2. Buck Converter Afstellen (Cruciaal!)
⚠️ Let op: Voordat je de ESP aansluit, moet je de output van de Buck Converter met een multimeter exact afregelen op 5V. Doe je dit niet, dan frituur je de hardware!
3. ESP en Sensoren Aansluiten
Verbind de + en - 5V output van de (afgestelde) Buck Converter met de 5V in- en uitgang van de WT32-ETH01.
Voor de voeding van de INA226 verbind je de 3.3V out van de WT32-ETH01 met de VCC in van de INA226.
Koppel de communicatiepinnen van de INA226 aan de ESP:
ESP IO4 -> INA226 SCL
ESP IO14 -> INA226 SDA
Verbind de twee kleine aansluitingen op de 100A Shunt met de twee grote + en - aansluitingen op de INA226 module.
4. Temperatuursensoren (DS18B20) Toevoegen
Sluit de datalijn van de DS18B20 sensoren aan op poort IO1 van de ESP.
Plaats hierbij altijd de 4.7K Ohm weerstand (pull-up) tussen de datalijn en de 3.3V voeding voor een correcte werking.
Uitgebreide beschrijving van de YAML configuratie
Om deze hardware in Home Assistant via ESPHome te laten werken, is de YAML configuratie als volgt opgebouwd:
Netwerk & Basis: Configuratie van het vaste netwerk via de ethernet-component specifiek voor de WT32-ETH01.
I2C Bus & INA226: Definitie van de I2C-bus op de juiste IO-pinnen (SDA: 14, SCL: 4) en de INA226 sensor voor het uitlezen van het actuele voltage, de stroom (A) en het vermogen (W).
Temperatuur (1-Wire): Configuratie van de Dallas hub op pin IO1 om de DS18B20 temperatuursensoren nauwkeurig te loggen.
SOC Berekening (State of Charge): Een integratiesensor (zoals de integration of total_daily_energy sensor) gecombineerd met template sensoren in ESPHome om de stroom in/uit te integreren over tijd (Ah). Hiermee wordt een accuraat percentage (0-100%) berekend van de resterende accucapaciteit.
Cycli Counter: Globale variabelen (globals) en automatiseringsregels (on_value_range of on_state) binnen de ESPHome code. Deze detecteren wanneer de accu een volledige laad- en ontlaadcyclus heeft voltooid en hogen de interne teller op. Zo houd je de veroudering van de accu bij.
De Yaml
esphome:
name: "esp-accu-monitor"
friendly_name: "Accu Monitor Systeem"
esp32:
board: wt32-eth01
framework:
type: arduino
globals:
- id: current_soc
type: float
restore_value: true
initial_value: '60.0'
- id: total_discharged_ah
type: float
restore_value: true
initial_value: '24939.0'
- id: total_charged_ah
type: float
restore_value: true
initial_value: '0.0'
- id: total_charged_kwh
type: float
restore_value: true
initial_value: '0.0'
- id: total_discharged_kwh
type: float
restore_value: true
initial_value: '0.0'
logger:
level: INFO
baud_rate: 0
api:
encryption:
key: "esphom eencriptionkeyhere!"
ota:
- platform: esphome
password: "youreownotakeyhere"
web_server:
port: 80
# Haal de hekjes hieronder weg om de webpagina met een wachtwoord te beveiligen
# auth:
# username: "admin"
# password: "KiesEenVeiligWachtwoord"
ethernet:
type: LAN8720
mdc_pin: GPIO23
mdio_pin: GPIO18
clk: { pin: GPIO0, mode: CLK_EXT_IN }
phy_addr: 1
power_pin: GPIO16
i2c:
sda: 14
scl: 4
scan: true
id: bus_a
one_wire:
- platform: gpio
pin: 1
id: dallas_bus
# --- SYSTEEM BEDIENING ---
button:
- platform: restart
name: "Accu Monitor Herstarten"
id: restart_button
icon: "mdi:restart"
# --- SYSTEEM INFORMATIE ---
text_sensor:
- platform: template
name: "Software Versie"
icon: "mdi:tag-text-outline"
lambda: 'return std::string("ESP Accu Monitor V3.1");'
update_interval: 60s
- platform: version
name: "ESPHome Versie"
icon: "mdi:home-assistant"
- platform: ethernet_info
ip_address:
name: "Accu Monitor IP Adres"
mac_address:
name: "Accu Monitor MAC Adres"
# --- KALIBRATIE ---
binary_sensor:
- platform: template
id: checkpoint_100
internal: true
lambda: 'return id(accu_voltage).state > 27.60;'
filters: { delayed_on: 3min }
on_press:
then:
- if:
condition:
lambda: 'return id(raw_current).state > -1.0 && id(raw_current).state < 2.5;'
then:
- globals.set: { id: current_soc, value: '100.0' }
# --- SENSOREN & BEREKENINGEN ---
sensor:
- platform: dallas_temp
one_wire_id: dallas_bus
index: 0
name: "Temperatuur Powerstream 1"
filters: { offset: -3.3 }
- platform: dallas_temp
one_wire_id: dallas_bus
index: 1
name: "Temperatuur Powerstream 2"
filters: { offset: -2.9 }
- platform: uptime
name: "Accu Monitor Uptime"
id: sys_uptime
update_interval: 60s
- platform: ina226
address: 0x40
shunt_resistance: 0.000449 ohm
max_current: 100A
update_interval: 1s
bus_voltage:
name: "Accu Voltage"
id: accu_voltage
accuracy_decimals: 2
on_value_range:
- below: 25.12
above: 25.07
then: { globals.set: { id: current_soc, value: '20.0' } }
- below: 25.07
above: 25.00
then: { globals.set: { id: current_soc, value: '10.0' } }
- below: 25.00
then: { globals.set: { id: current_soc, value: '0.0' } }
current:
id: raw_current
internal: true
filters: { multiply: -1.0 }
on_value:
then:
- lambda: |-
static uint32_t last_time = millis();
uint32_t now = millis();
float dt_hours = (now - last_time) / 3600000.0;
last_time = now;
float amps = id(raw_current).state;
float volts = id(accu_voltage).state;
if (std::isnan(amps) || std::isnan(volts)) return;
float energy_wh = volts * amps * dt_hours;
float system_capacity = 400.0;
if (amps > 0) { // Laden
id(total_charged_ah) += (amps * dt_hours);
id(total_charged_kwh) += (energy_wh / 1000.0);
id(current_soc) += ((amps * dt_hours * 0.90) / system_capacity) * 100.0;
} else { // Ontladen
float amps_out = amps * -1.0;
id(total_discharged_ah) += (amps_out * dt_hours);
id(total_discharged_kwh) += ((energy_wh * -1.0) / 1000.0);
id(current_soc) -= (amps_out * dt_hours / system_capacity) * 100.0;
}
if (id(current_soc) > 100.0) id(current_soc) = 100.0;
if (id(current_soc) < 0.0) id(current_soc) = 0.0;
# --- TEMPLATE SENSOREN (LIVE STROOM & VERMOGEN) ---
- platform: template
name: "Accu Laadstroom (IN)"
unit_of_measurement: "A"
accuracy_decimals: 2
icon: "mdi:battery-charging-100"
lambda: 'return id(raw_current).state > 0 ? id(raw_current).state : 0.0;'
update_interval: 1s
- platform: template
name: "Accu Ontlaadstroom (UIT)"
unit_of_measurement: "A"
accuracy_decimals: 2
icon: "mdi:battery-arrow-down"
lambda: 'return id(raw_current).state < 0 ? (id(raw_current).state * -1.0) : 0.0;'
update_interval: 1s
- platform: template
name: "Accu Vermogen (Netto W)"
unit_of_measurement: "W"
accuracy_decimals: 0
icon: "mdi:flash"
lambda: 'return id(accu_voltage).state * id(raw_current).state;'
update_interval: 1s
- platform: template
name: "Accu Vermogen Laden"
unit_of_measurement: "W"
device_class: power
state_class: measurement
accuracy_decimals: 0
icon: "mdi:solar-power"
lambda: |-
float power = id(accu_voltage).state * id(raw_current).state;
return (power > 0) ? power : 0.0;
update_interval: 1s
- platform: template
name: "Accu Vermogen Ontladen"
unit_of_measurement: "W"
device_class: power
state_class: measurement
accuracy_decimals: 0
icon: "mdi:home-export-outline"
lambda: |-
float power = id(accu_voltage).state * id(raw_current).state;
return (power < 0) ? (power * -1.0) : 0.0;
update_interval: 1s
# --- TEMPLATE SENSOREN (STATISTIEKEN & TOTALEN) ---
- platform: template
name: "Accu State of Charge (SOC)"
id: accu_soc_sensor
unit_of_measurement: "%"
accuracy_decimals: 1
icon: "mdi:battery-high"
lambda: 'return id(current_soc);'
update_interval: 2s
- platform: template
name: "Accu Totaal Aantal Cycli"
unit_of_measurement: "Cycli"
accuracy_decimals: 2
icon: "mdi:sync"
lambda: 'return id(total_discharged_ah) / 400.0;'
update_interval: 10s
- platform: template
name: "Accu Capaciteit Geladen Totaal"
unit_of_measurement: "Ah"
accuracy_decimals: 1
icon: "mdi:battery-plus-variant"
lambda: 'return id(total_charged_ah);'
update_interval: 10s
- platform: template
name: "Accu Capaciteit Ontladen Totaal"
unit_of_measurement: "Ah"
accuracy_decimals: 1
icon: "mdi:battery-minus-variant"
lambda: 'return id(total_discharged_ah);'
update_interval: 10s
- platform: template
name: "Accu Energie Geladen Totaal"
unit_of_measurement: "kWh"
accuracy_decimals: 3
icon: "mdi:transmission-tower-import"
lambda: 'return id(total_charged_kwh);'
update_interval: 10s
- platform: template
name: "Accu Energie Ontladen Totaal"
unit_of_measurement: "kWh"
accuracy_decimals: 3
icon: "mdi:transmission-tower-export"
lambda: 'return id(total_discharged_kwh);'
update_interval: 10s
Omdat een echt goede en betrouwbare accumonitor essentieel is, ben ik deze zelf gaan bouwen voor een naadloze integratie met Home Assistant. Dit project meet niet alleen nauwkeurig de laad- en ontlaadstromen, het voltage en de temperatuur van de omvormers (of fungeert als vorstbeveiliging), maar beschikt ook over een geavanceerde SOC (State of Charge) berekening en een cycli counter om de levensduur en de actuele status van de accu perfect in de gaten te houden.
Gebruikte Hardware en Sensoren
Microcontroller: WT32-ETH01 (voor een stabiele bekabelde LAN-verbinding, al is een reguliere ESP32 ook mogelijk. https://amzn.to/4cFqi6D
Spanningsregelaar: LM2596HVS Buck Converter (om de accuspanning veilig terug te brengen naar 5V. https://amzn.to/4kMhNc1
Stroommeting (Shunt): 100A 75mV DC 0,5 Class shunt. Let op: stem de shuntcapaciteit af op je eigen maximale laad-/ontlaadstroom (in mijn geval blijf ik onder de 50A. https://nl.aliexpress.com...BjH6&gatewayAdapt=glo2nld
Monitoringsmodule: INA226 IIC I2C Bi-Directional Interface (voor de communicatie tussen de shunt en de ESP https://amzn.to/4aD2Q7u
Beveiliging: Zekeringhouder met een zekering van 1 á 2 Ampère. https://amzn.to/46jYFvZ
Temperatuursensoren: DS18B20 sensoren (inclusief benodigde 4.7K Ohm weerstand https://amzn.to/4kOmVMS
Aansluitschema & Instructies
1. Voeding en Voltage Meting
Trek een draad vanaf de pluspool van de accu en plaats hier direct de 1A-2A zekering tussen.
Sluit deze draad na de zekering aan op de input van de Buck Converter.
Trek vanaf ditzelfde punt (na de zekering) ook een directe draad naar de -VBS input van de INA226 module. Hiermee wordt straks het exacte voltage van de accu gemeten.
Trek een draad vanaf de minpool van de accu naar de min-input van de Buck Converter.
2. Buck Converter Afstellen (Cruciaal!)
⚠️ Let op: Voordat je de ESP aansluit, moet je de output van de Buck Converter met een multimeter exact afregelen op 5V. Doe je dit niet, dan frituur je de hardware!
3. ESP en Sensoren Aansluiten
Verbind de + en - 5V output van de (afgestelde) Buck Converter met de 5V in- en uitgang van de WT32-ETH01.
Voor de voeding van de INA226 verbind je de 3.3V out van de WT32-ETH01 met de VCC in van de INA226.
Koppel de communicatiepinnen van de INA226 aan de ESP:
ESP IO4 -> INA226 SCL
ESP IO14 -> INA226 SDA
Verbind de twee kleine aansluitingen op de 100A Shunt met de twee grote + en - aansluitingen op de INA226 module.
4. Temperatuursensoren (DS18B20) Toevoegen
Sluit de datalijn van de DS18B20 sensoren aan op poort IO1 van de ESP.
Plaats hierbij altijd de 4.7K Ohm weerstand (pull-up) tussen de datalijn en de 3.3V voeding voor een correcte werking.
Uitgebreide beschrijving van de YAML configuratie
Om deze hardware in Home Assistant via ESPHome te laten werken, is de YAML configuratie als volgt opgebouwd:
Netwerk & Basis: Configuratie van het vaste netwerk via de ethernet-component specifiek voor de WT32-ETH01.
I2C Bus & INA226: Definitie van de I2C-bus op de juiste IO-pinnen (SDA: 14, SCL: 4) en de INA226 sensor voor het uitlezen van het actuele voltage, de stroom (A) en het vermogen (W).
Temperatuur (1-Wire): Configuratie van de Dallas hub op pin IO1 om de DS18B20 temperatuursensoren nauwkeurig te loggen.
SOC Berekening (State of Charge): Een integratiesensor (zoals de integration of total_daily_energy sensor) gecombineerd met template sensoren in ESPHome om de stroom in/uit te integreren over tijd (Ah). Hiermee wordt een accuraat percentage (0-100%) berekend van de resterende accucapaciteit.
Cycli Counter: Globale variabelen (globals) en automatiseringsregels (on_value_range of on_state) binnen de ESPHome code. Deze detecteren wanneer de accu een volledige laad- en ontlaadcyclus heeft voltooid en hogen de interne teller op. Zo houd je de veroudering van de accu bij.
De Yaml
esphome:
name: "esp-accu-monitor"
friendly_name: "Accu Monitor Systeem"
esp32:
board: wt32-eth01
framework:
type: arduino
globals:
- id: current_soc
type: float
restore_value: true
initial_value: '60.0'
- id: total_discharged_ah
type: float
restore_value: true
initial_value: '24939.0'
- id: total_charged_ah
type: float
restore_value: true
initial_value: '0.0'
- id: total_charged_kwh
type: float
restore_value: true
initial_value: '0.0'
- id: total_discharged_kwh
type: float
restore_value: true
initial_value: '0.0'
logger:
level: INFO
baud_rate: 0
api:
encryption:
key: "esphom eencriptionkeyhere!"
ota:
- platform: esphome
password: "youreownotakeyhere"
web_server:
port: 80
# Haal de hekjes hieronder weg om de webpagina met een wachtwoord te beveiligen
# auth:
# username: "admin"
# password: "KiesEenVeiligWachtwoord"
ethernet:
type: LAN8720
mdc_pin: GPIO23
mdio_pin: GPIO18
clk: { pin: GPIO0, mode: CLK_EXT_IN }
phy_addr: 1
power_pin: GPIO16
i2c:
sda: 14
scl: 4
scan: true
id: bus_a
one_wire:
- platform: gpio
pin: 1
id: dallas_bus
# --- SYSTEEM BEDIENING ---
button:
- platform: restart
name: "Accu Monitor Herstarten"
id: restart_button
icon: "mdi:restart"
# --- SYSTEEM INFORMATIE ---
text_sensor:
- platform: template
name: "Software Versie"
icon: "mdi:tag-text-outline"
lambda: 'return std::string("ESP Accu Monitor V3.1");'
update_interval: 60s
- platform: version
name: "ESPHome Versie"
icon: "mdi:home-assistant"
- platform: ethernet_info
ip_address:
name: "Accu Monitor IP Adres"
mac_address:
name: "Accu Monitor MAC Adres"
# --- KALIBRATIE ---
binary_sensor:
- platform: template
id: checkpoint_100
internal: true
lambda: 'return id(accu_voltage).state > 27.60;'
filters: { delayed_on: 3min }
on_press:
then:
- if:
condition:
lambda: 'return id(raw_current).state > -1.0 && id(raw_current).state < 2.5;'
then:
- globals.set: { id: current_soc, value: '100.0' }
# --- SENSOREN & BEREKENINGEN ---
sensor:
- platform: dallas_temp
one_wire_id: dallas_bus
index: 0
name: "Temperatuur Powerstream 1"
filters: { offset: -3.3 }
- platform: dallas_temp
one_wire_id: dallas_bus
index: 1
name: "Temperatuur Powerstream 2"
filters: { offset: -2.9 }
- platform: uptime
name: "Accu Monitor Uptime"
id: sys_uptime
update_interval: 60s
- platform: ina226
address: 0x40
shunt_resistance: 0.000449 ohm
max_current: 100A
update_interval: 1s
bus_voltage:
name: "Accu Voltage"
id: accu_voltage
accuracy_decimals: 2
on_value_range:
- below: 25.12
above: 25.07
then: { globals.set: { id: current_soc, value: '20.0' } }
- below: 25.07
above: 25.00
then: { globals.set: { id: current_soc, value: '10.0' } }
- below: 25.00
then: { globals.set: { id: current_soc, value: '0.0' } }
current:
id: raw_current
internal: true
filters: { multiply: -1.0 }
on_value:
then:
- lambda: |-
static uint32_t last_time = millis();
uint32_t now = millis();
float dt_hours = (now - last_time) / 3600000.0;
last_time = now;
float amps = id(raw_current).state;
float volts = id(accu_voltage).state;
if (std::isnan(amps) || std::isnan(volts)) return;
float energy_wh = volts * amps * dt_hours;
float system_capacity = 400.0;
if (amps > 0) { // Laden
id(total_charged_ah) += (amps * dt_hours);
id(total_charged_kwh) += (energy_wh / 1000.0);
id(current_soc) += ((amps * dt_hours * 0.90) / system_capacity) * 100.0;
} else { // Ontladen
float amps_out = amps * -1.0;
id(total_discharged_ah) += (amps_out * dt_hours);
id(total_discharged_kwh) += ((energy_wh * -1.0) / 1000.0);
id(current_soc) -= (amps_out * dt_hours / system_capacity) * 100.0;
}
if (id(current_soc) > 100.0) id(current_soc) = 100.0;
if (id(current_soc) < 0.0) id(current_soc) = 0.0;
# --- TEMPLATE SENSOREN (LIVE STROOM & VERMOGEN) ---
- platform: template
name: "Accu Laadstroom (IN)"
unit_of_measurement: "A"
accuracy_decimals: 2
icon: "mdi:battery-charging-100"
lambda: 'return id(raw_current).state > 0 ? id(raw_current).state : 0.0;'
update_interval: 1s
- platform: template
name: "Accu Ontlaadstroom (UIT)"
unit_of_measurement: "A"
accuracy_decimals: 2
icon: "mdi:battery-arrow-down"
lambda: 'return id(raw_current).state < 0 ? (id(raw_current).state * -1.0) : 0.0;'
update_interval: 1s
- platform: template
name: "Accu Vermogen (Netto W)"
unit_of_measurement: "W"
accuracy_decimals: 0
icon: "mdi:flash"
lambda: 'return id(accu_voltage).state * id(raw_current).state;'
update_interval: 1s
- platform: template
name: "Accu Vermogen Laden"
unit_of_measurement: "W"
device_class: power
state_class: measurement
accuracy_decimals: 0
icon: "mdi:solar-power"
lambda: |-
float power = id(accu_voltage).state * id(raw_current).state;
return (power > 0) ? power : 0.0;
update_interval: 1s
- platform: template
name: "Accu Vermogen Ontladen"
unit_of_measurement: "W"
device_class: power
state_class: measurement
accuracy_decimals: 0
icon: "mdi:home-export-outline"
lambda: |-
float power = id(accu_voltage).state * id(raw_current).state;
return (power < 0) ? (power * -1.0) : 0.0;
update_interval: 1s
# --- TEMPLATE SENSOREN (STATISTIEKEN & TOTALEN) ---
- platform: template
name: "Accu State of Charge (SOC)"
id: accu_soc_sensor
unit_of_measurement: "%"
accuracy_decimals: 1
icon: "mdi:battery-high"
lambda: 'return id(current_soc);'
update_interval: 2s
- platform: template
name: "Accu Totaal Aantal Cycli"
unit_of_measurement: "Cycli"
accuracy_decimals: 2
icon: "mdi:sync"
lambda: 'return id(total_discharged_ah) / 400.0;'
update_interval: 10s
- platform: template
name: "Accu Capaciteit Geladen Totaal"
unit_of_measurement: "Ah"
accuracy_decimals: 1
icon: "mdi:battery-plus-variant"
lambda: 'return id(total_charged_ah);'
update_interval: 10s
- platform: template
name: "Accu Capaciteit Ontladen Totaal"
unit_of_measurement: "Ah"
accuracy_decimals: 1
icon: "mdi:battery-minus-variant"
lambda: 'return id(total_discharged_ah);'
update_interval: 10s
- platform: template
name: "Accu Energie Geladen Totaal"
unit_of_measurement: "kWh"
accuracy_decimals: 3
icon: "mdi:transmission-tower-import"
lambda: 'return id(total_charged_kwh);'
update_interval: 10s
- platform: template
name: "Accu Energie Ontladen Totaal"
unit_of_measurement: "kWh"
accuracy_decimals: 3
icon: "mdi:transmission-tower-export"
lambda: 'return id(total_discharged_kwh);'
update_interval: 10s
[ Voor 10% gewijzigd door Aengineering op 20-02-2026 22:53 ]