oui en il est en wifi, mai pour etre sur j’ai reflasher en USB
voila le code complet
substitutions:
device_name: "smart-powermeter-2"
project_name: "smart.powermeter"
project_version: "2.0"
ap_ssid: "Smart-Powermeter 2"
ap_pwd: "smartpowermeter2"
update_interval: 1s
probe_1_name: "CUMULUS L1"
probe_2_name: "CUMULUS L2"
probe_3_name: "CUMULUS L3"
probe_4_name: "Plaque de cuisson L1"
probe_5_name: "Plaque de cuissonL2"
probe_6_name: "Bassin"
esphome:
name: "${device_name}"
name_add_mac_suffix: true
project:
name: "${project_name}"
version: "${project_version}"
esp32:
board: esp32-s2-saola-1
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "4ulLkR3BXmTpjShwtXQdbDeTrPEkfEA35krp16TA0hc="
ota:
- platform: esphome
password: "6647a1a3b6f04087d989b14fab79e391"
external_components:
- source: github://dentra/esphome-components
backup:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Optional manual IP
manual_ip:
static_ip: 192.168.1.16
gateway: 192.168.1.254
subnet: 255.255.255.0
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Smart-Powermeter-1"
password: "obQR3S5Yu0Z3"
captive_portal:
web_server:
improv_serial:
time:
- platform: homeassistant
id: esptime
sensor:
- platform: adc
pin: GPIO1
id: Input_1
attenuation: 12db
update_interval: "${update_interval}"
- platform: adc
pin: GPIO2
id: Input_2
attenuation: 12db
update_interval: "${update_interval}"
- platform: adc
pin: GPIO3
id: Input_3
attenuation: 12db
update_interval: "${update_interval}"
- platform: adc
pin: GPIO4
id: Input_4
attenuation: 12db
update_interval: "${update_interval}"
- platform: adc
pin: GPIO5
id: Input_5
attenuation: 12db
update_interval: "${update_interval}"
- platform: adc
pin: GPIO6
id: Input_6
attenuation: 12db
update_interval: "${update_interval}"
# Intensitée par phase
- platform: ct_clamp
sensor: Input_1
id: Probe_1
name: "${probe_1_name}"
sample_duration: 200ms
update_interval: "${update_interval}"
filters:
- calibrate_linear:
- 0 -> 0
- 0.042 -> 2.72
- platform: ct_clamp
sensor: Input_2
name: "${probe_2_name}"
id: Probe_2
sample_duration: 200ms
update_interval: "${update_interval}"
filters:
- calibrate_linear:
- 0 -> 0
- 0.033 -> 1.07
- platform: ct_clamp
sensor: Input_3
name: "${probe_3_name}"
id: Probe_3
sample_duration: 200ms
update_interval: "${update_interval}"
filters:
- calibrate_linear:
- 0 -> 0
- 0.022 -> 0.66
- platform: ct_clamp
sensor: Input_4
name: "${probe_4_name}"
id: Probe_4
sample_duration: 200ms
update_interval: "${update_interval}"
filters:
- calibrate_linear:
- 0 -> 0
- 0.022 -> 0.66
- platform: ct_clamp
sensor: Input_5
name: "${probe_5_name}"
id: Probe_5
sample_duration: 200ms
update_interval: "${update_interval}"
filters:
- calibrate_linear:
- 0 -> 0
- 0.022 -> 0.66
- platform: ct_clamp
sensor: Input_6
name: "${probe_6_name}"
id: Probe_6
sample_duration: 200ms
update_interval: "${update_interval}"
filters:
- calibrate_linear:
- 0 -> 0
- 0.022 -> 0.66
# Intensitée par appareil
- platform: template
id: current_intensity_cumulus
name: "Courant Cumulus"
lambda: return (id(Probe_1).state + id(Probe_2).state + id(Probe_3).state);
unit_of_measurement: 'A'
update_interval: "${update_interval}"
accuracy_decimals: 1
- platform: template
id: current_intensity_plaque_de_cuisson
name: "Courant Plaque de cuisson"
lambda: return (id(Probe_4).state + id(Probe_5).state);
unit_of_measurement: 'A'
update_interval: "${update_interval}"
accuracy_decimals: 1
- platform: template
id: current_intensity_bassin
name: "Courant Bassin"
lambda: return id(Probe_6).state;
unit_of_measurement: 'A'
update_interval: "${update_interval}"
accuracy_decimals: 1
# Puissance par appareil
- platform: template
id: current_power_cumulus
name: "Puissance Cumulus"
lambda: return (id(Probe_1).state + id(Probe_2).state + id(Probe_3).state) * id(tension_moyenne).state;
unit_of_measurement: 'W'
update_interval: "${update_interval}"
accuracy_decimals: 0
- platform: template
id: current_power_plaque_de_cuisson
name: "Puissance Plaque de cuisson"
lambda: return (id(Probe_4).state + id(Probe_5).state + id(Probe_6).state) * id(tension_moyenne).state;
unit_of_measurement: 'W'
update_interval: "${update_interval}"
accuracy_decimals: 0
- platform: template
id: current_power_bassin
name: "Puissance Bassin"
lambda: return id(Probe_6).state * id(tension_moyenne).state;
unit_of_measurement: 'W'
update_interval: "${update_interval}"
accuracy_decimals: 0
# Consomation par appareil
- platform: total_daily_energy
name: "Consomation Cumulus"
power_id: current_power_cumulus
id: daily_power_cumulus
- platform: total_daily_energy
name: "Consomation Plaque de cuisson"
power_id: current_power_plaque_de_cuisson
id: daily_power_plaque_de_cuisson
- platform: total_daily_energy
name: "Consomation Bassin"
power_id: current_power_bassin
id: daily_power_bassin
# WiFi Signal
- platform: wifi_signal
name: "WiFi Signal Sensor"
id: wifisignal
update_interval: 20s
# Temps de fonctionnement
- platform: uptime
name: "Allumé depuis (s)"
id: uptime_sec
# Tension moyenne (récupérée de HA)
- platform: homeassistant
id: tension_moyenne_from_ha
entity_id: sensor.aquarium_voltage
- platform: template
name: "Tension moyenne"
update_interval: "${update_interval}"
id: tension_moyenne
lambda: return id(tension_moyenne_from_ha).state;
#lambda: if(isnan(id(tension_moyenne_from_ha).state)){return 666;} else {return id(tension_moyenne_from_ha).state;}
# Transformation des secondes en jours
text_sensor:
- platform: template
name: "Allumé depuis (j)"
lambda: |-
int seconds = (id(uptime_sec).state);
int days = seconds / (24 * 3600);
seconds = seconds % (24 * 3600);
int hours = seconds / 3600;
seconds = seconds % 3600;
int minutes = seconds / 60;
seconds = seconds % 60;
return { (String(days) +"d " + String(hours) +"h " + String(minutes) +"m "+ String(seconds) +"s").c_str() };
icon: mdi:clock-start
update_interval: 10s
# Led statut
output:
- platform: gpio
pin: GPIO08
id: status_led
light:
- platform: binary
name: "LED PCB"
output: status_led
switch:
- platform: restart
name: "Redémarrage"
font:
- file: "gfonts://Audiowide"
id: font_header
size: 15
- file: "gfonts://Audiowide"
id: font_gauge
size: 15
- file: "gfonts://Audiowide"
id: font_text
size: 13
- file: 'gfonts://Material+Symbols+Outlined'
id: font_icon
size: 18
glyphs:
- "\U0000f0b0" # wifi-strength-0
- "\U0000ebe4" # wifi-strength-1
- "\U0000ebd6" # wifi-strength-2
- "\U0000ebe1" # wifi-strength-3
- "\U0000e1d8" # wifi-strength-4
spi:
clk_pin: GPIO12
mosi_pin: GPIO11 # Works on the e-paper
image:
- file: https://smart-powermeter.readthedocs.io/en/v2r2/_images/Gauge.png
id: gauge
- file: https://smart-powermeter.readthedocs.io/en/v2r2/_images/Gauge_1.png
id: gauge_1
- file: mdi:home-lightning-bolt
id: power
resize: 18x18
- file: mdi:cash-multiple
id: cash
resize: 18x18
- file: mdi:currency-eur
id: euro
resize: 18x18
- file: mdi:lightning-bolt
id: bolt
resize: 22x22
- file: mdi:sine-wave
id: tension
resize: 18x18
display:
- platform: waveshare_epaper
cs_pin: GPIO10
dc_pin: GPIO13
busy_pin: GPIO14
reset_pin: GPIO15
model: 2.90inv2
rotation: 270
update_interval: 30s
full_update_every: 1
pages:
- id: page1
lambda: |-
#define H_LEFT_MARGIN 4
#define H_RIGHT_MARGIN 280
#define H_CENTER 128
#define V_WEATHER 0
#define V_CLOCK 1
#define V_WIFI 30
#define V_VOLTAGE 60
#define V_BATTERY 90
// WiFi quality
// it.image(0, 0, id(background));
// Time
int x_head = 230;
int y_head = 0;
it.strftime(x_head, y_head, id(font_text), TextAlign::TOP_LEFT,
"%H:%M", id(esptime).now());
// WiFi quality
if(id(wifisignal).has_state ()) {
if (id(wifisignal).state >= -50) {
// Excellent # mdi-wifi-strength-4
it.printf(x_head, y_head, id(font_icon), TextAlign::TOP_RIGHT, "\U0000e1d8");
} else if (id(wifisignal).state >= -60) {
//Good # mdi-wifi-strength-3
it.printf(x_head, y_head, id(font_icon), TextAlign::TOP_RIGHT, "\U0000ebe1");
} else if (id(wifisignal).state >= -67) {
//Fair # mdi-wifi-strength-2
it.printf(x_head, y_head, id(font_icon), TextAlign::TOP_RIGHT, "\U0000ebd6");
} else if (id(wifisignal).state >= -70) {
//Weak # mdi-wifi-strength-1
it.printf(x_head, y_head, id(font_icon), TextAlign::TOP_RIGHT, "\U0000ebe4");
} else {
//Unlikely working mdi-wifi-strength-0
it.printf(x_head, y_head, id(font_icon), TextAlign::TOP_RIGHT, "\U0000f0b0");
}
}
// Gauges
// General parameters
float pi = 3.141592653589793;
float alpha = 4.71238898038469; // Defined as the gauge angle in radians (270deg)
float beta = 2*pi - alpha;
int radius = 25; // Radius of the gauge in pixels
int thick = 7; // Size of the marker
// Probe 1
int min_range = 0;
int max_range = 10;
int xc = 40;
int yc = 33;
it.image(xc-radius, yc-radius, id(gauge));
float measured = id(Probe_1).state;
if (measured < min_range) {
measured = min_range;
}
if (measured > max_range) {
measured = max_range;
}
float val = (measured - min_range) / abs(max_range - min_range) * alpha;
int x0 = static_cast<int>(xc + radius * cos(pi / 2 + beta / 2 + val));
int y0 = static_cast<int>(yc + radius * sin(pi / 2 + beta / 2 + val));
int x1 = static_cast<int>(xc + (radius+thick) * cos(pi / 2 + beta / 2 + val + 0.1));
int y1 = static_cast<int>(yc + (radius+thick) * sin(pi / 2 + beta / 2 + val + 0.1));
int x2 = static_cast<int>(xc + (radius+thick) * cos(pi / 2 + beta / 2 + val - 0.1));
int y2 = static_cast<int>(yc + (radius+thick) * sin(pi / 2 + beta / 2 + val - 0.1));
it.line(x0, y0, x1, y1);
it.line(x1, y1, x2, y2);
it.line(x2, y2, x0, y0);
it.printf(xc, yc, id(font_gauge), TextAlign::CENTER,
"11");
it.printf(xc, yc + radius*0.75, id(font_gauge), TextAlign::TOP_CENTER,
"%.1fA", measured);
// Probe 2
min_range = 0;
max_range = 10;
xc = 100;
yc = 33;
it.image(xc-radius, yc-radius, id(gauge));
measured = id(Probe_2).state;
if (measured < min_range) {
measured = min_range;
}
if (measured > max_range) {
measured = max_range;
}
val = (measured - min_range) / abs(max_range - min_range) * alpha;
x0 = static_cast<int>(xc + radius * cos(pi / 2 + beta / 2 + val));
y0 = static_cast<int>(yc + radius * sin(pi / 2 + beta / 2 + val));
x1 = static_cast<int>(xc + (radius+thick) * cos(pi / 2 + beta / 2 + val + 0.1));
y1 = static_cast<int>(yc + (radius+thick) * sin(pi / 2 + beta / 2 + val + 0.1));
x2 = static_cast<int>(xc + (radius+thick) * cos(pi / 2 + beta / 2 + val - 0.1));
y2 = static_cast<int>(yc + (radius+thick) * sin(pi / 2 + beta / 2 + val - 0.1));
it.line(x0, y0, x1, y1);
it.line(x1, y1, x2, y2);
it.line(x2, y2, x0, y0);
it.printf(xc, yc, id(font_gauge), TextAlign::CENTER,
"12");
it.printf(xc, yc + radius*0.75, id(font_gauge), TextAlign::TOP_CENTER,
"%.1fA", measured);
// Probe 3
min_range = 0;
max_range = 10;
xc = 160;
yc = 33;
it.image(xc-radius, yc-radius, id(gauge));
measured = id(Probe_3).state;
if (measured < min_range) {
measured = min_range;
}
if (measured > max_range) {
measured = max_range;
}
val = (measured - min_range) / abs(max_range - min_range) * alpha;
x0 = static_cast<int>(xc + radius * cos(pi / 2 + beta / 2 + val));
y0 = static_cast<int>(yc + radius * sin(pi / 2 + beta / 2 + val));
x1 = static_cast<int>(xc + (radius+thick) * cos(pi / 2 + beta / 2 + val + 0.1));
y1 = static_cast<int>(yc + (radius+thick) * sin(pi / 2 + beta / 2 + val + 0.1));
x2 = static_cast<int>(xc + (radius+thick) * cos(pi / 2 + beta / 2 + val - 0.1));
y2 = static_cast<int>(yc + (radius+thick) * sin(pi / 2 + beta / 2 + val - 0.1));
it.line(x0, y0, x1, y1);
it.line(x1, y1, x2, y2);
it.line(x2, y2, x0, y0);
it.printf(xc, yc, id(font_gauge), TextAlign::CENTER,
"13");
it.printf(xc, yc + radius*0.75, id(font_gauge), TextAlign::TOP_CENTER,
"%.1fA", measured);
// Probe 4
min_range = 0;
max_range = 10;
xc = 40;
yc = 95;
it.image(xc-radius, yc-radius, id(gauge));
measured = id(Probe_4).state;
if (measured < min_range) {
measured = min_range;
}
if (measured > max_range) {
measured = max_range;
}
val = (measured - min_range) / abs(max_range - min_range) * alpha;
x0 = static_cast<int>(xc + radius * cos(pi / 2 + beta / 2 + val));
y0 = static_cast<int>(yc + radius * sin(pi / 2 + beta / 2 + val));
x1 = static_cast<int>(xc + (radius+thick) * cos(pi / 2 + beta / 2 + val + 0.1));
y1 = static_cast<int>(yc + (radius+thick) * sin(pi / 2 + beta / 2 + val + 0.1));
x2 = static_cast<int>(xc + (radius+thick) * cos(pi / 2 + beta / 2 + val - 0.1));
y2 = static_cast<int>(yc + (radius+thick) * sin(pi / 2 + beta / 2 + val - 0.1));
it.line(x0, y0, x1, y1);
it.line(x1, y1, x2, y2);
it.line(x2, y2, x0, y0);
it.printf(xc, yc, id(font_gauge), TextAlign::CENTER,
"14");
it.printf(xc, yc + radius*0.75, id(font_gauge), TextAlign::TOP_CENTER,
"%.1fA", measured);
// Probe 5
min_range = 0;
max_range = 10;
xc = 100;
yc = 95;
it.image(xc-radius, yc-radius, id(gauge));
measured = id(Probe_5).state;
if (measured < min_range) {
measured = min_range;
}
if (measured > max_range) {
measured = max_range;
}
val = (measured - min_range) / abs(max_range - min_range) * alpha;
x0 = static_cast<int>(xc + radius * cos(pi / 2 + beta / 2 + val));
y0 = static_cast<int>(yc + radius * sin(pi / 2 + beta / 2 + val));
x1 = static_cast<int>(xc + (radius+thick) * cos(pi / 2 + beta / 2 + val + 0.1));
y1 = static_cast<int>(yc + (radius+thick) * sin(pi / 2 + beta / 2 + val + 0.1));
x2 = static_cast<int>(xc + (radius+thick) * cos(pi / 2 + beta / 2 + val - 0.1));
y2 = static_cast<int>(yc + (radius+thick) * sin(pi / 2 + beta / 2 + val - 0.1));
it.line(x0, y0, x1, y1);
it.line(x1, y1, x2, y2);
it.line(x2, y2, x0, y0);
it.printf(xc, yc, id(font_gauge), TextAlign::CENTER,
"15");
it.printf(xc, yc + radius*0.75, id(font_gauge), TextAlign::TOP_CENTER,
"%.1fA", measured);
// Probe 6
min_range = 0;
max_range = 10;
xc = 160;
yc = 95;
it.image(xc-radius, yc-radius, id(gauge));
measured = id(Probe_6).state;
if (measured < min_range) {
measured = min_range;
}
if (measured > max_range) {
measured = max_range;
}
val = (measured - min_range) / abs(max_range - min_range) * alpha;
x0 = static_cast<int>(xc + radius * cos(pi / 2 + beta / 2 + val));
y0 = static_cast<int>(yc + radius * sin(pi / 2 + beta / 2 + val));
x1 = static_cast<int>(xc + (radius+thick) * cos(pi / 2 + beta / 2 + val + 0.1));
y1 = static_cast<int>(yc + (radius+thick) * sin(pi / 2 + beta / 2 + val + 0.1));
x2 = static_cast<int>(xc + (radius+thick) * cos(pi / 2 + beta / 2 + val - 0.1));
y2 = static_cast<int>(yc + (radius+thick) * sin(pi / 2 + beta / 2 + val - 0.1));
it.line(x0, y0, x1, y1);
it.line(x1, y1, x2, y2);
it.line(x2, y2, x0, y0);
it.printf(xc, yc, id(font_gauge), TextAlign::CENTER,
"16");
it.printf(xc, yc + radius*0.75, id(font_gauge), TextAlign::TOP_CENTER,
"%.1fA", measured);
// // Total parameters
// // Power gauge
// alpha = pi; // Defined as the gauge angle in radians (270deg)
// beta = 2*pi - alpha;
// radius = 40; // Radius of the gauge in pixels
// thick = 7;
// min_range = 0;
// max_range = 5;
// xc = 245;
// yc = 65;
// it.image(xc-radius, yc-radius, id(gauge_1));
// measured = id(current_power).state;
// if (measured < min_range) {
// measured = min_range;
// }
// if (measured > max_range) {
// measured = max_range;
// }
// val = (measured - min_range) / abs(max_range - min_range) * alpha;
// x0 = static_cast<int>(xc + radius * cos(pi / 2 + beta / 2 + val));
// y0 = static_cast<int>(yc + radius * sin(pi / 2 + beta / 2 + val));
// x1 = static_cast<int>(xc + (radius+thick) * cos(pi / 2 + beta / 2 + val + 0.1));
// y1 = static_cast<int>(yc + (radius+thick) * sin(pi / 2 + beta / 2 + val + 0.1));
// x2 = static_cast<int>(xc + (radius+thick) * cos(pi / 2 + beta / 2 + val - 0.1));
// y2 = static_cast<int>(yc + (radius+thick) * sin(pi / 2 + beta / 2 + val - 0.1));
// it.line(x0, y0, x1, y1);
// it.line(x1, y1, x2, y2);
// it.line(x2, y2, x0, y0);
// it.image(xc-11, yc-22, id(bolt));
// it.printf(xc, yc + radius/2, id(font_gauge), TextAlign::BOTTOM_CENTER,
// "%.1fkW", measured);
// // it.printf(xc, yc + radius/2, id(font_gauge), TextAlign::TOP_CENTER,
// // "kW");
// // Derivated parameters:
// measured = id(daily_power).state;
// it.printf(290, 85, id(font_gauge), TextAlign::TOP_RIGHT,
// "%.0fkWh", measured);
// it.image(200, 85, id(power));
// measured = id(cost).state;
// it.image(200, 105, id(cash));
// it.printf(275, 105, id(font_gauge), TextAlign::TOP_RIGHT,
// "%.2f", measured);
// it.image(275, 105, id(euro));
it.printf(200, 18, id(font_text), TextAlign::TOP_LEFT, "Cumulus:");
it.printf(200, 33, id(font_text), TextAlign::TOP_LEFT, "%.1fA %4.0fW", id(current_intensity_cumulus).state, id(current_power_cumulus).state);
it.printf(200, 46, id(font_text), TextAlign::TOP_LEFT, "Cuisson:");
it.printf(200, 61, id(font_text), TextAlign::TOP_LEFT, "%.1fA %4.0fW", id(current_intensity_plaque_de_cuisson).state, id(current_power_plaque_de_cuisson).state);
it.printf(200, 74, id(font_text), TextAlign::TOP_LEFT, "Bassin:");
it.printf(200, 89, id(font_text), TextAlign::TOP_LEFT, "%.1fA %4.0fW", id(current_intensity_bassin).state, id(current_power_bassin).state);
it.image(200, 110, id(tension));
it.printf(230, 110, id(font_text), TextAlign::TOP_LEFT, "%.2f V", id(tension_moyenne).state);
déclaration ligne 257 à 266
utilisation de la valeur: 205 / 213 / 221 / 688
je me rend compte en listant les ligne que j’utilise la valeur avant de l’avoir déclaré danbs le YAML, mais pas sur que cela est un impact sur la compilation ?