Hello
apres avoir beaucoup demandé, la moindre des choses est de vous partager ma petite reussite (avec claude quand meme)
je resume, deux controleurs etek car deux VE, b1 est prioritaire sur b2
B2 s'enclenche si b1 a fini la charge ou si rien de branché
Portection rmcu, anti-surchauffe egalement, et enclenchement pendant les heures 22-6h.
Tout fonctionne nickel via modbus, avec un esp32, et un waveshare pour la conversion rs485
esphome:
name: wallbox-1
friendly_name: Wallbox_1
on_boot:
priority: -100
then:
- number.set:
id: consigne_b1
value: 0
- number.set:
id: consigne_b2
value: 0
- delay: 60s
esp32:
board: esp32dev
framework:
type: arduino
wifi:
ssid: "------"
password: "----"
api:
encryption:
key: "------"
ota:
- platform: esphome
password: "-------"
logger:
level: DEBUG
logs:
modbus: ERROR
modbus_controller: WARN
time:
- platform: sntp
id: sntp_time
timezone: "Europe/Paris"
uart:
id: uart_bus
tx_pin: GPIO17
rx_pin: GPIO16
baud_rate: 9600
stop_bits: 1
modbus:
id: bus_rs485
uart_id: uart_bus
send_wait_time: 500ms
modbus_controller:
- id: etek_1
address: 0xD5
modbus_id: bus_rs485
setup_priority: -10
update_interval: 30s
offline_skip_updates: 0
- id: etek_2
address: 0x02
modbus_id: bus_rs485
setup_priority: -10
update_interval: 30s
switch:
- platform: template
name: "Marche Forcée Hors HC"
id: mode_force
optimistic: true
restore_mode: ALWAYS_OFF
button:
- platform: template
name: "B1 RCMU ON (Reg110=1)"
on_press:
then:
- lambda: |-
auto cmd = modbus_controller::ModbusCommandItem::create_write_single_command(
id(etek_1), 110, 1);
id(etek_1)->queue_command(cmd);
- platform: template
name: "B1 RCMU OFF (Reg110=3)"
on_press:
then:
- lambda: |-
auto cmd = modbus_controller::ModbusCommandItem::create_write_single_command(
id(etek_1), 110, 3);
id(etek_1)->queue_command(cmd);
- platform: template
name: "B2 RCMU ON (Reg110=1)"
on_press:
then:
- lambda: |-
auto cmd = modbus_controller::ModbusCommandItem::create_write_single_command(
id(etek_2), 110, 1);
id(etek_2)->queue_command(cmd);
- platform: template
name: "B2 RCMU OFF (Reg110=3)"
on_press:
then:
- lambda: |-
auto cmd = modbus_controller::ModbusCommandItem::create_write_single_command(
id(etek_2), 110, 3);
id(etek_2)->queue_command(cmd);
sensor:
# --- BORNE 1 ---
- platform: modbus_controller
modbus_controller_id: etek_1
name: "B1 Status"
id: status_b1
register_type: holding
address: 141
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: etek_1
name: "B1 PWM sortie"
id: pwm_b1
register_type: holding
address: 152
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: etek_1
name: "B1 Temperature"
id: temp_b1
register_type: holding
address: 157
unit_of_measurement: "°C"
value_type: U_WORD
filters:
- multiply: 0.1
- platform: modbus_controller
modbus_controller_id: etek_1
name: "B1 RCMU Status"
register_type: holding
address: 143
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: etek_1
name: "B1 Reg110 RCMU mode"
register_type: holding
address: 110
value_type: U_WORD
# --- BORNE 2 ---
- platform: modbus_controller
modbus_controller_id: etek_2
name: "B2 Status"
id: status_b2
register_type: holding
address: 141
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: etek_2
name: "B2 PWM sortie"
id: pwm_b2
register_type: holding
address: 152
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: etek_2
name: "B2 Temperature"
id: temp_b2
register_type: holding
address: 157
unit_of_measurement: "°C"
value_type: U_WORD
filters:
- multiply: 0.1
- platform: modbus_controller
modbus_controller_id: etek_2
name: "B2 RCMU Status"
register_type: holding
address: 143
value_type: U_WORD
- platform: modbus_controller
modbus_controller_id: etek_2
name: "B2 Reg110 RCMU mode"
register_type: holding
address: 110
value_type: U_WORD
number:
# --- RÉGLAGE B1 ---
- platform: template
name: "B1 Réglage Intensité"
id: consigne_b1
min_value: 0
max_value: 32
step: 1
unit_of_measurement: "A"
initial_value: 0
optimistic: true
restore_value: false
set_action:
then:
- lambda: |-
uint16_t raw = (uint16_t)(x * 166.67);
auto cmd = modbus_controller::ModbusCommandItem::create_write_single_command(
id(etek_1), 152, raw);
id(etek_1)->queue_command(cmd);
# --- RÉGLAGE B2 ---
- platform: template
name: "B2 Réglage Intensité"
id: consigne_b2
min_value: 0
max_value: 32
step: 1
unit_of_measurement: "A"
initial_value: 0
optimistic: true
restore_value: false
set_action:
then:
- lambda: |-
uint16_t raw = (uint16_t)(x * 166.67);
auto cmd = modbus_controller::ModbusCommandItem::create_write_single_command(
id(etek_2), 152, raw);
id(etek_2)->queue_command(cmd);
# --- LOGIQUE DE GESTION DUO ---
interval:
- interval: 30s
then:
- lambda: |-
auto time = id(sntp_time).now();
bool est_en_hc = (time.hour >= 22 || time.hour < 6);
bool autorisation_charge = est_en_hc || id(mode_force).state;
if (!time.is_valid()) { autorisation_charge = true; }
// SÉCURITÉ THERMIQUE — coupe tout si > 50°C
float t1 = id(temp_b1).state;
float t2 = id(temp_b2).state;
if (t1 > 50.0 || t2 > 50.0) {
ESP_LOGW("THERMIQUE", "SURCHAUFFE ! B1=%.1f°C B2=%.1f°C — coupure urgence !", t1, t2);
auto cut1 = id(consigne_b1).make_call();
cut1.set_value(0.0); cut1.perform();
auto cut2 = id(consigne_b2).make_call();
cut2.set_value(0.0); cut2.perform();
return;
}
// B1 libre = pas de voiture OU charge terminée (Status 1 ou 2)
bool b1_libre = (id(status_b1).state <= 2.0);
// GESTION B1
auto call1 = id(consigne_b1).make_call();
if (autorisation_charge) {
if (id(consigne_b1).state < 6.0) { call1.set_value(32.0); call1.perform(); }
} else {
if (id(consigne_b1).state > 0) { call1.set_value(0.0); call1.perform(); }
}
// GESTION B2 — seulement si B1 libre
auto call2 = id(consigne_b2).make_call();
if (autorisation_charge && b1_libre) {
if (id(consigne_b2).state < 6.0) { call2.set_value(32.0); call2.perform(); }
} else {
if (id(consigne_b2).state > 0) { call2.set_value(0.0); call2.perform(); }
}
si vous souhaites le yaml de l'automation surchauffe et rmcu activé, n'hesitez pas