![]() |
| (Si quieres probar esta solución, al final dejo enlace de descarga del json NODE-RED) |
Cuando tu inversor «inteligente» en realidad no piensa
Si tienes placas y batería con Victron, seguro que conoces su modo "smart" ESS. Funciona, sí… pero su parte «inteligente» es limitada y a mí no me servía (no vendo a red). Yo quería decidir de verdad: cuándo merece la pena cargar de la red barata, cuándo tirar de batería y —sobre todo— cuánto hueco dejarle al sol para no desperdiciar ni un rayo. Y, ya puestos, sin maltratar las celdas.
Como el Smart ESS de Victron me daba poquísimo control sobre sus decisiones, me puse manos a la obra. Fui construyendo —con ayuda de la IA— mi propio gestor en Node-RED, y lo he ido ampliando hasta que por fin aprovecha la batería como yo quería. Te cuento cómo piensa.
Tres objetivos que tiran cada uno para su lado
Todo el sistema intenta equilibrar tres cosas que muchas veces se pelean entre ellas:
- Pagar poco: comprar energía en las horas baratas y esquivar las caras si la simulación de consumo así lo indica (en períodos largos de precio bajo, cargar de día para aprovechar energías renovables).
- Exprimir el sol: si el sol va a llenar la batería gratis, no llenarla antes con la red.
- Cuidar la batería: nada de descargas a fondo ni de tenerla siempre a tope.
Dos cerebros que no se pisan
La idea central es que hay dos cerebros trabajando a la vez, cada uno a su ritmo:
El Cerebro (cada media hora)
Es el estratega. Cada 30 minutos hace una especie de simulación de las próximas 48 horas: junta el precio de la luz, la previsión del sol y mi consumo, y con eso calcula cuánta batería conviene tener. Funciona como una hucha lista: la llena cuando es barato o va a sobrar sol, y la vacía cuando toca aprovecharla.
El Vigilante (cada pocos segundos)
Es el guardaespaldas. Mientras el Cerebro hace estrategia, el Vigilante mira la tensión real de las celdas casi en tiempo real. Si nota que están sufriendo, frena la descarga al instante —antes de que salte la protección de la batería— y además aprende: ajusta el suelo mínimo para que no vuelva a pasar. Utilizo dos baterías LifePo4 DIY de 16 celdas con BMS, con un smartshunt de Victron, por lo que esto es importante.
Los trucos que lo hacen «listo»
- Deja sitio al sol: si la previsión dice que va a sobrar generación, baja el objetivo para que quepa. Cuanto más me fío del sol, más hueco reserva (y eso lo ajusto con un mando de «agresividad»).
- Carga en el último momento: en las horas baratas no llena de golpe; espera por si el sol adelanta el trabajo. Así no compra de más.
- Aprende mi consumo: calcula la media de gasto de los últimos 7 días, así afina mucho mejor cuánta batería necesito de noche.
- Modo finde: los fines de semana y festivos —que con mi tarifa son baratos las 24 h— mantiene la batería en una banda sana del 30-80 % y prioriza cargar a mediodía aprovechando el sol, en vez de la red de madrugada.
- No se cree el sol a ciegas: si la previsión es de mala calidad, se fía menos de ella y va más sobre seguro.
A prueba de sustos
Un sistema que manda sobre una batería tiene que aguantar incluso cuando le fallan sus propios sensores. Si el medidor de batería deja de dar el porcentaje, el gestor lo deduce a partir de la tensión; y si todo falla, se pone en modo seguro y no hace tonterías. De hecho, hace poco una actualización me dejó sin el dato de batería… y el sistema siguió funcionando sin que me enterara.
¿Y merece la pena?
No te voy a vender que sea perfecto ni el óptimo teórico —eso no existe—. Pero toma buenas decisiones, una tras otra, razonando con los datos que tiene y protegiéndose de los que le faltan. Y lo más importante para mí: aprovecha la batería como yo quería y la trata con mimo, que es lo caro.
El ahorro se nota, y mucho.
Enlace de descarga del archivo NODE RED: FLOWS optimizado (aplica tu API KEY Solcast para que funcione)
Notas: Nuestro Multiplus trabaja en una fase L1, 230V; por un lado está conectado a la red en la entrada 1 y en LOut2 está conectada la casa y también los paneles solares (en caso de pérdida de la red general, los paneles siguen funcionando ya que funcionaría como un SAI mientras tenga batería). Esto es la evolución de lo que ya conté en «Automatizando el aprovechamiento solar con batería». Si te animas a montar algo parecido, ya sabes el lema: querer es poder… poder es crear.
___________________________________________________
Aquí los detalles para los más técnicos:
Gestor de energía (EMS)
Victron · Álava
Resumen de funcionalidad · flujo v61.16
Documento de Diseño del
Sistema (System Design Document) de la instalación fotovoltaica y de
almacenamiento. Refleja el comportamiento REAL del código en Node-RED
(sincronizado con flows_optimizado.json), no la intención teórica. Cualquier
ingeniero podría reimplementar el sistema completo a partir de aquí.
Visión Global del Ecosistema
Gestor de Energía Híbrido
(EMS) Bi-Capa. Dos cerebros asíncronos que se comunican por memoria compartida
(variables globales):
1.
Capa Macro (Cerebro Principal): estratega económico y meteorológico. Previsión a 48 h. Se ejecuta cada 30 min.
2. Capa
Micro (Vigilante Inteligente (v2.15)): guardaespaldas químico. Protege las celdas frente a caídas de tensión. Se
dispara con la corriente de batería del SmartShunt, limitado a 1 ejecución cada
5 s.
Hardware de referencia: banco LFP 16S,
~52,2 V nominal (3,26 V/celda), ~30 kWh. Umbrales de tensión usados en el
código: crítico 46 V (2,88 V/celda),
"lleno"/reset del Vigilante 50
V (3,13 V/celda), absorción/calibración 54 V (3,38 V/celda).
Módulo 1: Cerebro Principal (Oráculo Predictivo v61.16)
Frecuencia: cada 30 min (xx:00 y xx:30). Objetivo:
minimizar coste de importación de red, maximizar autoconsumo solar y cuidar la
salud de la batería.
1.1.
Ingesta de Datos y Clasificación
·
Tarifa FIJA: el sistema opera sobre una matriz de precios fija de 24 h (PRECIOS_FALLBACK, un patrón tipo
2.0TD: valle 0,084 / llano 0,116 / punta 0,195 €/kWh), que se trata de forma
cíclica para cubrir las 48 h. El código admite precios dinámicos vía msg.energy_prices / msg.energy_prices_tomorrow, pero actualmente no hay fuente dinámica
conectada, por lo que siempre usa la tarifa fija.
·
Agnosticismo de calendario: ignora el día de la semana; solo obedece a la
matriz de precios.
·
Clasificación de zonas (sobre los precios del día ordenados):
·
P3 (Valle): 25% de horas más baratas.
·
P1 (Punta): 25% de horas más caras.
·
P2 (Llano): 50% intermedio.
1.2. Motor de Integración Continua (Simulación 48h)
Recorre las próximas 48 h
calculando el Balance Neto horario
(Solar previsto − Consumo previsto). Si falta el consumo de una hora, usa el perfil horario real aprendido de los
últimos 7 días; si aún no existe, reparte el consumo medio diario; y solo en
última instancia asume un valor plano. De la curva
acumulada extrae:
·
Techo Ecológico (socMaxEcologico): a partir del pico de excedente solar futuro, deja hueco para no verter a
red.
·
Pulmón Elástico (hueco dinámico): con agresividad_reserva_solar
= 60, el hueco reservado al sol es dinámico entre 0% y 30% (NO un 20%
fijo). TARGET_PICO_DIARIO = 100 − hueco, por lo que el techo varía entre 70% y 93% (tope del 93%, protege la
bateria LFP y evita verter sol). La
calibración mensual sí puede llegar al 100% (lo necesita para sincronizar
el BMS); en operación normal el techo se limita al 93%, por lo que aun sin previsión de sol el objetivo máximo es 93%,
no 100%.
·
Supervivencia (socSupervivenciaP2): SOC necesario ahora para no
bajar del suelo en ningún momento del tramo caro hasta el próximo valle. (Hasta
la v61.15 se exigía además llegar al valle con reserva_llegada_pct; se eliminó en la v61.16 porque en P2 se cumplía
comprando a llano justo antes del valle.) Desde la v61.0 se calcula también dentro del valle (antes quedaba
muerta justo cuando había que decidir la compra), y es la que guía cuánta
energía barata comprar. El techo ecológico solo la limita, ya no la fuerza.
·
Oasis Global (socOasisGlobal): déficit máximo en 48 h (permite comprar hoy si mañana no hay sol ni P3
suficiente).
1.3. Árbol de Decisión ("La Hucha Inteligente")
·
P1:
vaciado activo hasta el suelo retenido (el suelo, o la reserva para apagones si
está cubierta). Nunca compra.
·
P2:
solo compra si hay horas punta antes
del próximo valle, y solo lo que hace falta para no tocar el suelo en ellas (suelo retenido + bajón en punta,
con el techo ecológico como límite). Si lo que viene es valle, retiene y no
compra: la casa pagaría lo mismo tirando de red.
·
P3 diurno (10:00–18:00): acelerador solar JIT. Si el tiempo hasta el
ocaso/fin de P3 ≤ horas necesarias de carga (+0,5 h de margen), inyecta carga
hasta el objetivo diario; si no, espera y permite que el SOC caiga hasta un
colchón de salud (min(35%, techo)).
·
Objetivo nocturno: lo fija solo
la supervivencia (la simulación). No hay colchón de salud que fuerce
compras de noche: esa función la cubre el Modo Valle Prolongado en los días
baratos. El colchón del 35% sigue existiendo de día, pero como tope que limita, no como objetivo que compre.
·
P3 nocturno/madrugada: si el bloque P3 alcanza el amanecer, delega la
carga al sol de mañana; si no, aplica Just-In-Time
sobre la potencia neta (potencia
inversor − consumo medio), arrancando solo si las horas baratas restantes ≤
horas necesarias (+1 h de margen).
Modo Valle Prolongado (findes y precio plano 24 h)
En 2.0TD los fines de semana y festivos nacionales son
valle las 24 h. Una capa de calendario marca sábados, domingos y festivos
nacionales como tarifa plana, y cuando el precio del día es plano (rango <
0,005 €) se activa el Modo Valle
Prolongado, que solo afecta a esos
días (entre semana todo sigue igual):
·
Banda saludable 30-80% (en vez de 20-93%): sin presión económica, se
cicla suave por salud de la batería.
·
Carga diurna 12-17 h dejando hueco al sol: el objetivo de mediodía es 80% − excedente solar esperado,
de modo que la red complementa al
sol sin robarle sitio.
·
Sin carga nocturna, salvo que el precio vaya a subir en < 8 h (entonces carga preventiva).
Mejoras generales (también entre
semana): el "oasis" de pre-compra se acota al próximo valle con capacidad de recarga (≥ 4 h) para no
sobre-comprar; y la previsión solar se pondera
por confianza (fuente sintética → se asume menos sol y se carga algo más).
Agnóstico a la tarifa: la matriz de precios de 24 h vive en un único
nodo de configuración (CONFIGURACION GENERAL (EDITAR AQUI)). Al cambiar
precios o tramos ahí, todo el sistema (clasificación P1/P2/P3 por percentiles,
detección de valle, findes, JIT, supervivencia) se recalibra automáticamente — no hay que tocar la lógica. Lo único
que sigue ligado a la hora es la ventana de luz solar (10-18 h), que depende
del sol, no de la tarifa.
1.4.
Cortafuegos y Latch
·
Corte Táctico de Subida (Guillotina): si la hora siguiente es punta y estamos en el minuto ≥ 20, deja de cargar de red sin soltar lo retenido: el suelo se
queda en el menor entre el objetivo de la franja y el SOC actual. Desde la
v61.16 no actúa en el paso de valle a llano: allí el solape cuesta céntimos y
en cambio mataba la carga de la última hora de valle.
·
Latch Guardián (corregido): el comando se envía al inversor solo si socFinal difiere del ÚLTIMO valor realmente enviado (ultimoSocPayload) y además
se cumple alguna de: ha cambiado la hora, el salto es ≥ 5%, o es una emergencia
(corte táctico o calibración). Persiste ultimoSocPayload y ultimaHoraEnviada. Esto garantiza que el límite del inversor
refleje el objetivo y re-afirma el valor al menos una vez por hora, sin
reescrituras innecesarias.
·
Suelo absoluto = soc_minimo_base_permanent (def. 20) + offset de seguridad. Techo = TARGET_PICO_DIARIO (o 100% en
calibración).
Módulo 2: Vigilante Inteligente (Arco Reflejo v2.12)
Disparo: corriente de batería del SmartShunt
(battery/274 /Dc/0/Current), pasada por un nodo delay que
la limita a 1 ejecución cada 5 s
(con drop). Así, 3 strikes = 15 s reales. Objetivo: proteger frente a caídas de
tensión (LVD) y adaptar el suelo mínimo si la batería se degrada.
2.1. Telemetría y Filtro de Espejismos (Sag)
·
Lee la corriente del SmartShunt (convención:
negativo = descarga) y, de variables globales, el voltaje (Volt_bateria) y el SOC
(current_soc).
·
Filtro de amperaje: umbral de sufrimiento −15 A (≈ 700–800 W de extracción). Si la batería descarga a más de
15 A, una caída de tensión se considera "Espejismo por Carga" (Voltage Sag) y se perdona.
2.2. Detección de Fatiga y Arco Reflejo
·
Si el voltaje
cae por debajo de VOLTAJE_CRITICO = 46 V (siendo > 0), no es un sag y la batería está descargando (entre 0 y −15
A), se anota un strike. El reflejo
solo evalúa si el SOC está en zona de peligro (≤ suelo + 20).
·
Tras 3 strikes consecutivos (15 s) dispara
el Arco Reflejo, con dos acciones:
1. Freno
inmediato: escribe en el inversor
un MinimumSocLimit = max(nuevo suelo, SOC actual + 5), forzando a detener
la descarga al instante y tomar energía de la red (protege las celdas de un
corte brusco del BMS).
2. Aprendizaje: sube el suelo permanente (soc_minimo_base_permanent) +5 puntos.
·
Reset no rencoroso: si en cualquier momento el voltaje sube de 46 V,
deja de ser sag, o cesa la descarga, el contador de strikes se borra a cero
(tiempo continuo).
2.3.
Evolución Estructural (Aprendizaje)
·
El reflejo
solo actúa una vez por descarga: un
candado (bloqueo_aprendizaje) impide volver a subir el suelo durante el mismo
ciclo de descarga.
·
El candado se
libera cuando el voltaje supera VOLTAJE_LLENO = 50 V (la batería se está cargando), permitiendo otro
+5 en un ciclo futuro si sigue habiendo sufrimiento.
·
El suelo
subido es permanente y no baja solo;
se restaura manualmente con el nodo "Borrado_variables"
(vuelve soc_minimo_base_permanent a 20% y limpia el estado del Vigilante).
Módulo 3: Previsión Solar y Consumo
Objetivo: alimentar el Motor de Integración del Cerebro. Salida normalizada a pares [timestamp_ms, Wh].
·
Previsión Solar (jerarquía de fallback): Solcast API → caché de Solcast → previsión de
Victron VRM → curva sintética matemática (campana senoidal con factor
estacional). Se suaviza la curva horaria. El estado del nodo indica la fuente
activa (verde/amarillo/rojo).
·
Previsión de Consumo: previsión de Victron VRM (vrm_consumption_fc), normalizada
y filtrada a futuro; si falta, genera un perfil sintético (~12 kWh/día con
curva horaria). El Cerebro asume 500 W en horas diurnas
sin dato.
Módulo 4: Sistema de Calibración (v1.3)
Objetivo: evitar el drift del
BMS/SmartShunt, inherente a la química LFP (curva de descarga muy plana).
·
Detección de batería llena, por dos vías:
·
Software: SOC ≥ 99%.
·
Física (corriente de cola): SOC ≥ 95% y
voltaje ≥ VOLTAJE_ABSORCION (54,0 V) y
corriente absoluta ≤ 3 A (la batería ya rechaza carga).
·
Hacen falta 2 ciclos consecutivos para confirmar;
entonces se resetea el contador de 25 días y se baja la bandera CALIBRANDO_BATERIAS.
·
Forzado mensual: si pasan 25 días sin alcanzar
el 100%, dentro de las 8 horas diurnas
más baratas (09:00–19:00) activa CALIBRANDO_BATERIAS
= true. El Cerebro lo detecta y, en
modo de autoridad máxima, ignora techo ecológico/hueco/tarifa y fija socObjetivo = 100% hasta que se
confirma la sincronización.
Módulo 5: Robustez y Aprendizaje
5.1. Failsafe de SOC/Tensión (banco 16S). El nodo "Failsafe
SOC/Tensión" es la fuente ÚNICA de current_soc y Volt_bateria efectivos. En
operación normal pasa los valores reales del SmartShunt; si éste deja de
refrescar (> 30 s) deduce el SOC de la tensión con una tabla OCV de 16S,
usando una tensión redundante del VE.Bus
(vebus/275 /Dc/0/Voltage) para
sobrevivir a un fallo del SmartShunt. La estimación se compensa por corriente
(si está disponible) y se acota en la zona plana. Si no hay ni SOC ni tensión
de ninguna fuente, el Cerebro entra en modo
seguro (suelo prudente 50%, no opera). La protección por tensión del
Vigilante sigue activa mientras exista cualquier fuente de tensión.
Además, un guardián de tensión ligero (cada 5 s, independiente de la
corriente) vigila la tensión efectiva cuando la corriente del SmartShunt está
obsoleta: si cae por debajo de 47 V
durante 15 s, fuerza un suelo de emergencia del 50% para detener la
descarga. Cubre el caso de muerte del SmartShunt, en el que el Vigilante
principal no puede ejecutarse (no recibe corriente).
5.2.
Aprendizaje de consumo. (a) Media diaria de 7 días: mide el consumo AC real de la casa (com.victronenergy.system), lo integra a total diario y mantiene la media móvil de los
últimos 7 días (consumo_diario_medio_kwh), persistida en /data/nodered_consumo7d.json (sobrevive a reinicios y actualizaciones de firmware; se guarda 1
vez/hora). Es la cifra de consumo de referencia cuando no hay previsión real —
mucho más fiable que los 12 kWh fijos para cargar de noche a ciegas. (b) EWMA de carga base (consumo_base_w): media exponencial de la descarga nocturna, como señal secundaria.
5.3.
Suelo aprendido con histéresis. El Vigilante sube
el suelo (soc_minimo_base_permanent) +5 ante
sufrimiento. Tras una carga sana/sincronizada, el suelo se relaja −5 (nunca por debajo del nivel confirmado). Si tras relajar
vuelve a sufrir a ese nivel en la siguiente descarga, ese nivel queda confirmado/bloqueado (soc_floor_confirmado); los topes superiores nuevos sí se re-evalúan en cargas
posteriores. Maximiza la capacidad usable sin perder protección.
5.4.
Previsión sintética calibrada para Álava. La curva
de último recurso (cuando fallan Solcast, caché y VRM) usa factores mensuales
rebajados por la nubosidad cantábrica (día medio, no día despejado), para no
quedarse corto de batería en invierno asumiendo un sol que no llega.
Anexo:
Capacidad real del banco (v9.0)
El Cerebro convierte kWh en puntos de SOC
en siete sitios, y el Failsafe necesita saber si el porcentaje del SmartShunt
sigue siendo cierto. Ambas cosas dependen de cuántos kWh tiene el banco de verdad, que no es un dato fijo: son
dos baterías de 15 kWh en paralelo, cada una con su BMS, y el banco puede
perder capacidad despacio (degradación) o de golpe (una se desconecta).
Cómo
se mide
Dos anclas físicas, no derivadas:
|
Ancla |
Qué
es |
|
Alta |
el
SmartShunt sincroniza a 100 % → ConsumedAmphours
= 0 |
|
Baja |
la tensión
en reposo baja de cap_v_zona_fiable (52,5 V),
donde la curva LFP sí tiene
pendiente |
capacidad_Ah = Ah_consumidos / (1 − SOC_ancla/100), suavizado con EWMA y filtrado entre el 35 % y el 110 % de la
nominal. Se muestrea solo con |I| ≤ cap_i_max_muestra (10 A) y compensando r_pack.
Por
qué el ancla tiene que estar abajo
La pendiente de la curva OCV decide la
precisión, y varía un orden de magnitud:
|
Tramo |
mV
por punto de SOC |
Error
si la tensión falla ±50 mV |
|
10-20
% |
100 |
±0,5
puntos |
|
20-30
% |
30 |
±1,7
puntos |
|
30-90 % |
15-20 |
±2,5 a
±3,3 puntos |
Anclando a 52,2 V (20 %) el error de
capacidad es de ±0,6 %. Con el suelo
del EMS en 20-30 %, esa zona se alcanza en cada ciclo profundo.
Historial
de los intentos anteriores
·
v7.0 — ancla baja fija en 51,5 V (13 %
de SOC): inalcanzable, porque el EMS defiende un suelo del 20-30 %. Nunca llegó
a medir.
·
v7.1 — ancla adaptativa al mínimo del
ciclo: se resolvía el problema de alcance, pero el ancla caía en la zona ciega (15 mV por punto). Midió 11,3 kWh en un banco de 30, y como el
Cerebro divide por la capacidad, multiplicó por 2,7 sus necesidades de compra.
·
v8.x — ΔAh / ΔSOC con los dos números del shunt: correcto pero tautológico. El shunt no mide el SOC, lo deriva de esos mismos Ah y
de su capacidad configurada, así que devolvía siempre esa cifra. No habría
detectado ni la degradación ni una batería caída.
·
v9.0 — Ah reales contra un ancla de
tensión en la zona con pendiente.
Independiente del shunt, y por eso ve las dos averías con el mismo cálculo, sin
casos especiales.
Qué
se hace con la medida
1.
El Cerebro la usa como factor kWh ↔ % en cuanto hay cap_muestras_fiable (5) muestras.
2.
El Failsafe corrige el SOC: el porcentaje del shunt se calcula contra
su capacidad configurada, así que si el banco ya no la tiene, miente. Los Ah
consumidos sí son reales, de modo que se rehace la división: SOC_real
= 100 × (1 − Ah / capacidad_medida). Con el banco sano
la medida coincide con la nominal y la corrección es nula; con una batería
caída, un «50 %» del shunt se convierte en el 0 % que realmente es, y el suelo vuelve a proteger. La fuente
pasa a real_corr cuando la corrección
supera los 2 puntos.
3.
El panel muestra la capacidad en kWh y en % de la nominal, y avisa por
debajo de cap_alarma_pct (80 %). El histórico
semanal la guarda, así que con los años ese fichero es la curva de degradación del banco.
Reparto
de papeles entre el Vigilante y el Failsafe
Se parecen y conviene no confundirlos:
|
|
Vigilante
(Vigila
SOC real) |
Failsafe
(Failsafe
SOC/Tensión) |
|
Qué
vigila |
la
salud química de la batería |
que
el sistema siga funcionando |
|
Lo
dispara |
la
corriente del SmartShunt |
un
inject cada 5 s |
|
Si
cae el shunt |
deja de ejecutarse |
sigue
latiendo |
|
Qué hace |
frena la
descarga cuando la tensión se hunde |
elige la
fuente del SOC, lo corrige con la capacidad real y lo publica |
Por eso el guardián de tensión vive dentro del Failsafe aunque se parezca al
Vigilante: es su relevo cuando este se queda sin disparador. Y por eso la corrección del SOC por capacidad real
vive también en el Failsafe, que es el nodo que define qué significa current_soc; el Vigilante la hereda al leerlo.
Desde la v61.10, la publicación de Amperios_bateria se ha sacado del Vigilante a un nodo de datos propio (Amperios
a global). El Vigilante es ahora un consumidor puro: un return temprano suyo ya no puede dejar sin corriente al Failsafe ni al
medidor de capacidad.
Módulo
8: Configuración única, memoria y estado visible (v61.3)
8.1.
Un solo nodo que editar
Todos los parámetros ajustables viven en CONFIGURACION GENERAL (EDITAR
AQUI), junto a los precios y los festivos
nacionales. Publica cuatro globales:
|
Global |
Contenido |
|
tarifa_horaria |
24
precios (€/kWh) de día laborable |
|
tarifa_horaria_finde |
24
precios de findes y festivos (plano) |
|
festivos_fijos |
festivos
nacionales de fecha fija (MM-DD) |
|
config |
43
parámetros ajustables agrupados por área |
Cada nodo lee la configuración con cfg(clave,
defecto): si la clave falta, usa su valor por defecto,
de modo que añadir o quitar claves nunca
rompe el flujo. Ya no quedan constantes repartidas por el Cerebro, el
Vigilante, el Failsafe, el Calibrado, el estimador de capacidad ni el
procesador de previsión.
8.2.
Árbitro de prioridades del suelo
Tres nodos pueden escribir MinimumSocLimit. Antes ganaba el último en hablar, aunque fuese el menos urgente.
Ahora todos pasan por solicitarSuelo(valor, prioridad,
motivo, origen):
|
Prioridad |
Quién
la usa |
Caduca
a |
|
2 |
Vigilante
(reflejo por tensión), Guardián del Failsafe, Modo Seguro |
30
min |
|
1 |
Calibración
mensual |
60
min |
|
0 |
Cerebro
(decisión económica normal) |
— |
Una petición de prioridad inferior a la
vigente se descarta (el Cerebro lo
anota como arbitro_bloqueo en el debug) hasta
que la urgente caduca. El árbitro es además quien registra ultima_carga_red cada vez que un suelo concedido queda por encima del SOC actual:
ahí queda grabado cuándo, a cuánto,
desde qué SOC, por qué y qué nodo lo pidió.
8.3.
Persistencia: nada se pierde al reiniciar
Tres ficheros en /data (sobreviven a reinicios y a actualizaciones de firmware):
|
Fichero |
Contenido |
|
nodered_estado_bateria.json |
suelo
permanente, suelo confirmado y pendiente, fecha del último 100 %, racha de
cargas completas, última carga de red y histórico
semanal |
|
nodered_consumo7d.json |
consumo
de los últimos 7 días, día en curso y perfil
horario (medio y de los 7 días) |
|
nodered_capacidad.json |
capacidad
real medida del banco (formato v9) |
El histórico
guarda una entrada por semana ISO
(consumo medio, capacidad, suelo aprendido y confirmado) y purga por antigüedad al superar config.historico_semanas (52 = un año). Los valores se redondean y se fechan por día, no por
milisegundo, para que el fichero solo se reescriba cuando algo cambia de
verdad: es amable con la flash del GX.
El restaurador levanta la bandera estado_bateria_restaurado antes de que el guardado pueda actuar, así que un arranque en frío
nunca machaca el fichero con valores por defecto. Si el fichero aún no existe
(primer arranque), el nodo de lectura emite msg.error en vez de callarse y el restaurador levanta la bandera igualmente:
el primer guardado lo crea.
8.4.
Consumo real en lugar de constantes
El nodo Integrador consumo diario acumula la potencia AC cada 30 s en dos
sitios: el total del día y la hora en
curso. Al cambiar de día cierra la jornada, la mete en un anillo de 7 días
y recalcula la media diaria y el perfil
horario medio (consumo_perfil_horario_w, 24
valores).
Ese perfil es ahora la fuente de reserva en
dos sitios:
·
El Cerebro rellena con él cualquier hora sin previsión de consumo.
·
El normalizador de consumo fabrica con él la previsión sintética
cuando VRM no responde, en vez de la vieja curva inventada valle/punta. El
estado del nodo indica siempre la procedencia: VICTRON
FORECAST, ESTIMADO/perfil real
7d o ESTIMADO/curva generica.
8.5.
Frescura de sensores y de la previsión
·
La tensión lleva marca de
tiempo (Volt_bateria_ts, escrita por el
Failsafe). El Vigilante no actúa con
lecturas más viejas de config.stale_ms — una tensión congelada no es una tensión baja — y el Calibrado no da por llena la batería si
la tensión o la corriente están obsoletas.
·
«No llega mensaje» no es «sensor muerto» (v61.7). Todos los paths del SmartShunt usan onlyChanges: si no llega nada, es que el valor no ha cambiado, y un valor quieto sigue siendo válido. En descarga
lenta /Soc (entero) emite cada ~31 min y /Dc/0/Voltage (2 decimales) cada ~21 min, porque la meseta LFP solo mueve 15 mV
por punto de SOC; únicamente la corriente (3 decimales) cambia sin parar.
Aplicarles a todas el plazo de 30 s daba el shunt por muerto casi siempre —de
noche, sistemáticamente— y metía el sistema en Failsafe permanente. Ahora el criterio es el servicio entero: si cualquiera de sus señales ha llegado dentro
de config.shunt_stale_ms (5 min), el
shunt está vivo y el último valor de cada una vale. El estimador de capacidad
ni siquiera necesita el chequeo: solo se ejecuta cuando el shunt publica /ConsumedAmphours, así que su propia ejecución ya es la prueba de vida.
·
Escalones de degradación (v61.8). El SOC
efectivo se busca en este orden: SmartShunt → servicio system del GX (que sigue al monitor de batería activo; con el ajuste en Automático, si el shunt cae el GX pasa
al contador del MultiPlus) → tabla OCV sobre la tensión → modo seguro. Cada
servicio tiene su propia prueba de
vida sobre sus propios paths, de modo que un system que se congelara al morir el shunt se detectaría y se caería al
escalón de OCV en vez de confiar en un SOC muerto.
·
En la misma línea, la tensión
del shunt se prefiere siempre a la
del VE.Bus cuando el shunt está vivo, en vez de coger la lectura más reciente
(el VE.Bus refresca más a menudo y ganaba casi siempre, midiendo al otro lado
de cables y fusible).
·
La previsión solar también envejece: su confianza se multiplica por
0,90 / 0,80 / 0,70 pasadas 6, 12 y 24 h desde la última actualización.
8.6.
El suelo de emergencia ya no rebaja el aprendido
El Modo Seguro y el Guardián de tensión
aplican max(valor de config, suelo aprendido). Antes podían bajar la
protección química justo en el momento en que peor se veía la situación.
8.7.
Estado global visible en el dashboard
El nodo Estado EMS publica la global estado_ems cada 30 s y la pinta en la pestaña Sistema:
·
Modo (NORMAL / FAILSAFE / MODO
SEGURO / CALIBRACIÓN / EMERGENCIA), zona tarifaria y SOC con su origen.
·
Última decisión: acción, suelo
enviado, techo y supervivencia.
·
Por qué se cargó de red la última vez:
fecha, objetivo, SOC de partida, motivo y nodo que lo pidió.
·
Suelo prioritario activo, si lo
hay, con su motivo.
·
Tensión y corriente (con la
fuente), suelo aprendido y confirmado, capacidad estimada, consumo medio de 7
días, estado del perfil horario, origen y confianza de la previsión solar, CPU
del GX, semanas de histórico y avisos de estrés o de guardián.
Es un nodo
puramente informativo: solo lee globales y publica. Se puede borrar sin afectar
al control.
v61.16
— Compras solo en valle, reserva para apagones y subida mínima
Motivo: el 8-oct la gráfica de VRM mostró
~3 kWh comprados a llano de 22:00 a 24:00 y ~4 kWh de 14:00 a 18:00, ambos por
la rama P2 intentando «llegar al valle con el 40 %». La energía comprada a las
22:00 se la llevó el coche de madrugada, con la red a 0,084. Y la madrugada del
9 el Cerebro pidió 26 % con el SOC en 20 %: el ESS no arranca la carga con
diferencias tan pequeñas.
1.
Fuera reserva_llegada_pct. La supervivencia es solo «no bajar del
suelo en el tramo caro».
2.
P2 solo compra para cubrir punta. Se
rastrea en el motor de 48 h el mayor bajón en horas P1 antes del valle (_para_cubrir_P1, hay_P1_antes_del_valle en el
debug). Sin punta por delante, no compra.
3.
Corte táctico solo antes de punta, y sin
soltar lo retenido: el suelo se queda en el menor entre el objetivo de la
franja y el SOC actual (antes bajaba al mínimo y la casa gastaba a llano lo
guardado para la punta).
4.
Subida mínima (subida_minima_carga_pct, 10): si hay que cargar, el suelo enviado es al menos SOC + 10, en
cualquier franja. Es el arranque del ESS, no una compra fija: al alcanzar la
necesidad, la siguiente ejecución lo baja. Queda en el debug como subida_minima_aplicada.
5.
Reserva para apagones (soc_reserva_apagon_pct, 40). El suelo del ESS es «SOC mínimo salvo fallo de red», así que
lo que se guarda por encima está disponible en un corte de luz.
·
Cede ante el sol: reserva efectiva = máx(suelo,
mín(40 %, techo ecológico)).
·
Se recarga solo en valle: en P3 se suma
a la necesidad de compra.
·
En P1/P2 solo retiene: hace de suelo
pero nunca por encima del SOC actual, así que nunca dispara una compra a llano
o punta. En fin de semana retiene de noche y se rellena en la ventana del
mediodía.
·
Para desactivarla basta con
ponerla igual al suelo (20).
Simulación de
cuatro días laborables con las mismas previsiones: el coste diario en régimen
queda igual que sin reserva (la reserva solo cuesta su llenado inicial, ~0,20
€, y luego se arrastra), las compras a llano desaparecen y el SOC al cerrar el
día sube del ~40 % al ~46 %.
Ficha técnica: Victron MultiPlus II · SmartShunt 500A · GX con Venus OS · batería LFP 16S (~48 V / ~30 kWh) · tarifa 2.0TD · Node-RED · previsión solar con Solcast y la API de VRM. Desarrollado con ayuda de la IA.


No hay comentarios:
Publicar un comentario
Puede dejar su comentario, que tratará de ser moderado en los días siguientes. En caso de ser algo importante/urgente, por favor utilicen el formulario de arriba a la derecha para contactar.