mirror of
https://github.com/Legolas-2025/esp32-energy-meter.git
synced 2026-08-18 12:44:58 +02:00
Add files via upload
This commit is contained in:
@@ -0,0 +1,618 @@
|
|||||||
|
# Advanced Features Guide
|
||||||
|
|
||||||
|
This guide covers advanced features and customization options for your ESP32 Energy Meter project.
|
||||||
|
|
||||||
|
## 🚀 Overview
|
||||||
|
|
||||||
|
The ESP32 Energy Meter project includes several advanced features that can be enabled and customized based on your specific requirements:
|
||||||
|
|
||||||
|
- **OLED Burn-in Protection**: Prevents screen damage from static content
|
||||||
|
- **Enhanced WiFi Monitoring**: Accurate connectivity status monitoring
|
||||||
|
- **Custom Display Layouts**: Flexible display configuration
|
||||||
|
- **Advanced Sensor Filtering**: Noise reduction and smoothing
|
||||||
|
- **MQTT Integration**: Alternative to Home Assistant API
|
||||||
|
- **Remote Configuration**: Dynamic parameter adjustment
|
||||||
|
|
||||||
|
## 🔄 OLED Burn-in Protection
|
||||||
|
|
||||||
|
### Current Implementation
|
||||||
|
The project includes automatic screen clearing to prevent OLED burn-in:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
lambda: !lambda |-
|
||||||
|
// Time integration for burn-in protection
|
||||||
|
time_t now = id(homeassistant_time).now().timestamp;
|
||||||
|
|
||||||
|
// Clear screen every 30 minutes to prevent OLED burn-in
|
||||||
|
if (now % 1800 == 0) { // Every 30 minutes
|
||||||
|
it.clear();
|
||||||
|
return; // Exit early to prevent drawing during clear
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rest of display logic...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customizable Parameters
|
||||||
|
```yaml
|
||||||
|
# Modify burn-in protection interval
|
||||||
|
lambda: !lambda |-
|
||||||
|
time_t now = id(homeassistant_time).now().timestamp;
|
||||||
|
|
||||||
|
// Custom interval: every 10 minutes (600 seconds)
|
||||||
|
if (now % 600 == 0) {
|
||||||
|
it.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alternative: Screen saver mode after 60 minutes
|
||||||
|
static bool screen_saver = false;
|
||||||
|
if (now > 3600 && !screen_saver) {
|
||||||
|
screen_saver = true;
|
||||||
|
// Display logo or blank screen
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Advanced Burn-in Protection
|
||||||
|
```yaml
|
||||||
|
# Enhanced burn-in protection with rotation
|
||||||
|
lambda: !lambda |-
|
||||||
|
time_t now = id(homeassistant_time).now().timestamp;
|
||||||
|
|
||||||
|
// Clear screen every 15 minutes
|
||||||
|
if (now % 900 == 0) {
|
||||||
|
it.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rotate display content every 30 minutes to distribute wear
|
||||||
|
static int rotation_counter = 0;
|
||||||
|
if (now % 1800 == 0) {
|
||||||
|
rotation_counter++;
|
||||||
|
it.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw based on rotation
|
||||||
|
switch (rotation_counter % 3) {
|
||||||
|
case 0:
|
||||||
|
// Standard layout
|
||||||
|
it.printf(it.get_width()/2, 38, id(baloo_32_700), TextAlign::CENTER, "%.1f W", id(power2).state);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
// Compact layout
|
||||||
|
it.printf(it.get_width()/2, 20, id(baloo_18_700), TextAlign::CENTER, "Power: %.1fW", id(power2).state);
|
||||||
|
it.printf(it.get_width()/2, 40, id(baloo_18_700), TextAlign::CENTER, "Voltage: %.1fV", id(voltage2).state);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
// Detailed layout with additional info
|
||||||
|
it.printf(it.get_width()/2, 20, id(baloo_18_700), TextAlign::CENTER, "P:%.1fW V:%.1fV", id(power2).state, id(voltage2).state);
|
||||||
|
it.printf(it.get_width()/2, 40, id(baloo_18_700), TextAlign::CENTER, "I:%.4fA", id(current2).state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📶 Enhanced WiFi Monitoring
|
||||||
|
|
||||||
|
### Current WiFi Status Logic
|
||||||
|
```yaml
|
||||||
|
binary_sensor:
|
||||||
|
- platform: template
|
||||||
|
name: "WiFi Connection Status"
|
||||||
|
id: connection_status
|
||||||
|
lambda: !lambda
|
||||||
|
return id(wifi_signal_strength).state > -70; // Connected if signal strength > -70 dBm
|
||||||
|
```
|
||||||
|
|
||||||
|
### Advanced WiFi Monitoring
|
||||||
|
```yaml
|
||||||
|
# Multiple WiFi network monitoring
|
||||||
|
wifi:
|
||||||
|
networks:
|
||||||
|
- ssid: !secret wifi_ssid
|
||||||
|
password: !secret wifi_password
|
||||||
|
priority: 1
|
||||||
|
- ssid: !secret backup_wifi_ssid
|
||||||
|
password: !secret backup_wifi_password
|
||||||
|
priority: 0.5
|
||||||
|
|
||||||
|
# Enhanced WiFi status with multiple criteria
|
||||||
|
binary_sensor:
|
||||||
|
- platform: template
|
||||||
|
name: "WiFi Connection Status"
|
||||||
|
id: connection_status
|
||||||
|
lambda: !lambda
|
||||||
|
// Check signal strength, connection time, and error rate
|
||||||
|
return (id(wifi_signal_strength).state > -75) &&
|
||||||
|
(id(uptime_sensor).state > 60) &&
|
||||||
|
(id(wifi_error_count).state < 5);
|
||||||
|
|
||||||
|
- platform: template
|
||||||
|
name: "WiFi Quality"
|
||||||
|
id: wifi_quality
|
||||||
|
lambda: !lambda
|
||||||
|
float signal = id(wifi_signal_strength).state;
|
||||||
|
if (signal > -50) return "Excellent";
|
||||||
|
if (signal > -60) return "Good";
|
||||||
|
if (signal > -70) return "Fair";
|
||||||
|
if (signal > -80) return "Poor";
|
||||||
|
return "Very Poor";
|
||||||
|
```
|
||||||
|
|
||||||
|
### WiFi Optimization
|
||||||
|
```yaml
|
||||||
|
wifi:
|
||||||
|
ssid: !secret wifi_ssid
|
||||||
|
password: !secret wifi_password
|
||||||
|
fast_connect: true # Skip network scanning
|
||||||
|
output_power: 12.0 # Maximum transmission power
|
||||||
|
# Enable WiFi power saving
|
||||||
|
power_save_mode: LIGHT
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📱 Custom Display Layouts
|
||||||
|
|
||||||
|
### Dynamic Display Content
|
||||||
|
```yaml
|
||||||
|
# Conditional display based on data availability
|
||||||
|
lambda: !lambda |-
|
||||||
|
time_t now = id(homeassistant_time).now().timestamp;
|
||||||
|
|
||||||
|
// Burn-in protection
|
||||||
|
if (now % 1800 == 0) {
|
||||||
|
it.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
it.clear();
|
||||||
|
|
||||||
|
// Header with time
|
||||||
|
it.printf(0, 0, id(baloo_18_500), TextAlign::TOP_LEFT,
|
||||||
|
"%02d:%02d",
|
||||||
|
id(homeassistant_time).now().hour,
|
||||||
|
id(homeassistant_time).now().minute);
|
||||||
|
|
||||||
|
// Main power display
|
||||||
|
if (!isnan(id(power2).state)) {
|
||||||
|
it.printf(it.get_width()/2, 30, id(baloo_32_700), TextAlign::CENTER,
|
||||||
|
"%.1f W", id(power2).state);
|
||||||
|
} else {
|
||||||
|
it.printf(it.get_width()/2, 30, id(baloo_32_700), TextAlign::CENTER, "No Data");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Secondary information
|
||||||
|
if (!isnan(id(voltage2).state)) {
|
||||||
|
it.printf(0, it.get_height() + 12, id(baloo_18_700), TextAlign::BOTTOM_LEFT,
|
||||||
|
"%.1f V", id(voltage2).state);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isnan(id(current2).state)) {
|
||||||
|
it.printf(it.get_width(), it.get_height() + 12, id(baloo_18_700), TextAlign::BOTTOM_RIGHT,
|
||||||
|
"%.4f A", id(current2).state);
|
||||||
|
}
|
||||||
|
|
||||||
|
// WiFi status with signal strength
|
||||||
|
float signal = id(wifi_signal_strength).state;
|
||||||
|
if (!isnan(signal)) {
|
||||||
|
if (signal > -70) {
|
||||||
|
it.print(it.get_width(), 0, id(icons_18), TextAlign::TOP_RIGHT, "\ue63e");
|
||||||
|
} else {
|
||||||
|
it.print(it.get_width(), 0, id(icons_18), TextAlign::TOP_RIGHT, "\ue648");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom Font Loading
|
||||||
|
```yaml
|
||||||
|
# Additional fonts for different display modes
|
||||||
|
font:
|
||||||
|
- file:
|
||||||
|
type: gfonts
|
||||||
|
family: Roboto+Mono
|
||||||
|
weight: 400
|
||||||
|
id: mono_14
|
||||||
|
size: 14
|
||||||
|
|
||||||
|
- file:
|
||||||
|
type: gfonts
|
||||||
|
family: Material+Icons
|
||||||
|
id: material_icons_24
|
||||||
|
size: 24
|
||||||
|
glyphs: ["\ue63e", "\ue648", "\ue8d5", "\ue84f"] # WiFi, WiFi off, battery, temperature
|
||||||
|
|
||||||
|
- file:
|
||||||
|
type: gfonts
|
||||||
|
family: JetBrains+Mono
|
||||||
|
weight: 700
|
||||||
|
id: jetbrains_mono_12
|
||||||
|
size: 12
|
||||||
|
```
|
||||||
|
|
||||||
|
### Display Themes
|
||||||
|
```yaml
|
||||||
|
# Display theme switching based on time of day
|
||||||
|
lambda: !lambda |-
|
||||||
|
time_t now = id(homeassistant_time).now().timestamp;
|
||||||
|
int hour = id(homeassistant_time).now().hour;
|
||||||
|
|
||||||
|
// Night mode (10 PM - 6 AM)
|
||||||
|
bool night_mode = (hour >= 22) || (hour <= 6);
|
||||||
|
|
||||||
|
if (now % 1800 == 0) {
|
||||||
|
it.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
it.clear();
|
||||||
|
|
||||||
|
// Night mode: dimmer colors, larger text
|
||||||
|
if (night_mode) {
|
||||||
|
it.set_brightness(0.3); // Assuming display supports brightness
|
||||||
|
it.print(-1, -4, id(baloo_18_500), "Night Mode");
|
||||||
|
it.printf(it.get_width()/2, 35, id(baloo_32_700), TextAlign::CENTER, "%.1f W", id(power2).state);
|
||||||
|
} else {
|
||||||
|
it.set_brightness(1.0);
|
||||||
|
it.print(-1, -4, id(baloo_18_500), "Energy Meter");
|
||||||
|
it.printf(it.get_width()/2, 38, id(baloo_32_700), TextAlign::CENTER, "%.1f W", id(power2).state);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rest of display logic...
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Advanced Sensor Filtering
|
||||||
|
|
||||||
|
### Exponential Moving Average
|
||||||
|
```yaml
|
||||||
|
# Smooth out noisy readings
|
||||||
|
sensor:
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: jsymk
|
||||||
|
id: power2_smoothed
|
||||||
|
name: "Power 2 (Smoothed)"
|
||||||
|
address: 0x0052
|
||||||
|
unit_of_measurement: "W"
|
||||||
|
register_type: holding
|
||||||
|
value_type: U_DWORD
|
||||||
|
filters:
|
||||||
|
- multiply: 0.0001
|
||||||
|
- exponential_moving_average:
|
||||||
|
alpha: 0.1 # Lower values = more smoothing
|
||||||
|
beta: 0.9
|
||||||
|
```
|
||||||
|
|
||||||
|
### Outlier Detection
|
||||||
|
```yaml
|
||||||
|
# Remove extreme outliers
|
||||||
|
sensor:
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: jsymk
|
||||||
|
id: power2_filtered
|
||||||
|
name: "Power 2 (Filtered)"
|
||||||
|
address: 0x0052
|
||||||
|
unit_of_measurement: "W"
|
||||||
|
register_type: holding
|
||||||
|
value_type: U_DWORD
|
||||||
|
filters:
|
||||||
|
- multiply: 0.0001
|
||||||
|
- delta: 100.0 # Remove changes > 100W
|
||||||
|
- clamp:
|
||||||
|
min: 0.0
|
||||||
|
max: 10000.0 # Clamp to reasonable range
|
||||||
|
```
|
||||||
|
|
||||||
|
### Calibration Filters
|
||||||
|
```yaml
|
||||||
|
# Apply calibration corrections
|
||||||
|
sensor:
|
||||||
|
- platform: modbus_controller
|
||||||
|
modbus_controller_id: jsymk
|
||||||
|
id: voltage2_calibrated
|
||||||
|
name: "Voltage 2 (Calibrated)"
|
||||||
|
address: 0x0050
|
||||||
|
unit_of_measurement: "V"
|
||||||
|
register_type: holding
|
||||||
|
value_type: U_DWORD
|
||||||
|
filters:
|
||||||
|
- multiply: 0.0001
|
||||||
|
- offset: -2.3 # Apply measured offset
|
||||||
|
- calibrate_linear:
|
||||||
|
- 0.0 -> 0.0
|
||||||
|
- 240.0 -> 242.1 # Correct for systematic error
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📡 MQTT Integration
|
||||||
|
|
||||||
|
### MQTT Configuration
|
||||||
|
```yaml
|
||||||
|
# Alternative to Home Assistant API
|
||||||
|
mqtt:
|
||||||
|
broker: 192.168.1.100
|
||||||
|
port: 1883
|
||||||
|
username: !secret mqtt_username
|
||||||
|
password: !secret mqtt_password
|
||||||
|
topic_prefix: energy_meter
|
||||||
|
|
||||||
|
sensor:
|
||||||
|
- platform: modbus_controller
|
||||||
|
# ... other config ...
|
||||||
|
mqtt:
|
||||||
|
state_topic: "energy_meter/power_2/state"
|
||||||
|
value_template: "{{ value }}"
|
||||||
|
```
|
||||||
|
|
||||||
|
### MQTT Sensors
|
||||||
|
```yaml
|
||||||
|
# Send sensor data to MQTT topics
|
||||||
|
sensor:
|
||||||
|
- platform: mqtt_sensormqtt:
|
||||||
|
name: "ESP32 Power"
|
||||||
|
state_topic: "energy_meter/power"
|
||||||
|
unit_of_measurement: "W"
|
||||||
|
value_template: "{{ value | float(0) }}"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🌍 Remote Configuration
|
||||||
|
|
||||||
|
### HTTP Server
|
||||||
|
```yaml
|
||||||
|
# Simple web server for remote configuration
|
||||||
|
web_server:
|
||||||
|
port: 80
|
||||||
|
auth:
|
||||||
|
username: admin
|
||||||
|
password: !secret web_password
|
||||||
|
```
|
||||||
|
|
||||||
|
### API Endpoints
|
||||||
|
```yaml
|
||||||
|
# Custom API for external control
|
||||||
|
api:
|
||||||
|
services:
|
||||||
|
- service: set_update_interval
|
||||||
|
variables:
|
||||||
|
interval: int
|
||||||
|
then:
|
||||||
|
- lambda: >-
|
||||||
|
id(jsymk).set_update_interval(interval);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Over-the-Air Updates
|
||||||
|
```yaml
|
||||||
|
# Enhanced OTA with progress monitoring
|
||||||
|
ota:
|
||||||
|
- platform: esphome
|
||||||
|
password: !secret ota_password
|
||||||
|
id: ota_component
|
||||||
|
platformio_options:
|
||||||
|
board_build.extra_flags:
|
||||||
|
- -DESP32_OTA_PROGRESS_PIN=2
|
||||||
|
- -DESP32_OTA_PROGRESS_LED=4
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 Data Logging and Analytics
|
||||||
|
|
||||||
|
### Local Data Storage
|
||||||
|
```yaml
|
||||||
|
# Store data locally for analysis
|
||||||
|
text_sensor:
|
||||||
|
- platform: template
|
||||||
|
name: "Last Update"
|
||||||
|
id: last_update
|
||||||
|
lambda: !lambda
|
||||||
|
return to_string(id(homeassistant_time).now().strftime("%Y-%m-%d %H:%M:%S"));
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom Analytics
|
||||||
|
```yaml
|
||||||
|
# Calculate energy statistics
|
||||||
|
sensor:
|
||||||
|
- platform: template
|
||||||
|
name: "Peak Power Today"
|
||||||
|
id: peak_power_today
|
||||||
|
unit_of_measurement: "W"
|
||||||
|
state_class: measurement
|
||||||
|
lambda: !lambda
|
||||||
|
static float max_power = 0.0;
|
||||||
|
float current_power = id(power2).state;
|
||||||
|
if (current_power > max_power) {
|
||||||
|
max_power = current_power;
|
||||||
|
}
|
||||||
|
// Reset at midnight
|
||||||
|
if (id(homeassistant_time).now().hour == 0 && id(homeassistant_time).now().minute == 0) {
|
||||||
|
max_power = 0.0;
|
||||||
|
}
|
||||||
|
return max_power;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Power Factor Monitoring
|
||||||
|
```yaml
|
||||||
|
# Advanced power quality monitoring
|
||||||
|
sensor:
|
||||||
|
- platform: template
|
||||||
|
name: "Power Quality Score"
|
||||||
|
id: power_quality_score
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
lambda: !lambda
|
||||||
|
float voltage = id(voltage2).state;
|
||||||
|
float frequency = id(frequency).state;
|
||||||
|
float pf = id(powerfactor2).state;
|
||||||
|
|
||||||
|
int score = 100;
|
||||||
|
|
||||||
|
// Voltage quality (220-240V)
|
||||||
|
if (voltage < 220) score -= (220 - voltage) * 2;
|
||||||
|
if (voltage > 240) score -= (voltage - 240) * 2;
|
||||||
|
|
||||||
|
// Frequency quality (49-51 Hz)
|
||||||
|
if (frequency < 49) score -= (49 - frequency) * 10;
|
||||||
|
if (frequency > 51) score -= (frequency - 51) * 10;
|
||||||
|
|
||||||
|
// Power factor quality (>0.9)
|
||||||
|
if (pf < 0.9) score -= (0.9 - pf) * 50;
|
||||||
|
|
||||||
|
return clamp(score, 0, 100);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔄 Conditional Updates
|
||||||
|
|
||||||
|
### Smart Update Intervals
|
||||||
|
```yaml
|
||||||
|
# Adaptive update intervals based on power consumption
|
||||||
|
sensor:
|
||||||
|
- platform: template
|
||||||
|
id: dynamic_update_interval
|
||||||
|
lambda: !lambda
|
||||||
|
float power = id(power2).state;
|
||||||
|
if (power > 1000) return 1.0; // High power: update every 1s
|
||||||
|
if (power > 100) return 2.0; // Medium power: update every 2s
|
||||||
|
return 5.0; // Low power: update every 5s
|
||||||
|
```
|
||||||
|
|
||||||
|
### Conditional Display Updates
|
||||||
|
```yaml
|
||||||
|
# Only update display when values change significantly
|
||||||
|
lambda: !lambda |-
|
||||||
|
static float last_power = -1.0;
|
||||||
|
static float last_voltage = -1.0;
|
||||||
|
static float last_current = -1.0;
|
||||||
|
|
||||||
|
float current_power = id(power2).state;
|
||||||
|
float current_voltage = id(voltage2).state;
|
||||||
|
float current_current = id(current2).state;
|
||||||
|
|
||||||
|
bool need_update = false;
|
||||||
|
|
||||||
|
// Check for significant changes (>5% or >50W)
|
||||||
|
if (fabs(current_power - last_power) > max(last_power * 0.05, 50.0)) {
|
||||||
|
need_update = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update display only if needed
|
||||||
|
if (need_update || millis() % 30000 < 1000) { // Force update every 30s
|
||||||
|
last_power = current_power;
|
||||||
|
last_voltage = current_voltage;
|
||||||
|
last_current = current_current;
|
||||||
|
|
||||||
|
// Display update logic...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔒 Security Enhancements
|
||||||
|
|
||||||
|
### Secure Communication
|
||||||
|
```yaml
|
||||||
|
# Enable HTTPS and secure connections
|
||||||
|
web_server:
|
||||||
|
port: 443
|
||||||
|
ssl_certificate: /config/cert.pem
|
||||||
|
ssl_private_key: /config/key.pem
|
||||||
|
|
||||||
|
mqtt:
|
||||||
|
broker: 192.168.1.100
|
||||||
|
port: 8883
|
||||||
|
username: !secret mqtt_username
|
||||||
|
password: !secret mqtt_password
|
||||||
|
certificate: /config/ca.pem
|
||||||
|
```
|
||||||
|
|
||||||
|
### Access Control
|
||||||
|
```yaml
|
||||||
|
# API authentication
|
||||||
|
api:
|
||||||
|
encryption:
|
||||||
|
key: !secret api_key
|
||||||
|
services:
|
||||||
|
- service: set_calibration
|
||||||
|
variables:
|
||||||
|
offset: float
|
||||||
|
then:
|
||||||
|
- lambda: >-
|
||||||
|
if (id(homeassistant_time).now().hour < 6 ||
|
||||||
|
id(homeassistant_time).now().hour > 22) {
|
||||||
|
// Only allow calibration during daytime
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎯 Performance Optimization
|
||||||
|
|
||||||
|
### Memory Management
|
||||||
|
```yaml
|
||||||
|
esp32:
|
||||||
|
board: esp32dev
|
||||||
|
framework:
|
||||||
|
type: esp-idf
|
||||||
|
psram:
|
||||||
|
mode: octal
|
||||||
|
speed: 80mhz
|
||||||
|
|
||||||
|
# Optimize heap usage
|
||||||
|
substitutions:
|
||||||
|
update_interval: "5s"
|
||||||
|
font_cache_size: "3"
|
||||||
|
```
|
||||||
|
|
||||||
|
### CPU Optimization
|
||||||
|
```yaml
|
||||||
|
# Optimize for low power consumption
|
||||||
|
esp32:
|
||||||
|
board: esp32dev
|
||||||
|
board_flash_mode: qio
|
||||||
|
board_flash_freq: 80m
|
||||||
|
board_flash_size: 4MB
|
||||||
|
|
||||||
|
# Power management
|
||||||
|
deep_sleep:
|
||||||
|
run_duration: 30s # Active for 30s
|
||||||
|
sleep_duration: 60s # Sleep for 60s
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📈 Custom Dashboard Widgets
|
||||||
|
|
||||||
|
### Power Usage Widget
|
||||||
|
```yaml
|
||||||
|
# Custom widget for real-time power display
|
||||||
|
web_server:
|
||||||
|
index: index.html
|
||||||
|
|
||||||
|
# Custom HTML for power display
|
||||||
|
frontend:
|
||||||
|
themes:
|
||||||
|
default:
|
||||||
|
primary-color: "#03a9f4"
|
||||||
|
accent-color: "#ff5722"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Troubleshooting Advanced Features
|
||||||
|
|
||||||
|
### Debug Logging
|
||||||
|
```yaml
|
||||||
|
logger:
|
||||||
|
level: DEBUG
|
||||||
|
logs:
|
||||||
|
modbus: DEBUG
|
||||||
|
sensor: DEBUG
|
||||||
|
wifi: DEBUG
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance Monitoring
|
||||||
|
```yaml
|
||||||
|
sensor:
|
||||||
|
- platform: uptime
|
||||||
|
name: "Uptime"
|
||||||
|
id: uptime_sensor
|
||||||
|
|
||||||
|
- platform: template
|
||||||
|
name: "Free Heap"
|
||||||
|
lambda: !lambda
|
||||||
|
return ESP.getFreeHeap();
|
||||||
|
unit_of_measurement: "bytes"
|
||||||
|
|
||||||
|
- platform: template
|
||||||
|
name: "WiFi Errors"
|
||||||
|
id: wifi_error_count
|
||||||
|
lambda: !lambda
|
||||||
|
// Count WiFi connection errors
|
||||||
|
static int error_count = 0;
|
||||||
|
return error_count;
|
||||||
|
```
|
||||||
|
|
||||||
|
For more advanced features and customization options, refer to the [ESPHome Documentation](https://esphome.io/) and experiment with the configuration to suit your specific needs.
|
||||||
@@ -0,0 +1,480 @@
|
|||||||
|
# Home Assistant Integration Guide
|
||||||
|
|
||||||
|
This guide covers how to integrate your ESP32 Energy Meter with Home Assistant for comprehensive energy monitoring and automation.
|
||||||
|
|
||||||
|
## 🎯 Overview
|
||||||
|
|
||||||
|
Home Assistant provides a powerful platform for energy monitoring, allowing you to:
|
||||||
|
- Create detailed energy dashboards
|
||||||
|
- Set up energy usage alerts
|
||||||
|
- Integrate with utility companies
|
||||||
|
- Automate based on consumption
|
||||||
|
- Analyze trends and patterns
|
||||||
|
|
||||||
|
## 🔗 Integration Methods
|
||||||
|
|
||||||
|
### Method 1: Auto-Discovery (Recommended)
|
||||||
|
1. **Power on ESP32**: Device will broadcast presence on network
|
||||||
|
2. **Home Assistant Discovery**: Device appears under "Devices & Services"
|
||||||
|
3. **Add Integration**: Click "Configure" to add ESP32 Energy Meter
|
||||||
|
4. **Enter API Key**: Provide the API key when prompted
|
||||||
|
|
||||||
|
### Method 2: Manual Integration
|
||||||
|
1. Go to **Configuration** → **Devices & Services**
|
||||||
|
2. Click **Add Integration**
|
||||||
|
3. Search for **ESPHome**
|
||||||
|
4. Enter IP address: `192.168.1.XXX`
|
||||||
|
5. Enter API key
|
||||||
|
|
||||||
|
## 📊 Available Entities
|
||||||
|
|
||||||
|
### Power Monitoring Entities
|
||||||
|
```yaml
|
||||||
|
# Primary power sensors
|
||||||
|
sensor.esp32_energy_meter_power_1 # Channel 1 Power (W)
|
||||||
|
sensor.esp32_energy_meter_power_2 # Channel 2 Power (W)
|
||||||
|
sensor.esp32_energy_meter_voltage_1 # Channel 1 Voltage (V)
|
||||||
|
sensor.esp32_energy_meter_voltage_2 # Channel 2 Voltage (V)
|
||||||
|
sensor.esp32_energy_meter_current_1 # Channel 1 Current (A)
|
||||||
|
sensor.esp32_energy_meter_current_2 # Channel 2 Current (A)
|
||||||
|
sensor.esp32_energy_meter_energy_1 # Channel 1 Energy (kWh)
|
||||||
|
sensor.esp32_energy_meter_energy_2 # Channel 2 Energy (kWh)
|
||||||
|
```
|
||||||
|
|
||||||
|
### System Monitoring Entities
|
||||||
|
```yaml
|
||||||
|
# System status
|
||||||
|
sensor.esp32_energy_meter_wifi_signal_strength # WiFi Signal (dBm)
|
||||||
|
binary_sensor.esp32_energy_meter_wifi_connection_status # Connection Status
|
||||||
|
sensor.esp32_energy_meter_frequency # AC Frequency (Hz)
|
||||||
|
sensor.esp32_energy_meter_power_factor_1 # Channel 1 Power Factor
|
||||||
|
sensor.esp32_energy_meter_power_factor_2 # Channel 2 Power Factor
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🏠 Energy Dashboard Setup
|
||||||
|
|
||||||
|
### Step 1: Configure Energy Sources
|
||||||
|
1. Go to **Configuration** → **Energy**
|
||||||
|
2. Click **Add Consumption** under "Electricity Grid"
|
||||||
|
3. Select appropriate energy sensor
|
||||||
|
4. Set energy source details
|
||||||
|
|
||||||
|
### Step 2: Add Consumption Sources
|
||||||
|
```yaml
|
||||||
|
# Recommended configuration for energy dashboard
|
||||||
|
consumption:
|
||||||
|
- sensor.esp32_energy_meter_energy_2 # Main consumption
|
||||||
|
- sensor.esp32_energy_meter_energy_1 # Secondary circuit (optional)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Configure Sensors for Dashboard
|
||||||
|
```yaml
|
||||||
|
# Template sensors for better dashboard integration
|
||||||
|
template:
|
||||||
|
sensors:
|
||||||
|
# Daily energy consumption
|
||||||
|
daily_energy_consumption:
|
||||||
|
friendly_name: "Daily Energy Consumption"
|
||||||
|
unit_of_measurement: "kWh"
|
||||||
|
value_template: >-
|
||||||
|
{% set today = states('sensor.date') %}
|
||||||
|
{{ states('sensor.esp32_energy_meter_energy_2') | float(0) }}
|
||||||
|
icon_template: mdi:flash
|
||||||
|
|
||||||
|
# Real-time power usage
|
||||||
|
current_power_usage:
|
||||||
|
friendly_name: "Current Power Usage"
|
||||||
|
unit_of_measurement: "W"
|
||||||
|
value_template: "{{ states('sensor.esp32_energy_meter_power_2') | float(0) }}"
|
||||||
|
icon_template: mdi:lightning-bolt
|
||||||
|
|
||||||
|
# Power cost estimation
|
||||||
|
estimated_power_cost:
|
||||||
|
friendly_name: "Estimated Power Cost"
|
||||||
|
unit_of_measurement: "$/day"
|
||||||
|
value_template: >-
|
||||||
|
{{ (states('sensor.esp32_energy_meter_power_2') | float(0) * 0.12 / 1000) | round(2) }}
|
||||||
|
icon_template: mdi:currency-usd
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📈 Creating Energy Cards
|
||||||
|
|
||||||
|
### Power Usage Card
|
||||||
|
```yaml
|
||||||
|
type: entities
|
||||||
|
entities:
|
||||||
|
- entity: sensor.current_power_usage
|
||||||
|
name: Current Power
|
||||||
|
icon: mdi:lightning-bolt
|
||||||
|
- entity: sensor.esp32_energy_meter_power_1
|
||||||
|
name: Circuit 1 Power
|
||||||
|
- entity: sensor.esp32_energy_meter_power_2
|
||||||
|
name: Circuit 2 Power
|
||||||
|
show_header_toggle: false
|
||||||
|
title: Real-time Power Usage
|
||||||
|
```
|
||||||
|
|
||||||
|
### Energy Statistics Card
|
||||||
|
```yaml
|
||||||
|
type: statistics-graph
|
||||||
|
entities:
|
||||||
|
- sensor.esp32_energy_meter_power_2
|
||||||
|
period: 24h
|
||||||
|
stat_types:
|
||||||
|
- change
|
||||||
|
- max
|
||||||
|
- mean
|
||||||
|
title: 24 Hour Power Statistics
|
||||||
|
```
|
||||||
|
|
||||||
|
### Energy Gauge Card
|
||||||
|
```yaml
|
||||||
|
type: gauge
|
||||||
|
entity: sensor.current_power_usage
|
||||||
|
min: 0
|
||||||
|
max: 5000
|
||||||
|
severity:
|
||||||
|
green: 0
|
||||||
|
yellow: 2000
|
||||||
|
red: 4000
|
||||||
|
unit: W
|
||||||
|
title: Current Power Usage
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔔 Energy Alerts and Automations
|
||||||
|
|
||||||
|
### High Power Usage Alert
|
||||||
|
```yaml
|
||||||
|
automation:
|
||||||
|
- id: high_power_usage_alert
|
||||||
|
alias: "High Power Usage Alert"
|
||||||
|
description: "Alert when power usage exceeds threshold"
|
||||||
|
trigger:
|
||||||
|
- platform: numeric_state
|
||||||
|
entity_id: sensor.esp32_energy_meter_power_2
|
||||||
|
above: 3000 # 3000W threshold
|
||||||
|
condition:
|
||||||
|
- condition: time
|
||||||
|
after: "08:00:00"
|
||||||
|
before: "22:00:00"
|
||||||
|
action:
|
||||||
|
- service: notify.persistent_notification
|
||||||
|
data:
|
||||||
|
title: "High Power Usage Alert"
|
||||||
|
message: "Current power usage is {{ states('sensor.esp32_energy_meter_power_2') }}W"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Energy Cost Tracking
|
||||||
|
```yaml
|
||||||
|
automation:
|
||||||
|
- id: daily_energy_report
|
||||||
|
alias: "Daily Energy Report"
|
||||||
|
description: "Send daily energy consumption report"
|
||||||
|
trigger:
|
||||||
|
- platform: time
|
||||||
|
at: "23:59:00"
|
||||||
|
condition:
|
||||||
|
- condition: time
|
||||||
|
weekday:
|
||||||
|
- mon
|
||||||
|
- wed
|
||||||
|
- fri
|
||||||
|
action:
|
||||||
|
- service: notify.telegram
|
||||||
|
data:
|
||||||
|
message: >-
|
||||||
|
Daily Energy Report:
|
||||||
|
Power: {{ states('sensor.esp32_energy_meter_power_2') }}W
|
||||||
|
Energy: {{ states('sensor.esp32_energy_meter_energy_2') }}kWh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Power Quality Monitoring
|
||||||
|
```yaml
|
||||||
|
sensor:
|
||||||
|
- platform: template
|
||||||
|
sensors:
|
||||||
|
power_quality_status:
|
||||||
|
friendly_name: "Power Quality"
|
||||||
|
value_template: >-
|
||||||
|
{% set voltage = states('sensor.esp32_energy_meter_voltage_2') | float(0) %}
|
||||||
|
{% set frequency = states('sensor.esp32_energy_meter_frequency') | float(0) %}
|
||||||
|
{% set pf = states('sensor.esp32_energy_meter_power_factor_2') | float(1) %}
|
||||||
|
|
||||||
|
{% if 220 <= voltage <= 240 and 49 <= frequency <= 51 and pf >= 0.9 %}
|
||||||
|
Good
|
||||||
|
{% elif 210 <= voltage <= 250 and 48 <= frequency <= 52 %}
|
||||||
|
Fair
|
||||||
|
{% else %}
|
||||||
|
Poor
|
||||||
|
{% endif %}
|
||||||
|
icon_template: >-
|
||||||
|
{% set status = states('sensor.power_quality_status') %}
|
||||||
|
{% if status == 'Good' %}
|
||||||
|
mdi:check-circle
|
||||||
|
{% elif status == 'Fair' %}
|
||||||
|
mdi:alert-circle
|
||||||
|
{% else %}
|
||||||
|
mdi:alert-octagon
|
||||||
|
{% endif %}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🏠 Home Automation Examples
|
||||||
|
|
||||||
|
### Smart Appliance Control
|
||||||
|
```yaml
|
||||||
|
automation:
|
||||||
|
- id: turn_off_high_consumption_device
|
||||||
|
alias: "Auto Turn Off High Consumption Device"
|
||||||
|
description: "Turn off appliances when power usage is too high"
|
||||||
|
trigger:
|
||||||
|
- platform: numeric_state
|
||||||
|
entity_id: sensor.esp32_energy_meter_power_2
|
||||||
|
above: 4000
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: switch.large_appliance
|
||||||
|
state: "on"
|
||||||
|
action:
|
||||||
|
- service: switch.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: switch.large_appliance
|
||||||
|
- service: notify.mobile_app_phone
|
||||||
|
data:
|
||||||
|
message: "Auto turned off large appliance due to high power usage"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Energy Saving Mode
|
||||||
|
```yaml
|
||||||
|
automation:
|
||||||
|
- id: energy_saving_mode
|
||||||
|
alias: "Energy Saving Mode"
|
||||||
|
description: "Activate energy saving mode during peak hours"
|
||||||
|
trigger:
|
||||||
|
- platform: time
|
||||||
|
at: "16:00:00"
|
||||||
|
condition:
|
||||||
|
- condition: time
|
||||||
|
weekday:
|
||||||
|
- mon
|
||||||
|
- tue
|
||||||
|
- wed
|
||||||
|
- thu
|
||||||
|
- fri
|
||||||
|
action:
|
||||||
|
- service: climate.set_temperature
|
||||||
|
target:
|
||||||
|
entity_id: climate.main_thermostat
|
||||||
|
data:
|
||||||
|
temperature: 20
|
||||||
|
- service: light.turn_off
|
||||||
|
target:
|
||||||
|
entity_id: group.living_room_lights
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📊 Advanced Dashboard Configuration
|
||||||
|
|
||||||
|
### Custom Energy Dashboard
|
||||||
|
```yaml
|
||||||
|
views:
|
||||||
|
- title: Energy Dashboard
|
||||||
|
path: energy_dashboard
|
||||||
|
icon: mdi:flash
|
||||||
|
cards:
|
||||||
|
- type: energy-distribution
|
||||||
|
title: Energy Distribution
|
||||||
|
link_entity: sensor.esp32_energy_meter_energy_2
|
||||||
|
link_type: consumption
|
||||||
|
source_type: grid
|
||||||
|
chart_type: pie
|
||||||
|
|
||||||
|
- type: energy-usage-graph
|
||||||
|
title: Energy Usage
|
||||||
|
period: 24h
|
||||||
|
start: "{{ now() - timedelta(days=1) }}"
|
||||||
|
end: "{{ now() }}"
|
||||||
|
|
||||||
|
- type: thermostat
|
||||||
|
entity: climate.main_thermostat
|
||||||
|
theme: default
|
||||||
|
|
||||||
|
- type: grid
|
||||||
|
columns: 2
|
||||||
|
cards:
|
||||||
|
- type: gauge
|
||||||
|
entity: sensor.current_power_usage
|
||||||
|
title: Current Power
|
||||||
|
unit: W
|
||||||
|
severity:
|
||||||
|
green: 0
|
||||||
|
yellow: 2000
|
||||||
|
red: 4000
|
||||||
|
|
||||||
|
- type: statistic
|
||||||
|
name: Average Power
|
||||||
|
entity: sensor.esp32_energy_meter_power_2
|
||||||
|
period: day
|
||||||
|
stat_type: mean
|
||||||
|
|
||||||
|
- type: sensor
|
||||||
|
entity: sensor.esp32_energy_meter_voltage_2
|
||||||
|
name: Voltage
|
||||||
|
|
||||||
|
- type: sensor
|
||||||
|
entity: sensor.esp32_energy_meter_frequency
|
||||||
|
name: Frequency
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Configuration Tips
|
||||||
|
|
||||||
|
### Sensor Naming Conventions
|
||||||
|
```yaml
|
||||||
|
# Use descriptive names for better organization
|
||||||
|
sensor:
|
||||||
|
- platform: modbus_controller
|
||||||
|
name: "Kitchen Power"
|
||||||
|
id: power_kitchen
|
||||||
|
- platform: modbus_controller
|
||||||
|
name: "Living Room Power"
|
||||||
|
id: power_living_room
|
||||||
|
```
|
||||||
|
|
||||||
|
### Custom Device Classes
|
||||||
|
```yaml
|
||||||
|
# Use appropriate device classes for better integration
|
||||||
|
sensor:
|
||||||
|
- platform: modbus_controller
|
||||||
|
device_class: power # For power measurements
|
||||||
|
address: 0x0052
|
||||||
|
unit_of_measurement: "W"
|
||||||
|
|
||||||
|
- platform: modbus_controller
|
||||||
|
device_class: voltage # For voltage measurements
|
||||||
|
address: 0x0050
|
||||||
|
unit_of_measurement: "V"
|
||||||
|
|
||||||
|
- platform: modbus_controller
|
||||||
|
device_class: current # For current measurements
|
||||||
|
address: 0x0051
|
||||||
|
unit_of_measurement: "A"
|
||||||
|
```
|
||||||
|
|
||||||
|
### State Classes for Energy
|
||||||
|
```yaml
|
||||||
|
# Proper state classes for energy measurements
|
||||||
|
sensor:
|
||||||
|
- platform: modbus_controller
|
||||||
|
address: 0x004B # Energy register
|
||||||
|
unit_of_measurement: "kWh"
|
||||||
|
state_class: total # For cumulative energy
|
||||||
|
device_class: energy
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📱 Mobile App Integration
|
||||||
|
|
||||||
|
### Mobile Card Configuration
|
||||||
|
```yaml
|
||||||
|
# Optimized for mobile viewing
|
||||||
|
cards:
|
||||||
|
- type: entities
|
||||||
|
title: Energy Overview
|
||||||
|
entities:
|
||||||
|
- sensor.current_power_usage
|
||||||
|
- sensor.esp32_energy_meter_energy_2
|
||||||
|
- sensor.esp32_energy_meter_voltage_2
|
||||||
|
- binary_sensor.esp32_energy_meter_wifi_connection_status
|
||||||
|
show_header_toggle: false
|
||||||
|
|
||||||
|
- type: gauge
|
||||||
|
title: Power Usage
|
||||||
|
entity: sensor.current_power_usage
|
||||||
|
min: 0
|
||||||
|
max: 5000
|
||||||
|
unit: W
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔄 Data Retention and History
|
||||||
|
|
||||||
|
### Recorder Configuration
|
||||||
|
```yaml
|
||||||
|
# In configuration.yaml
|
||||||
|
recorder:
|
||||||
|
purge_keep_days: 365 # Keep 1 year of data
|
||||||
|
commit_interval: 5 # Commit every 5 seconds
|
||||||
|
|
||||||
|
exclude:
|
||||||
|
entities:
|
||||||
|
- binary_sensor.esp32_energy_meter_wifi_connection_status
|
||||||
|
```
|
||||||
|
|
||||||
|
### Statistics Configuration
|
||||||
|
```yaml
|
||||||
|
# Enable statistics for energy calculations
|
||||||
|
statistics:
|
||||||
|
sensors:
|
||||||
|
- entity_id: sensor.esp32_energy_meter_energy_2
|
||||||
|
type: state
|
||||||
|
name: "Energy Statistics"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🎛️ Lovelace UI Customization
|
||||||
|
|
||||||
|
### Energy Summary Card
|
||||||
|
```yaml
|
||||||
|
type: energy-summary
|
||||||
|
consumption:
|
||||||
|
- sensor.esp32_energy_meter_energy_2
|
||||||
|
grid_return:
|
||||||
|
- sensor.grid_energy
|
||||||
|
solar:
|
||||||
|
- sensor.solar_energy
|
||||||
|
title: Energy Summary
|
||||||
|
```
|
||||||
|
|
||||||
|
### Power Flow Card
|
||||||
|
```yaml
|
||||||
|
type: energy-distribution
|
||||||
|
title: Power Flow
|
||||||
|
link_entity: sensor.esp32_energy_meter_power_2
|
||||||
|
link_type: consumption
|
||||||
|
source_type: grid
|
||||||
|
chart_type: pie
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 Troubleshooting Integration
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
#### Entities Not Appearing
|
||||||
|
- **Check API key**: Ensure correct API key in Home Assistant
|
||||||
|
- **Verify network**: Confirm ESP32 and HA are on same network
|
||||||
|
- **Restart integration**: Try removing and re-adding ESP32 integration
|
||||||
|
|
||||||
|
#### Missing Energy Data
|
||||||
|
- **Check state class**: Ensure energy sensors have `state_class: total`
|
||||||
|
- **Verify device class**: Use `device_class: energy` for energy measurements
|
||||||
|
- **Check recorder**: Ensure statistics are being recorded
|
||||||
|
|
||||||
|
#### Dashboard Not Loading
|
||||||
|
- **Enable statistics**: Statistics must be enabled for energy dashboard
|
||||||
|
- **Check configuration**: Verify energy sources are properly configured
|
||||||
|
- **Restart Home Assistant**: Sometimes needed after major changes
|
||||||
|
|
||||||
|
### Debug Commands
|
||||||
|
```bash
|
||||||
|
# Check ESPHome device status
|
||||||
|
esphome logs esp32-energy-meter.yaml --device 192.168.1.100
|
||||||
|
|
||||||
|
# Monitor ESP32 serial output
|
||||||
|
esphome logs esp32-energy-meter.yaml --serial /dev/ttyUSB0
|
||||||
|
|
||||||
|
# Check Home Assistant logs
|
||||||
|
tail -f /config/home-assistant.log
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📚 Additional Resources
|
||||||
|
|
||||||
|
- [Home Assistant Energy Documentation](https://www.home-assistant.io/docs/energy/)
|
||||||
|
- [ESPHome Documentation](https://esphome.io/)
|
||||||
|
- [JSY Energy Meter Manual](link-to-manual)
|
||||||
|
|
||||||
|
For advanced features and troubleshooting, see [Advanced Features](../wiki/Advanced-Features.md) and [Troubleshooting](../docs/troubleshooting.md).
|
||||||
Reference in New Issue
Block a user