substitutions:
name: CHANGE-ME #Accepta doar litere mici
device_description: "ESPHome - Deye - Config"
modbus_controller_id: deye_8k
device_type: deye
inverter_model: "SUN-8K-SG05LP1-EU"
##############################################################
esphome:
name: ${name}
friendly_name: ${name}
##############################################################
esp32:
board: esp32dev
framework:
type: esp-idf
##############################################################
logger:
level: WARN
##############################################################
api:
encryption:
key: "CHANGE-ME" # Pune key-ul tau de encryption generat de ESPHome
reboot_timeout: 0s
##############################################################
wifi:
ssid: !secret wifi_ssid # Defineste in secrets.yaml
password: !secret wifi_password # Defineste in secrets.yaml
use_address: 0.0.0.0 # Seteaza IP-ul static al ESP-ului tau
power_save_mode: none
fast_connect: on
manual_ip:
static_ip: 0.0.0.0 # Seteaza IP-ul static al ESP-ului tau (acelasi ca use_address)
gateway: 0.0.0.0 # Seteaza gateway-ul retelei tale (de obicei IP-ul routerului)
subnet: 255.255.255.0
dns1: 1.1.1.1
##############################################################
web_server:
local: true
port: 80
version: 2
include_internal: false
auth:
username: !secret web_server_username
password: !secret web_server_password
##############################################################
ota:
platform: esphome
password: !secret ota_password
##############################################################
# TIME - Sincronizare ora (HA primary, SNTP backup)
##############################################################
time:
- platform: homeassistant
id: homeassistant_time
timezone: Europe/Bucharest
on_time_sync:
then:
- logger.log: "Ora sincronizata cu Home Assistant"
- platform: sntp
id: sntp_time
timezone: Europe/Bucharest
servers:
- time.google.com
- 0.pool.ntp.org
- 1.pool.ntp.org
on_time_sync:
then:
- logger.log: "Ora sincronizata cu SNTP (backup)"
on_time:
# Reset zilnic la 12:00
- seconds: 0
minutes: 0
hours: 12
then:
- lambda: |-
ESP_LOGI("virtual_sensors", "=== RESET ZILNIC la 12:00 ===");
ESP_LOGI("virtual_sensors", "Daily: %.2f kWh", id(virtual_daily_batt_discharge));
ESP_LOGI("virtual_sensors", "Yesterday: %.2f kWh", id(virtual_batt_discharge_yesterday));
// Rotatie valori
id(virtual_batt_discharge_day_before) = id(virtual_batt_discharge_yesterday);
id(virtual_batt_discharge_yesterday) = id(virtual_daily_batt_discharge);
id(virtual_daily_batt_discharge) = 0.0;
ESP_LOGI("virtual_sensors", "Nou: Daily=0.0, Yesterday=%.2f, DayBefore=%.2f",
id(virtual_batt_discharge_yesterday),
id(virtual_batt_discharge_day_before));
# Reset lunar pe 1 a lunii la 00:00
- seconds: 0
minutes: 0
hours: 0
days_of_month: 1
then:
- lambda: |-
ESP_LOGI("virtual_sensors", "=== RESET LUNAR la 01.00:00 ===");
ESP_LOGI("virtual_sensors", "Luna trecuta:");
ESP_LOGI("virtual_sensors", " Batt Discharge: %.2f kWh", id(virtual_monthly_batt_discharge));
ESP_LOGI("virtual_sensors", " Batt Charge: %.2f kWh", id(virtual_monthly_batt_charge));
ESP_LOGI("virtual_sensors", " Load: %.2f kWh", id(virtual_monthly_load));
// PV - salvam noua referinta
float total_pv_now = id(deye_pv_total_energy).state;
if (!isnan(total_pv_now)) {
ESP_LOGI("virtual_sensors", " PV: %.2f kWh (Total: %.1f kWh)",
total_pv_now - id(month_start_pv_total), total_pv_now);
id(month_start_pv_total) = total_pv_now;
ESP_LOGI("virtual_sensors", " Noua referinta PV: %.1f kWh", total_pv_now);
}
ESP_LOGI("virtual_sensors", " Grid Import: %.2f kWh", id(virtual_monthly_grid_import));
// Reset valorile lunare (exceptand PV care e calculat dinamic)
id(virtual_monthly_batt_discharge) = 0.0;
id(virtual_monthly_batt_charge) = 0.0;
id(virtual_monthly_load) = 0.0;
id(virtual_monthly_grid_import) = 0.0;
##############################################################
uart:
id: mod_bus
tx_pin: GPIO17
rx_pin: GPIO16
baud_rate: 9600
stop_bits: 1
##############################################################
modbus:
id: modbus1
uart_id: mod_bus
##############################################################
modbus_controller:
- id: ${modbus_controller_id}
address: 0x1
modbus_id: modbus1
setup_priority: -10
update_interval: 20s
##############################################################
# GLOBALS
##############################################################
globals:
# Watchdog
- id: last_modbus_update
type: unsigned long
restore_value: no
initial_value: '0'
- id: wifi_retry_count
type: int
restore_value: no
initial_value: '0'
- id: last_pv1_voltage
type: float
restore_value: no
initial_value: '0.0'
- id: last_pv2_voltage
type: float
restore_value: no
initial_value: '0.0'
- id: last_batt_voltage
type: float
restore_value: no
initial_value: '0.0'
- id: last_grid_voltage
type: float
restore_value: no
initial_value: '0.0'
- id: last_batt_soc
type: float
restore_value: no
initial_value: '0.0'
# Senzori virtuali - Previous values (pentru detectare diferență)
- id: previous_deye_batt_discharge
type: float
restore_value: yes
initial_value: '0.0'
- id: previous_deye_batt_charge
type: float
restore_value: yes
initial_value: '0.0'
- id: previous_deye_load
type: float
restore_value: yes
initial_value: '0.0'
- id: previous_deye_grid_import
type: float
restore_value: yes
initial_value: '0.0'
# PV Monthly - REFERINȚĂ (start lună)
- id: month_start_pv_total
type: float
restore_value: yes
initial_value: '0.0'
# Senzori virtuali - Daily (doar battery discharge)
- id: virtual_daily_batt_discharge
type: float
restore_value: yes
initial_value: '0.0'
- id: virtual_batt_discharge_yesterday
type: float
restore_value: yes
initial_value: '0.0'
- id: virtual_batt_discharge_day_before
type: float
restore_value: yes
initial_value: '0.0'
# Senzori virtuali - Monthly
- id: virtual_monthly_batt_discharge
type: float
restore_value: yes
initial_value: '0.0'
- id: virtual_monthly_batt_charge
type: float
restore_value: yes
initial_value: '0.0'
- id: virtual_monthly_load
type: float
restore_value: yes
initial_value: '0.0'
- id: virtual_monthly_pv
type: float
restore_value: no
initial_value: '0.0'
- id: virtual_monthly_grid_import
type: float
restore_value: yes
initial_value: '0.0'
##############################################################
# SENZORI - ORIGINALI
##############################################################
sensor:
# PV TOTAL Power
- platform: template
name: "${device_type}_pv_total_power"
id: pv_total_power
unit_of_measurement: "W"
device_class: power
state_class: "measurement"
accuracy_decimals: 0
icon: "mdi:solar-power-variant"
update_interval: 20s
lambda: |-
if (isnan(id(pv1_power).state) || isnan(id(pv2_power).state)) {
return 0;
}
return id(pv1_power).state + id(pv2_power).state;
# PV1 Power
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_pv1_power"
id: pv1_power
register_type: holding
address: 186
unit_of_measurement: "W"
device_class: power
state_class: "measurement"
accuracy_decimals: 0
icon: "mdi:solar-power"
value_type: U_WORD
# PV2 Power
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_pv2_power"
id: pv2_power
register_type: holding
address: 187
unit_of_measurement: "W"
device_class: power
state_class: "measurement"
accuracy_decimals: 0
icon: "mdi:solar-power"
value_type: U_WORD
# PV1 Current
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_pv1_current"
register_type: holding
address: 110
unit_of_measurement: "A"
device_class: current
state_class: "measurement"
accuracy_decimals: 1
icon: "mdi:current-dc"
filters:
- multiply: 0.1
value_type: U_WORD
# PV2 Current
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_pv2_current"
register_type: holding
address: 112
unit_of_measurement: "A"
device_class: current
state_class: "measurement"
accuracy_decimals: 1
icon: "mdi:current-dc"
filters:
- multiply: 0.1
value_type: U_WORD
# PV1 Voltage
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_pv1_voltage"
id: pv1_voltage
register_type: holding
address: 109
unit_of_measurement: "V"
device_class: voltage
state_class: "measurement"
accuracy_decimals: 1
icon: "mdi:lightning-bolt"
filters:
- multiply: 0.1
value_type: U_WORD
# PV2 Voltage
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_pv2_voltage"
id: pv2_voltage
register_type: holding
address: 111
unit_of_measurement: "V"
device_class: voltage
state_class: "measurement"
accuracy_decimals: 1
icon: "mdi:lightning-bolt"
filters:
- multiply: 0.1
value_type: U_WORD
# Day PV Energy
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_pv_day_energy"
id: deye_pv_day_energy
register_type: holding
address: 108
unit_of_measurement: "kWh"
state_class: "total_increasing"
device_class: energy
accuracy_decimals: 1
icon: "mdi:solar-power"
filters:
- multiply: 0.1
value_type: U_WORD
# Total PV Energy
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_pv_total_energy"
id: deye_pv_total_energy
register_type: holding
address: 96
unit_of_measurement: "kWh"
state_class: "total_increasing"
device_class: energy
accuracy_decimals: 1
icon: "mdi:solar-power-variant"
filters:
- multiply: 0.1
value_type: U_WORD
# Battery SOC
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_batt_soc"
id: batt_soc
register_type: holding
address: 184
unit_of_measurement: "%"
state_class: "measurement"
device_class: battery
accuracy_decimals: 0
icon: "mdi:battery"
value_type: U_WORD
# Battery Power
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_batt_power"
register_type: holding
address: 190
unit_of_measurement: "W"
device_class: power
state_class: "measurement"
accuracy_decimals: 0
icon: "mdi:battery-charging"
filters:
- multiply: -1
value_type: S_WORD
# Battery Voltage
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_batt_voltage"
id: batt_voltage
register_type: holding
address: 183
unit_of_measurement: "V"
device_class: voltage
state_class: "measurement"
accuracy_decimals: 2
icon: "mdi:lightning-bolt"
filters:
- multiply: 0.01
value_type: U_WORD
# Battery Current
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_batt_current"
register_type: holding
address: 191
unit_of_measurement: "A"
device_class: current
state_class: "measurement"
accuracy_decimals: 2
icon: "mdi:current-dc"
filters:
- multiply: -0.01
value_type: S_WORD
# Battery Temperature
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_batt_temperature"
register_type: holding
address: 182
unit_of_measurement: "°C"
device_class: temperature
accuracy_decimals: 1
icon: "mdi:thermometer"
filters:
- offset: -1000
- multiply: 0.1
value_type: U_WORD
# Day Battery Charge
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_batt_day_charge"
id: deye_batt_day_charge
register_type: holding
address: 70
unit_of_measurement: "kWh"
state_class: "total_increasing"
device_class: energy
accuracy_decimals: 1
icon: "mdi:battery-plus"
filters:
- multiply: 0.1
value_type: U_WORD
# Day Battery Discharge
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_batt_day_discharge"
id: deye_batt_day_discharge
register_type: holding
address: 71
unit_of_measurement: "kWh"
state_class: "total_increasing"
device_class: energy
accuracy_decimals: 1
icon: "mdi:battery-minus"
filters:
- multiply: 0.1
value_type: U_WORD
# Grid Power
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_grid_power"
register_type: holding
address: 169
unit_of_measurement: "W"
device_class: power
state_class: "measurement"
accuracy_decimals: 0
icon: "mdi:transmission-tower"
value_type: S_WORD
# Grid Voltage
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_grid_voltage"
id: deye_grid_voltage
register_type: holding
address: 150
unit_of_measurement: "V"
device_class: voltage
state_class: "measurement"
accuracy_decimals: 1
icon: "mdi:lightning-bolt"
filters:
- multiply: 0.1
value_type: U_WORD
# Grid Current
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_grid_current"
register_type: holding
address: 160
unit_of_measurement: "A"
device_class: current
state_class: "measurement"
accuracy_decimals: 2
icon: "mdi:current-ac"
filters:
- multiply: 0.01
value_type: S_WORD
# Grid Frequency
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_grid_frequency"
id: deye_grid_frequency
register_type: holding
address: 79
unit_of_measurement: "Hz"
state_class: "measurement"
accuracy_decimals: 2
icon: "mdi:sine-wave"
filters:
- multiply: 0.01
value_type: U_WORD
# Day Grid Export
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_grid_day_export"
register_type: holding
address: 81
unit_of_measurement: "kWh"
state_class: "total_increasing"
device_class: energy
accuracy_decimals: 1
icon: "mdi:transmission-tower-export"
filters:
- multiply: 0.1
value_type: U_WORD
# Day Grid Import
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_grid_day_import"
id: deye_grid_day_import
register_type: holding
address: 76
unit_of_measurement: "kWh"
state_class: "total_increasing"
device_class: energy
accuracy_decimals: 1
icon: "mdi:transmission-tower-import"
filters:
- multiply: 0.1
value_type: U_WORD
# Load Power
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_load_power"
id: load_power_sensor
register_type: holding
address: 178
unit_of_measurement: "W"
device_class: power
state_class: "measurement"
accuracy_decimals: 0
icon: "mdi:home-lightning-bolt"
value_type: S_WORD
# Load Voltage
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_load_voltage"
register_type: holding
address: 154
unit_of_measurement: "V"
device_class: voltage
state_class: "measurement"
accuracy_decimals: 1
icon: "mdi:home-lightning-bolt"
filters:
- multiply: 0.1
value_type: U_WORD
# Load Frequency
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_load_frequency"
register_type: holding
address: 193
unit_of_measurement: "Hz"
state_class: "measurement"
accuracy_decimals: 2
icon: "mdi:sine-wave"
filters:
- multiply: 0.01
value_type: U_WORD
# Day Load Energy
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_load_day_energy"
id: deye_load_day_energy
register_type: holding
address: 84
unit_of_measurement: "kWh"
state_class: "total_increasing"
device_class: energy
accuracy_decimals: 1
icon: "mdi:home-lightning-bolt-outline"
filters:
- multiply: 0.1
value_type: U_WORD
##############################################################
# BATTERY SETTINGS - READ
##############################################################
# Battery Capacity - READ (doar citire, nu scriere)
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_read_capacity"
register_type: holding
address: 204
unit_of_measurement: "Ah"
state_class: "measurement"
icon: "mdi:battery-high"
accuracy_decimals: 0
value_type: U_WORD
##############################################################
# INVERTER
##############################################################
# Inverter Temperature
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_inverter_temperature"
register_type: holding
address: 90
unit_of_measurement: "°C"
device_class: temperature
state_class: "measurement"
accuracy_decimals: 1
icon: "mdi:thermometer"
filters:
- offset: -1000
- multiply: 0.1
value_type: U_WORD
# Inverter Load %
- platform: template
name: "${device_type}_inverter_load"
unit_of_measurement: "%"
state_class: "measurement"
accuracy_decimals: 0
icon: "mdi:gauge"
update_interval: 20s
lambda: |-
float load_power = id(load_power_sensor).state;
if (isnan(load_power) || load_power < 0) {
return 0;
}
float load_percent = (load_power / 8000.0) * 100.0;
if (load_percent > 100) load_percent = 100;
return load_percent;
##############################################################
# SENZORI VIRTUALI
##############################################################
# ZILNIC - Battery Discharge
- platform: template
name: "${device_type}_virtual_battery_discharge_daily"
id: sensor_battery_discharge_daily
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
accuracy_decimals: 2
icon: "mdi:battery-minus"
update_interval: 300s
lambda: |-
return id(virtual_daily_batt_discharge);
- platform: template
name: "${device_type}_virtual_battery_discharge_yesterday"
id: sensor_battery_discharge_yesterday
unit_of_measurement: "kWh"
device_class: energy
accuracy_decimals: 2
icon: "mdi:battery-clock"
update_interval: 60s
lambda: |-
return id(virtual_batt_discharge_yesterday);
- platform: template
name: "${device_type}_virtual_battery_discharge_day_before"
id: sensor_battery_discharge_day_before
unit_of_measurement: "kWh"
device_class: energy
accuracy_decimals: 2
icon: "mdi:battery-clock-outline"
update_interval: 60s
lambda: |-
return id(virtual_batt_discharge_day_before);
# LUNARI
- platform: template
name: "${device_type}_virtual_monthly_battery_discharge"
id: sensor_monthly_battery_discharge
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
accuracy_decimals: 2
icon: "mdi:battery-arrow-down"
update_interval: 60s
lambda: |-
return id(virtual_monthly_batt_discharge);
- platform: template
name: "${device_type}_virtual_monthly_battery_charge"
id: sensor_monthly_battery_charge
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
accuracy_decimals: 2
icon: "mdi:battery-plus"
update_interval: 60s
lambda: |-
return id(virtual_monthly_batt_charge);
- platform: template
name: "${device_type}_virtual_monthly_house_consumption"
id: sensor_monthly_house
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
accuracy_decimals: 2
icon: "mdi:home-lightning-bolt"
update_interval: 60s
lambda: |-
return id(virtual_monthly_load);
- platform: template
name: "${device_type}_virtual_monthly_solar_production"
id: sensor_monthly_solar
unit_of_measurement: "kWh"
device_class: energy
state_class: total
accuracy_decimals: 2
icon: "mdi:solar-power"
update_interval: 60s
lambda: |-
float total_pv = id(deye_pv_total_energy).state;
float month_start = id(month_start_pv_total);
if (isnan(total_pv)) {
return 0.0;
}
return total_pv - month_start;
# REFERINȚĂ PV LUNARĂ - VIZIBILĂ
- platform: template
name: "${device_type}_pv_monthly_reference"
unit_of_measurement: "kWh"
device_class: energy
accuracy_decimals: 1
icon: "mdi:bookmark"
update_interval: 60s
lambda: |-
return id(month_start_pv_total);
- platform: template
name: "${device_type}_virtual_monthly_grid_import"
id: sensor_monthly_grid
unit_of_measurement: "kWh"
device_class: energy
state_class: total_increasing
accuracy_decimals: 2
icon: "mdi:transmission-tower-import"
update_interval: 60s
lambda: |-
return id(virtual_monthly_grid_import);
# Virtual SOC - Calculat precis pentru LiFePO4 16S (49V-55.5V)
- platform: template
name: "${device_type}_virtual_soc"
id: virtual_soc_sensor
unit_of_measurement: "%"
device_class: battery
state_class: "measurement"
accuracy_decimals: 1
icon: "mdi:battery"
update_interval: 10s
lambda: |-
float v = id(batt_voltage).state;
if (isnan(v)) {
return 0.0;
}
// Limitare la range-ul tău (49V - 55.5V)
if (v <= 49.0) return 0.0;
if (v >= 55.5) return 100.0;
// Lookup table pentru LiFePO4 16S
// Format: {voltage, soc}
float soc = 0.0;
if (v >= 55.5) {
soc = 100.0;
} else if (v >= 54.4) {
// 54.4V-55.5V → 85%-100% (1.1V range = 15% SOC)
soc = 85.0 + ((v - 54.4) / 1.1) * 15.0;
} else if (v >= 53.6) {
// 53.6V-54.4V → 70%-85% (0.8V range = 15% SOC)
soc = 70.0 + ((v - 53.6) / 0.8) * 15.0;
} else if (v >= 52.8) {
// 52.8V-53.6V → 55%-70% (0.8V range = 15% SOC)
soc = 55.0 + ((v - 52.8) / 0.8) * 15.0;
} else if (v >= 52.0) {
// 52.0V-52.8V → 40%-55% (0.8V range = 15% SOC)
soc = 40.0 + ((v - 52.0) / 0.8) * 15.0;
} else if (v >= 51.2) {
// 51.2V-52.0V → 25%-40% (0.8V range = 15% SOC)
soc = 25.0 + ((v - 51.2) / 0.8) * 15.0;
} else if (v >= 50.4) {
// 50.4V-51.2V → 12%-25% (0.8V range = 13% SOC)
soc = 12.0 + ((v - 50.4) / 0.8) * 13.0;
} else if (v >= 49.6) {
// 49.6V-50.4V → 5%-12% (0.8V range = 7% SOC)
soc = 5.0 + ((v - 49.6) / 0.8) * 7.0;
} else {
// 49.0V-49.6V → 0%-5% (0.6V range = 5% SOC)
soc = 0.0 + ((v - 49.0) / 0.6) * 5.0;
}
// Asigură-te că rămâne în range 0-100
if (soc < 0.0) soc = 0.0;
if (soc > 100.0) soc = 100.0;
return soc;
# WiFi Signal Strength
- platform: wifi_signal
name: "${device_type}_wifi_signal_db"
id: wifi_signal_db
update_interval: 60s
internal: true
- platform: template
name: "${device_type}_wifi_signal_percent"
unit_of_measurement: "%"
icon: "mdi:wifi"
update_interval: 60s
accuracy_decimals: 0
lambda: |-
float dbm = id(wifi_signal_db).state;
if (isnan(dbm)) {
return 0;
}
// Conversie dBm la procente (standard WiFi)
// -50 dBm = 100% (excelent)
// -100 dBm = 0% (foarte slab)
float quality;
if (dbm <= -100) {
quality = 0;
} else if (dbm >= -50) {
quality = 100;
} else {
quality = 2 * (dbm + 100);
}
return quality;
##############################################################
# BATTERY SETTINGS - WRITE
##############################################################
number:
# Absorption Voltage
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_set_absorption_voltage"
id: set_absorption_voltage
address: 202
value_type: U_WORD
use_write_multiple: true
multiply: 100
min_value: 48.0
max_value: 60.0
step: 0.1
unit_of_measurement: "V"
mode: box
icon: "mdi:battery-charging-high"
# Float Voltage
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_set_float_voltage"
id: set_float_voltage
address: 203
value_type: U_WORD
use_write_multiple: true
multiply: 100
min_value: 48.0
max_value: 58.0
step: 0.1
unit_of_measurement: "V"
mode: box
icon: "mdi:battery-charging-medium"
# Battery Empty Voltage
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_set_empty_voltage"
id: set_empty_voltage
address: 205
value_type: U_WORD
use_write_multiple: true
multiply: 100
min_value: 40.0
max_value: 50.0
step: 0.1
unit_of_measurement: "V"
mode: box
icon: "mdi:battery-outline"
# Battery Max Charge Current
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_set_max_charge_current"
id: set_max_charge_current
address: 210
value_type: U_WORD
use_write_multiple: true
min_value: 0
max_value: 200
step: 1
unit_of_measurement: "A"
mode: box
icon: "mdi:battery-charging-high"
# Battery Max Discharge Current
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_set_max_discharge_current"
id: set_max_discharge_current
address: 211
value_type: U_WORD
use_write_multiple: true
min_value: 0
max_value: 200
step: 1
unit_of_measurement: "A"
mode: box
icon: "mdi:battery-arrow-down"
# Battery Shutdown Voltage
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_set_shutdown_voltage"
id: set_shutdown_voltage
address: 220
value_type: U_WORD
use_write_multiple: true
multiply: 100
min_value: 40.0
max_value: 50.0
step: 0.1
unit_of_measurement: "V"
mode: box
icon: "mdi:battery-alert"
# Battery Restart Voltage
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_set_restart_voltage"
id: set_restart_voltage
address: 221
value_type: U_WORD
use_write_multiple: true
multiply: 100
min_value: 40.0
max_value: 52.0
step: 0.1
unit_of_measurement: "V"
mode: box
icon: "mdi:battery-arrow-up"
# Battery Low Voltage
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_set_low_voltage"
id: set_low_voltage
address: 222
value_type: U_WORD
use_write_multiple: true
multiply: 100
min_value: 40.0
max_value: 52.0
step: 0.1
unit_of_measurement: "V"
mode: box
icon: "mdi:battery-low"
##############################################################
# STATUS
##############################################################
text_sensor:
# WiFi Status
- platform: template
name: "${device_type}_wifi_status"
id: wifi_status_sensor
icon: "mdi:wifi"
update_interval: 60s
lambda: |-
if (wifi::global_wifi_component->is_connected()) {
return {"WiFi OK"};
} else {
int count = id(wifi_retry_count);
char status[20];
sprintf(status, "Retry (%d/5)", count);
return {(std::string)status};
}
# ESP Current Time
- platform: template
name: "${device_type}_current_time"
id: esp_current_time
icon: "mdi:clock-outline"
update_interval: 1s
lambda: |-
auto time = id(homeassistant_time).now();
if (!time.is_valid()) {
return {"Waiting for time sync..."};
}
// Actualizeaza doar la secunda 00
if (time.second != 0) {
return {};
}
char buf[17];
sprintf(buf, "%04d-%02d-%02d %02d:%02d",
time.year, time.month, time.day_of_month,
time.hour, time.minute);
return {buf};
# Inverter Status
- platform: modbus_controller
modbus_controller_id: ${modbus_controller_id}
name: "${device_type}_inverter_status"
register_type: holding
address: 59
icon: "mdi:information-outline"
raw_encode: HEXBYTES
lambda: |-
uint16_t value = modbus_controller::word_from_hex_str(x, 0);
switch (value) {
case 0: return std::string("Standby");
case 1: return std::string("Self-check");
case 2: return std::string("Normal");
case 3: return std::string("Alarm");
case 4: return std::string("Fault");
default: return std::string("Unknown");
}
return x;
##############################################################
# WATCHDOG & INTERVALS
##############################################################
binary_sensor:
# WiFi connectivity status
- platform: template
name: "${device_type}_wifi_connected"
id: wifi_connected
device_class: connectivity
lambda: |-
return wifi::global_wifi_component->is_connected();
# Senzor de monitorizare comunicatie Modbus
- platform: template
name: "${device_type}_modbus_alive"
id: modbus_alive
device_class: connectivity
lambda: |-
unsigned long now = millis();
unsigned long last = id(last_modbus_update);
// Verifică dacă senzorii au valori valide (Modbus comunică)
bool pv1_valid = !isnan(id(pv1_voltage).state);
bool grid_valid = !isnan(id(deye_grid_voltage).state);
bool batt_valid = !isnan(id(batt_soc).state);
// Dacă cel puțin 2 din 3 senzori sunt valizi, Modbus e OK
int valid_count = (pv1_valid ? 1 : 0) + (grid_valid ? 1 : 0) + (batt_valid ? 1 : 0);
if (valid_count >= 2) {
// Modbus comunică, update timestamp
id(last_modbus_update) = now;
return true;
}
// Verifică dacă au trecut 5 minute fără comunicare validă
if (last > 0 && (now - last) > 300000) {
ESP_LOGW("watchdog", "Modbus NU COMUNICA de 5 minute!");
return false;
}
return (last > 0);
interval:
# Watchdog WiFi - verifica la fiecare 60s
- interval: 60s
then:
- lambda: |-
bool wifi_ok = wifi::global_wifi_component->is_connected();
if (wifi_ok) {
// WiFi conectat - reset counter si update status
if (id(wifi_retry_count) != 0) {
ESP_LOGI("watchdog", "WiFi reconectat!");
}
id(wifi_retry_count) = 0;
id(wifi_status_sensor).publish_state("WiFi OK");
} else {
// WiFi deconectat - creste counter
id(wifi_retry_count) += 1;
int count = id(wifi_retry_count);
ESP_LOGW("watchdog", "WiFi deconectat - Retry %d/5", count);
char status[20];
sprintf(status, "Retry (%d/5)", count);
id(wifi_status_sensor).publish_state(status);
// Dupa 5 incercari (5 minute) -> RESTART
if (count >= 5) {
ESP_LOGW("watchdog", "=== WIFI DECONECTAT 5 MINUTE! RESTART! ===");
App.safe_reboot();
}
}
# Watchdog Modbus - Restart daca nu comunica
- interval: 60s
then:
- lambda: |-
unsigned long now = millis();
unsigned long last = id(last_modbus_update);
// Daca Modbus nu a comunicat de 5 minute
if (last > 0 && (now - last) > 300000) {
ESP_LOGW("watchdog", "=== MODBUS BLOCAT DE 5 MINUTE! RESTART! ===");
ESP_LOGW("watchdog", "Last update was %.1f minutes ago", (now - last) / 60000.0);
App.safe_reboot();
}
# Actualizare senzori virtuali - La fiecare 5 minute
- interval: 300s
then:
- lambda: |-
// === BATTERY DISCHARGE ===
float deye_batt_discharge = id(deye_batt_day_discharge).state;
float prev_batt_discharge = id(previous_deye_batt_discharge);
if (!isnan(deye_batt_discharge)) {
if (deye_batt_discharge < prev_batt_discharge) {
// Deye s-a resetat la 00:00
ESP_LOGI("virtual", "Deye Battery Discharge reset detectat: %.2f -> %.2f",
prev_batt_discharge, deye_batt_discharge);
id(previous_deye_batt_discharge) = deye_batt_discharge;
} else {
// Calculează diferența
float diff = deye_batt_discharge - prev_batt_discharge;
if (diff > 0) {
id(virtual_daily_batt_discharge) += diff;
id(virtual_monthly_batt_discharge) += diff;
ESP_LOGD("virtual", "Batt Discharge +%.3f kWh (Daily: %.2f, Monthly: %.2f)",
diff, id(virtual_daily_batt_discharge), id(virtual_monthly_batt_discharge));
}
id(previous_deye_batt_discharge) = deye_batt_discharge;
}
}
// === BATTERY CHARGE ===
float deye_batt_charge = id(deye_batt_day_charge).state;
float prev_batt_charge = id(previous_deye_batt_charge);
if (!isnan(deye_batt_charge)) {
if (deye_batt_charge < prev_batt_charge) {
ESP_LOGI("virtual", "Deye Battery Charge reset detectat");
id(previous_deye_batt_charge) = deye_batt_charge;
} else {
float diff = deye_batt_charge - prev_batt_charge;
if (diff > 0) {
id(virtual_monthly_batt_charge) += diff;
ESP_LOGD("virtual", "Batt Charge +%.3f kWh (Monthly: %.2f)",
diff, id(virtual_monthly_batt_charge));
}
id(previous_deye_batt_charge) = deye_batt_charge;
}
}
// === LOAD (CASA) ===
float deye_load = id(deye_load_day_energy).state;
float prev_load = id(previous_deye_load);
if (!isnan(deye_load)) {
if (deye_load < prev_load) {
ESP_LOGI("virtual", "Deye Load reset detectat");
id(previous_deye_load) = deye_load;
} else {
float diff = deye_load - prev_load;
if (diff > 0) {
id(virtual_monthly_load) += diff;
ESP_LOGD("virtual", "Load +%.3f kWh (Monthly: %.2f)",
diff, id(virtual_monthly_load));
}
id(previous_deye_load) = deye_load;
}
}
// === PV (PANOURI) - METODA SIMPLA ===
// NU facem nimic aici, se calculeaza dinamic in senzor!
// === GRID IMPORT ===
float deye_grid = id(deye_grid_day_import).state;
float prev_grid = id(previous_deye_grid_import);
if (!isnan(deye_grid)) {
if (deye_grid < prev_grid) {
ESP_LOGI("virtual", "Deye Grid Import reset detectat");
id(previous_deye_grid_import) = deye_grid;
} else {
float diff = deye_grid - prev_grid;
if (diff > 0) {
id(virtual_monthly_grid_import) += diff;
ESP_LOGD("virtual", "Grid Import +%.3f kWh (Monthly: %.2f)",
diff, id(virtual_monthly_grid_import));
}
id(previous_deye_grid_import) = deye_grid;
}
}
button:
# Buton manual de restart
- platform: restart
name: "${device_type}_restart"
icon: "mdi:restart"
# Buton RESETARE referință PV lunară la ZERO
- platform: template
name: "${device_type}_reset_pv_reference_to_zero"
icon: "mdi:numeric-0-box"
on_press:
- lambda: |-
id(month_start_pv_total) = 0.0;
ESP_LOGI("manual_reset", "Referință PV RESETATĂ LA ZERO!");
# Buton SALVARE referință PV lunară (setează la valoarea curentă)
- platform: template
name: "${device_type}_save_pv_reference"
icon: "mdi:content-save"
on_press:
- lambda: |-
float total_pv = id(deye_pv_total_energy).state;
if (!isnan(total_pv)) {
id(month_start_pv_total) = total_pv;
ESP_LOGI("manual_reset", "Referință PV salvată: %.1f kWh", total_pv);
}