En esta entrada os voy a enseñar cómo tengo actualmente montado el sistema de baterías de mi instalación solar.
La idea no es enseñar solo una gráfica bonita, sino explicar el funcionamiento real del sistema: la batería principal de litio-ion tipo Powerwall casera, el nuevo banco de baterías Deye LiFePO4 que he incorporado, cómo se comportan cuando una está trabajando y otra está en reposo, y cómo estoy viendo todo desde Home Assistant gracias a ESPHome y la domótica.
Este montaje forma parte de la evolución de mi sistema solar doméstico. Como siempre, es una instalación casera, hecha poco a poco, probando, midiendo y mejorando según van saliendo necesidades reales.
Qué tengo montado actualmente
En mi caso tengo un sistema formado por varias partes:
- Una batería principal de litio-ion tipo Powerwall casera.
- Un banco nuevo de baterías Deye LiFePO4.
- Inversores trabajando sobre el sistema de baterías.
- Un ESP32 leyendo datos del BMS mediante CAN bus.
- ESPHome para enviar esos datos a Home Assistant.
- Home Assistant para visualizar potencias, tensiones, estados, carga, descarga y comportamiento del sistema.
Algo importante es que no me interesa ver solo un porcentaje de batería. Lo realmente útil es poder ver qué está pasando en cada momento: si una batería está cargando, descargando, en reposo, qué voltaje tiene cada pack, cuánta potencia está entrando o saliendo y cómo se comporta el conjunto durante el día.
Desde Home Assistant puedo ver qué batería está entregando potencia, cuál está prácticamente en reposo, cómo cambia la potencia cuando hay consumo en casa, cuándo carga desde solar y cómo evoluciona el estado de carga.
Objetivo del proyecto
El objetivo principal era poder ver de forma clara qué está pasando con las baterías.
No quería tener solo un dato suelto. Lo interesante es poder ver:
- Voltaje de la batería.
- Porcentaje de carga.
- Potencia de carga o descarga.
- Corriente estimada.
- Diferencia de voltaje entre packs.
- Temperaturas.
- Ciclos.
- Si una batería está en reposo.
- Si una batería está trabajando.
- Si el sistema está consumiendo de batería.
- Si el sistema está cargando con solar.
- Cómo se ve todo esto en gráficas dentro de Home Assistant.
Con esto puedo entender mucho mejor el comportamiento de la instalación y detectar cosas raras antes de que sean un problema.
Materiales usados
En este montaje intervienen varios elementos:
- Batería de litio-ion tipo Powerwall casera.
- Banco de baterías Deye LiFePO4.
- Inversores solares.
- ESP32.
- Transceptor CAN compatible con ESP32.
- ESPHome.
- Home Assistant.
- BMS de las baterías.
- Gráficas y sensores personalizados en Home Assistant.
No todos los datos salen directamente del mismo sitio. Algunos datos los tengo por las entidades de la Powerwall, y otros salen directamente del banco Deye gracias al ESP32 leyendo el CAN bus del BMS.
Cómo se comunica con Home Assistant
La parte más interesante es que todo acaba entrando en Home Assistant.
Para ello uso ESPHome. En este caso, el ESP32 no está midiendo con pinzas externas ni importando sensores desde Home Assistant, sino que está leyendo directamente tramas CAN del BMS de las baterías Deye.
El ESP32 recibe esas tramas, interpreta los datos y publica sensores en Home Assistant.
Con esto puedo ver datos como:
- Voltaje medio del banco.
- Diferencia de voltaje entre packs.
- Corriente estimada.
- Potencia estimada.
- SOC estimado.
- Energía restante estimada.
- Voltaje del Pack 1.
- Datos completos del Pack 2.
- Temperaturas.
- Ciclos.
- Estado de salud del pack.
En mi instalación también tengo entidades de la Powerwall, por ejemplo:
sensor.jhb_501810019e79_bateria
sensor.jhb_501810019e79_potencia
sensor.jhb_501810019e79_voltaje
Y del banco Deye, según cómo Home Assistant haya nombrado las entidades, pueden aparecer con nombres similares a estos:
sensor.deye_banco_soc_estimado
sensor.deye_banco_potencia_estimada
sensor.deye_banco_voltaje_medio
sensor.deye_banco_corriente_estimada
sensor.deye_banco_diferencia_voltaje_packs
sensor.deye_banco_energia_restante_estimada
sensor.deye_pack_1_voltaje
sensor.deye_pack_2_voltaje
sensor.deye_pack_2_corriente
sensor.deye_pack_2_potencia
sensor.deye_pack_2_soc
sensor.deye_pack_2_soh
sensor.deye_pack_2_celda_max
sensor.deye_pack_2_celda_min
sensor.deye_pack_2_temp_max
sensor.deye_pack_2_temp_min
sensor.deye_pack_2_mos_temp
sensor.deye_pack_2_ciclos
En mi caso algunas entidades pueden tener un prefijo distinto si ya estaban renombradas en Home Assistant, por ejemplo sensor.inversor_deye_bms_deye_..., pero salen del mismo código ESPHome.
Estados que quiero visualizar
Una de las cosas que más me interesaba era diferenciar entre una batería que está en reposo y una batería que está trabajando.
Por ejemplo, si una batería está marcando muy poca potencia, podemos considerarla en reposo. En cambio, si empieza a entregar o absorber potencia, ya sabemos que está participando en la carga o descarga del sistema.
En el código del banco Deye he dejado la potencia normalizada de esta forma:
- Potencia positiva: batería cargando.
- Potencia negativa: batería descargando.
- Potencia cerca de cero: batería en reposo o prácticamente sin trabajar.
Esto es importante, porque algunos BMS o inversores muestran los signos al revés. En mi caso lo normalizo dentro del propio código para entenderlo siempre igual en Home Assistant.
Qué se ve en Home Assistant
En Home Assistant he preparado gráficas para ver la evolución de las baterías.
En ellas se puede ver:
- La potencia de la Powerwall.
- La potencia del banco Deye.
- El voltaje de cada banco.
- El porcentaje de carga.
- La corriente estimada.
- Los momentos de carga.
- Los momentos de descarga.
- Cuándo una batería está prácticamente en reposo.
- Cuándo otra batería está trabajando.
- Diferencias de voltaje entre packs.
- Temperaturas del pack.
Esto ayuda muchísimo porque no es lo mismo ver un dato instantáneo que ver una gráfica de varias horas. En la gráfica se entiende realmente cómo se comporta el sistema.
Código ESPHome actual
Este es el código ESPHome que tengo actualmente en uso para leer el banco Deye mediante CAN bus y publicar los datos en Home Assistant.
Las contraseñas no aparecen publicadas porque están guardadas en secrets.yaml mediante !secret.
esphome:
name: deye-bms
friendly_name: Deye
esp32:
board: esp32dev
framework:
type: esp-idf
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: deye-bms
password: !secret wifi_password
logger:
level: INFO
baud_rate: 0
api:
captive_portal:
ota:
- platform: esphome
password: !secret ota_password
web_server:
port: 80
canbus:
- platform: esp32_can
tx_pin: GPIO16
rx_pin: GPIO17
can_id: 4
bit_rate: 250kbps
on_frame:
# Deye 2: tramas estándar con datos completos
- can_id: 0x151
then:
- lambda: |-
float voltage = ((uint16_t(x[1]) << 8) | x[0]) / 10.0f;
int16_t raw_current = (int16_t)((uint16_t(x[3]) << 8) | x[2]);
float current_raw = raw_current / 10.0f;
float soc = ((uint16_t(x[5]) << 8) | x[4]) / 10.0f;
float soh = ((uint16_t(x[7]) << 8) | x[6]) / 10.0f;
float power_raw = voltage * current_raw;
// Deye bruto parece venir así:
// positivo = descarga
// negativo = carga
//
// Normalizamos:
// positivo = carga
// negativo = descarga
float current_norm = current_raw * -1.0f;
float power_norm = power_raw * -1.0f;
id(deye_2_voltage).publish_state(voltage);
id(deye_2_current).publish_state(current_norm);
id(deye_2_power).publish_state(power_norm);
id(deye_2_soc).publish_state(soc);
id(deye_2_soh).publish_state(soh);
// Banco completo estimado: 2 packs iguales
id(deye_bank_current_est).publish_state(current_norm * 2.0f);
id(deye_bank_power_est).publish_state(power_norm * 2.0f);
id(deye_bank_soc_est).publish_state(soc);
id(deye_bank_capacity_nominal).publish_state(10.24f);
id(deye_bank_energy_remaining_est).publish_state(10.24f * soc / 100.0f);
if (!isnan(id(deye_1_voltage).state)) {
id(deye_bank_voltage_avg).publish_state((id(deye_1_voltage).state + voltage) / 2.0f);
id(deye_bank_voltage_delta).publish_state(fabsf(id(deye_1_voltage).state - voltage));
}
- can_id: 0x201
then:
- lambda: |-
float cell_max = ((uint16_t(x[1]) << 8) | x[0]) / 1000.0f;
float cell_min = ((uint16_t(x[3]) << 8) | x[2]) / 1000.0f;
float temp_max = ((uint16_t(x[5]) << 8) | x[4]) / 10.0f;
float temp_min = ((uint16_t(x[7]) << 8) | x[6]) / 10.0f;
id(deye_2_cell_max).publish_state(cell_max);
id(deye_2_cell_min).publish_state(cell_min);
id(deye_2_temp_max).publish_state(temp_max);
id(deye_2_temp_min).publish_state(temp_min);
- can_id: 0x251
then:
- lambda: |-
int16_t raw_mos = (int16_t)((uint16_t(x[1]) << 8) | x[0]);
float mos_temp = raw_mos / 10.0f;
id(deye_2_mos_temp).publish_state(mos_temp);
- can_id: 0x401
then:
- lambda: |-
uint16_t cycles = ((uint16_t(x[3]) << 8) | x[2]);
id(deye_2_cycles).publish_state(cycles);
# Deye 1: solo voltaje por tramas extendidas
- can_id: 0x08028001
use_extended_id: true
then:
- lambda: |-
float voltage = ((uint16_t(x[0]) << 8) | x[1]) / 10.0f;
id(deye_1_voltage).publish_state(voltage);
if (!isnan(id(deye_2_voltage).state)) {
id(deye_bank_voltage_avg).publish_state((voltage + id(deye_2_voltage).state) / 2.0f);
id(deye_bank_voltage_delta).publish_state(fabsf(voltage - id(deye_2_voltage).state));
}
- can_id: 0x08020101
use_extended_id: true
then:
- lambda: |-
float voltage = ((uint16_t(x[0]) << 8) | x[1]) / 10.0f;
id(deye_1_voltage).publish_state(voltage);
if (!isnan(id(deye_2_voltage).state)) {
id(deye_bank_voltage_avg).publish_state((voltage + id(deye_2_voltage).state) / 2.0f);
id(deye_bank_voltage_delta).publish_state(fabsf(voltage - id(deye_2_voltage).state));
}
# Deye 2: voltaje extendido
- can_id: 0x08028002
use_extended_id: true
then:
- lambda: |-
float voltage = ((uint16_t(x[0]) << 8) | x[1]) / 10.0f;
id(deye_2_voltage).publish_state(voltage);
if (!isnan(id(deye_1_voltage).state)) {
id(deye_bank_voltage_avg).publish_state((id(deye_1_voltage).state + voltage) / 2.0f);
id(deye_bank_voltage_delta).publish_state(fabsf(id(deye_1_voltage).state - voltage));
}
- can_id: 0x08020102
use_extended_id: true
then:
- lambda: |-
float voltage = ((uint16_t(x[0]) << 8) | x[1]) / 10.0f;
id(deye_2_voltage).publish_state(voltage);
if (!isnan(id(deye_1_voltage).state)) {
id(deye_bank_voltage_avg).publish_state((id(deye_1_voltage).state + voltage) / 2.0f);
id(deye_bank_voltage_delta).publish_state(fabsf(id(deye_1_voltage).state - voltage));
}
sensor:
# Sensores calculados del banco Deye
- platform: template
name: "Banco Voltaje Medio"
id: deye_bank_voltage_avg
unit_of_measurement: "V"
accuracy_decimals: 1
state_class: measurement
device_class: voltage
update_interval: never
- platform: template
name: "Banco Diferencia Voltaje Packs"
id: deye_bank_voltage_delta
unit_of_measurement: "V"
accuracy_decimals: 1
state_class: measurement
device_class: voltage
update_interval: never
- platform: template
name: "Banco Corriente Estimada"
id: deye_bank_current_est
unit_of_measurement: "A"
accuracy_decimals: 1
state_class: measurement
device_class: current
update_interval: never
- platform: template
name: "Banco Potencia Estimada"
id: deye_bank_power_est
unit_of_measurement: "W"
accuracy_decimals: 0
state_class: measurement
device_class: power
update_interval: never
- platform: template
name: "Banco SOC Estimado"
id: deye_bank_soc_est
unit_of_measurement: "%"
accuracy_decimals: 0
state_class: measurement
update_interval: never
- platform: template
name: "Banco Capacidad Nominal"
id: deye_bank_capacity_nominal
unit_of_measurement: "kWh"
accuracy_decimals: 2
state_class: measurement
device_class: energy
update_interval: never
- platform: template
name: "Banco Energia Restante Estimada"
id: deye_bank_energy_remaining_est
unit_of_measurement: "kWh"
accuracy_decimals: 2
state_class: measurement
device_class: energy
update_interval: never
# Pack 1: solo se expone el voltaje real
- platform: template
name: "Pack 1 Voltaje"
id: deye_1_voltage
unit_of_measurement: "V"
accuracy_decimals: 1
state_class: measurement
device_class: voltage
update_interval: never
# Pack 2: entidades completas normalizadas
- platform: template
name: "Pack 2 Voltaje"
id: deye_2_voltage
unit_of_measurement: "V"
accuracy_decimals: 1
state_class: measurement
device_class: voltage
update_interval: never
- platform: template
name: "Pack 2 Corriente"
id: deye_2_current
unit_of_measurement: "A"
accuracy_decimals: 1
state_class: measurement
device_class: current
update_interval: never
- platform: template
name: "Pack 2 Potencia"
id: deye_2_power
unit_of_measurement: "W"
accuracy_decimals: 0
state_class: measurement
device_class: power
update_interval: never
- platform: template
name: "Pack 2 SOC"
id: deye_2_soc
unit_of_measurement: "%"
accuracy_decimals: 0
state_class: measurement
update_interval: never
- platform: template
name: "Pack 2 SOH"
id: deye_2_soh
unit_of_measurement: "%"
accuracy_decimals: 0
state_class: measurement
update_interval: never
- platform: template
name: "Pack 2 Celda Max"
id: deye_2_cell_max
unit_of_measurement: "V"
accuracy_decimals: 3
state_class: measurement
device_class: voltage
update_interval: never
- platform: template
name: "Pack 2 Celda Min"
id: deye_2_cell_min
unit_of_measurement: "V"
accuracy_decimals: 3
state_class: measurement
device_class: voltage
update_interval: never
- platform: template
name: "Pack 2 Temp Max"
id: deye_2_temp_max
unit_of_measurement: "°C"
accuracy_decimals: 1
state_class: measurement
device_class: temperature
update_interval: never
- platform: template
name: "Pack 2 Temp Min"
id: deye_2_temp_min
unit_of_measurement: "°C"
accuracy_decimals: 1
state_class: measurement
device_class: temperature
update_interval: never
- platform: template
name: "Pack 2 MOS Temp"
id: deye_2_mos_temp
unit_of_measurement: "°C"
accuracy_decimals: 1
state_class: measurement
device_class: temperature
update_interval: never
- platform: template
name: "Pack 2 Ciclos"
id: deye_2_cycles
accuracy_decimals: 0
state_class: measurement
update_interval: never
Explicación del código
El código anterior se encarga de leer el BMS de las baterías Deye mediante CAN bus.
La configuración principal del CAN está aquí:
canbus:
- platform: esp32_can
tx_pin: GPIO16
rx_pin: GPIO17
can_id: 4
bit_rate: 250kbps
Estoy usando un ESP32 con CAN a 250 kbps. A partir de ahí, ESPHome escucha diferentes tramas CAN y va publicando sensores.
Trama 0x151: datos principales del Pack 2
La trama 0x151 es una de las más importantes porque de ahí saco datos principales del Pack 2:
- Voltaje.
- Corriente.
- Potencia.
- SOC.
- SOH.
En el código también normalizo el signo de la corriente y la potencia.
El BMS parece enviar los datos de esta manera:
- Positivo = descarga.
- Negativo = carga.
Pero yo lo normalizo así:
- Positivo = carga.
- Negativo = descarga.
Por eso en el código aparece:
float current_norm = current_raw * -1.0f;
float power_norm = power_raw * -1.0f;
Después publico los sensores del Pack 2:
id(deye_2_voltage).publish_state(voltage);
id(deye_2_current).publish_state(current_norm);
id(deye_2_power).publish_state(power_norm);
id(deye_2_soc).publish_state(soc);
id(deye_2_soh).publish_state(soh);
Y también hago una estimación del banco completo considerando 2 packs iguales:
id(deye_bank_current_est).publish_state(current_norm * 2.0f);
id(deye_bank_power_est).publish_state(power_norm * 2.0f);
id(deye_bank_soc_est).publish_state(soc);
id(deye_bank_capacity_nominal).publish_state(10.24f);
id(deye_bank_energy_remaining_est).publish_state(10.24f * soc / 100.0f);
Esto me permite ver una estimación del banco completo, no solo del pack que está enviando todos los datos.
Trama 0x201: celdas y temperaturas
Con la trama 0x201 saco información de las celdas y temperaturas del Pack 2:
- Celda máxima.
- Celda mínima.
- Temperatura máxima.
- Temperatura mínima.
Estos datos son muy útiles para vigilar si el pack está equilibrado y si las temperaturas son normales.
Trama 0x251: temperatura MOS
Con la trama 0x251 obtengo la temperatura de los MOS del BMS.
Esto es interesante porque no solo importa la temperatura de las celdas. También es importante saber si la electrónica del BMS está trabajando caliente.
Trama 0x401: ciclos
Con la trama 0x401 obtengo los ciclos del Pack 2.
Este dato sirve para ir viendo el uso acumulado de la batería con el paso del tiempo.
Tramas extendidas: voltaje de Pack 1 y Pack 2
En mi caso, el Pack 1 no me está dando todos los datos completos como el Pack 2, pero sí consigo leer su voltaje mediante tramas extendidas.
Para el Pack 1 uso estas tramas:
can_id: 0x08028001
use_extended_id: true
y
can_id: 0x08020101
use_extended_id: true
Para el Pack 2 también leo voltaje extendido con:
can_id: 0x08028002
use_extended_id: true
y
can_id: 0x08020102
use_extended_id: true
Con estos voltajes calculo:
- Voltaje medio del banco.
- Diferencia de voltaje entre packs.
Esto es muy útil para saber si los dos packs van parejos o si hay una diferencia importante entre ellos.
Sensores que se crean en Home Assistant
El código crea sensores template en ESPHome. Estos sensores aparecen después en Home Assistant.
Los principales sensores del banco son:
Banco Voltaje Medio
Banco Diferencia Voltaje Packs
Banco Corriente Estimada
Banco Potencia Estimada
Banco SOC Estimado
Banco Capacidad Nominal
Banco Energia Restante Estimada
También se crea el voltaje del Pack 1:
Pack 1 Voltaje
Y sensores completos del Pack 2:
Pack 2 Voltaje
Pack 2 Corriente
Pack 2 Potencia
Pack 2 SOC
Pack 2 SOH
Pack 2 Celda Max
Pack 2 Celda Min
Pack 2 Temp Max
Pack 2 Temp Min
Pack 2 MOS Temp
Pack 2 Ciclos
En Home Assistant los nombres de entidad pueden variar según el nombre del dispositivo, pero normalmente quedan con un formato parecido a:
sensor.deye_banco_voltaje_medio
sensor.deye_banco_diferencia_voltaje_packs
sensor.deye_banco_corriente_estimada
sensor.deye_banco_potencia_estimada
sensor.deye_banco_soc_estimado
sensor.deye_banco_capacidad_nominal
sensor.deye_banco_energia_restante_estimada
sensor.deye_pack_1_voltaje
sensor.deye_pack_2_voltaje
sensor.deye_pack_2_corriente
sensor.deye_pack_2_potencia
sensor.deye_pack_2_soc
sensor.deye_pack_2_soh
sensor.deye_pack_2_celda_max
sensor.deye_pack_2_celda_min
sensor.deye_pack_2_temp_max
sensor.deye_pack_2_temp_min
sensor.deye_pack_2_mos_temp
sensor.deye_pack_2_ciclos
Ejemplo de tarjeta para Home Assistant
Para verlo de forma rápida en Home Assistant, se puede crear una tarjeta tipo Entities.
Hay que adaptar los nombres exactos de entidad si Home Assistant los ha renombrado, pero la idea sería esta:
type: entities
title: Sistema de baterías
entities:
- entity: sensor.jhb_501810019e79_bateria
name: Powerwall SOC
- entity: sensor.jhb_501810019e79_potencia
name: Powerwall potencia
- entity: sensor.jhb_501810019e79_voltaje
name: Powerwall voltaje
- entity: sensor.deye_banco_soc_estimado
name: Banco Deye SOC estimado
- entity: sensor.deye_banco_potencia_estimada
name: Banco Deye potencia estimada
- entity: sensor.deye_banco_corriente_estimada
name: Banco Deye corriente estimada
- entity: sensor.deye_banco_voltaje_medio
name: Banco Deye voltaje medio
- entity: sensor.deye_banco_diferencia_voltaje_packs
name: Diferencia voltaje packs
- entity: sensor.deye_banco_energia_restante_estimada
name: Energía restante estimada
- entity: sensor.deye_pack_1_voltaje
name: Pack 1 voltaje
- entity: sensor.deye_pack_2_voltaje
name: Pack 2 voltaje
- entity: sensor.deye_pack_2_soc
name: Pack 2 SOC
- entity: sensor.deye_pack_2_soh
name: Pack 2 SOH
- entity: sensor.deye_pack_2_potencia
name: Pack 2 potencia
- entity: sensor.deye_pack_2_temp_max
name: Pack 2 temperatura máxima
- entity: sensor.deye_pack_2_temp_min
name: Pack 2 temperatura mínima
- entity: sensor.deye_pack_2_mos_temp
name: Pack 2 temperatura MOS
- entity: sensor.deye_pack_2_ciclos
name: Pack 2 ciclos
Ejemplo de gráfica de potencia
También se puede usar una gráfica para ver cómo trabajan las baterías durante el día.
type: history-graph
title: Potencia baterías
hours_to_show: 12
refresh_interval: 30
entities:
- entity: sensor.jhb_501810019e79_potencia
name: Powerwall
- entity: sensor.deye_banco_potencia_estimada
name: Banco Deye
Si en tu Home Assistant la entidad aparece con otro prefijo, por ejemplo:
sensor.inversor_deye_bms_deye_banco_potencia_estimada
solo habría que cambiar esa línea en la tarjeta.
Qué se aprecia en las gráficas
En las gráficas se ve bastante bien el funcionamiento.
Hay momentos en los que una batería está prácticamente en reposo, mientras la otra está entregando energía o absorbiendo carga.
También se puede ver cómo cambia la potencia según el consumo de la casa, la producción solar y el estado de carga del sistema.
Esto me permite comprobar si el sistema se comporta como espero o si hay algo que revisar.
Por ejemplo:
- Si una batería debería estar cargando y no carga.
- Si una batería se descarga más de lo esperado.
- Si el voltaje cae demasiado.
- Si una batería permanece en reposo mientras la otra trabaja.
- Si el sistema cambia correctamente entre carga y descarga.
- Si los packs tienen diferencias de voltaje.
- Si las temperaturas suben más de lo normal.
Reposo, carga y descarga
En mi caso, para interpretar las gráficas considero que una batería está prácticamente en reposo cuando la potencia está cerca de cero.
No hace falta que sea exactamente 0 W, porque siempre puede haber pequeñas variaciones o ruido en la lectura.
Por ejemplo, se puede considerar reposo cuando la potencia está dentro de un margen pequeño alrededor de cero.
Lo importante es entender la tendencia:
- Si la potencia sube en positivo, el banco Deye está cargando.
- Si la potencia baja en negativo, el banco Deye está descargando.
- Si la potencia está cerca de cero, está prácticamente en reposo.
Ventajas de tenerlo en Home Assistant
Tener toda esta información dentro de Home Assistant tiene muchas ventajas:
- Puedo ver el sistema desde el móvil.
- Puedo crear gráficas.
- Puedo crear avisos.
- Puedo detectar comportamientos raros.
- Puedo comparar consumo, solar y batería.
- Puedo automatizar decisiones según SOC, potencia o estado.
- Puedo tener histórico de todo lo que ocurre.
- Puedo controlar si los packs van equilibrados.
- Puedo ver temperaturas y ciclos.
- Puedo ver si realmente una batería está trabajando o no.
Además, al estar integrado en la domótica, el sistema de baterías deja de ser algo aislado y pasa a formar parte de toda la casa.
Aviso importante de seguridad
Este proyecto trabaja con baterías, inversores y corriente continua.
La corriente continua en sistemas de baterías solares puede ser peligrosa. Un error de conexión, una mala protección o un cable mal dimensionado puede provocar calentamientos, chispazos, daños en equipos o incluso incendio.
Esta entrada no es una guía profesional de instalación eléctrica. Es una explicación de mi montaje y de cómo lo estoy monitorizando.
Si vas a hacer algo parecido, revisa bien:
- Sección de cable.
- Fusibles.
- Magnetotérmicos o protecciones DC adecuadas.
- BMS.
- Polaridad.
- Conexiones.
- Temperatura de cables.
- Capacidad real de las baterías.
- Configuración del inversor.
- Compatibilidad de baterías.
- Comunicación CAN.
- Protección del banco de baterías.
- Diferencia de voltaje entre packs antes de conectarlos.
Y si no lo tienes claro, consulta con un profesional.
Vídeo explicativo
En el vídeo enseño físicamente las baterías, cómo están colocadas, cómo tengo organizado el sistema y después pasamos a Home Assistant para ver las gráficas y sensores en funcionamiento.
También se puede ver cómo una batería puede estar en reposo mientras otra está trabajando, y cómo cambia la potencia según el momento.
Conclusión
Con este sistema puedo entender mucho mejor qué está ocurriendo con mis baterías solares.
Antes podía ver datos sueltos, pero ahora con Home Assistant y ESPHome tengo una visión mucho más clara del conjunto.
Puedo ver la Powerwall, el banco Deye, las potencias, los voltajes, los estados de carga y descarga, las temperaturas, los ciclos y la diferencia de voltaje entre packs.
Además, queda todo preparado para futuras automatizaciones y mejoras dentro de Home Assistant.
Como siempre, esto seguirá evolucionando poco a poco, porque cada vez que añado algo nuevo aparecen nuevas ideas para mejorar la instalación.
Si te gusta la domótica, la energía solar, las baterías caseras y Home Assistant, te invito a seguir el proyecto en el canal.

