|
substitutions: |
|
device_name: esp-tesla |
|
friendly_name: ESPHome Tesla |
|
mqtt_broker: your.mqtt.server # CHANGE! |
|
tx_pin: GPIO1 # connect to RX on modbus bridge # CHANGE! |
|
rx_pin: GPIO3 # connect to TX on modbus bridge # CHANGE! |
|
mqtt_value_id: meter_reading |
|
min_value: 0.0 |
|
max_value: 35.0 # adjust to a value above configured max-value in Wall Connector config |
|
grid_voltage: 230 # used for power calculation |
|
# serial <-> modbus bridge config |
|
baud_rate: 115200 |
|
data_bits: 8 |
|
parity: NONE |
|
stop_bits: 1 |
|
|
|
esp8266: # CHANGE! |
|
board: esp01_1m |
|
|
|
logger: |
|
level: INFO # Don't use DEBUG in production |
|
baud_rate: 0 #disable serial in order to use serial ports for modbus |
|
logs: |
|
# Reduce verbosity for components that might log sensitive data |
|
wifi: WARN |
|
api: WARN |
|
|
|
esphome: |
|
name: ${device_name} |
|
friendly_name: ${friendly_name} |
|
min_version: 2025.9.0 |
|
name_add_mac_suffix: false |
|
|
|
wifi: |
|
networks: |
|
- ssid: !secret wifi_ssid |
|
password: !secret wifi_password |
|
- ssid: !secret wifi2_ssid |
|
password: !secret wifi2_password |
|
|
|
min_auth_mode: WPA2 |
|
|
|
ota: |
|
- platform: esphome |
|
password: !secret eh_tesla_ota_password |
|
|
|
globals: |
|
- id: ct1_power_w |
|
type: float |
|
initial_value: "0.0" |
|
- id: ct2_power_w |
|
type: float |
|
initial_value: "0.0" |
|
- id: ct3_power_w |
|
type: float |
|
initial_value: "0.0" |
|
- id: ct4_power_w |
|
type: float |
|
initial_value: "0.0" |
|
- id: ct_total_w |
|
type: float |
|
initial_value: "0.0" |
|
|
|
- id: ct1_current_a |
|
type: float |
|
initial_value: "0.0" |
|
- id: ct2_current_a |
|
type: float |
|
initial_value: "0.0" |
|
- id: ct3_current_a |
|
type: float |
|
initial_value: "0.0" |
|
- id: ct4_current_a |
|
type: float |
|
initial_value: "0.0" |
|
- id: ct_total_a |
|
type: float |
|
initial_value: "0.0" |
|
|
|
# Power config value |
|
number: |
|
- platform: template |
|
id: meter_reading |
|
name: "Meter Reading" |
|
icon: "mdi:meter-electric" |
|
disabled_by_default: false |
|
unit_of_measurement: "A" |
|
min_value: ${min_value} |
|
max_value: ${max_value} |
|
step: 0.01 |
|
initial_value: ${max_value} # cannot be used with lambda |
|
optimistic: true # update when set |
|
on_value: |
|
then: |
|
lambda: |- |
|
// set ct1_current to meter reading |
|
id(ct1_current_a) = id(${mqtt_value_id}).state; |
|
// set all other ct_currents to same. Ignore ct4 (it was initialized with 0.0). |
|
id(ct2_current_a) = id(ct3_current_a) = id(ct1_current_a); |
|
id(ct_total_a) = id(ct1_current_a) + id(ct2_current_a) + id(ct3_current_a) + id(ct4_current_a); |
|
id(ct1_power_w) = ${grid_voltage} * id(ct1_current_a); // assume 230 volts |
|
id(ct2_power_w) = id(ct3_power_w) = id(ct1_power_w); // all amps and watts are equal, ignore ct4 |
|
id(ct_total_w) = id(ct1_power_w) + id(ct2_power_w) + id(ct3_power_w) + id(ct4_power_w); |
|
|
|
mqtt: |
|
broker: ${mqtt_broker} |
|
username: !secret mqtt_user |
|
password: !secret mqtt_pw |
|
birth_message: |
|
topic: ${device_name}/availability |
|
payload: online |
|
will_message: |
|
topic: ${device_name}/availability |
|
payload: offline |
|
reboot_timeout: 0s |
|
|
|
uart: |
|
- id: wallconn_uart |
|
tx_pin: ${tx_pin} |
|
rx_pin: ${rx_pin} |
|
baud_rate: ${baud_rate} |
|
data_bits: ${data_bits} |
|
parity: ${parity} |
|
stop_bits: ${stop_bits} |
|
|
|
modbus: |
|
- id: wallconn_modbus |
|
uart_id: wallconn_uart |
|
role: server |
|
|
|
modbus_controller: |
|
- id: wc_mb_server # modbus server (wall conector is client/requestor) |
|
modbus_id: wallconn_modbus |
|
address: 1 |
|
server_registers: |
|
# Serial number / MAC address |
|
- { address: 1, value_type: U_WORD, read_lambda: 'return 0x3078;' } |
|
- { address: 2, value_type: U_WORD, read_lambda: 'return 0x3030;' } |
|
- { address: 3, value_type: U_WORD, read_lambda: 'return 0x3030;' } |
|
- { address: 4, value_type: U_WORD, read_lambda: 'return 0x3034;' } |
|
- { address: 5, value_type: U_WORD, read_lambda: 'return 0x3731;' } |
|
- { address: 6, value_type: U_WORD, read_lambda: 'return 0x3442;' } |
|
- { address: 7, value_type: U_WORD, read_lambda: 'return 0x3035;' } |
|
- { address: 8, value_type: U_WORD, read_lambda: 'return 0x3638;' } |
|
- { address: 9, value_type: U_WORD, read_lambda: 'return 0x3631;' } |
|
- { address: 10, value_type: U_WORD, read_lambda: 'return 0x0000;' } |
|
|
|
# "1.6.1‑Tesla" |
|
- { address: 11, value_type: U_WORD, read_lambda: 'return 0x312E;' } |
|
- { address: 12, value_type: U_WORD, read_lambda: 'return 0x362E;' } |
|
- { address: 13, value_type: U_WORD, read_lambda: 'return 0x312D;' } |
|
- { address: 14, value_type: U_WORD, read_lambda: 'return 0x5465;' } |
|
- { address: 15, value_type: U_WORD, read_lambda: 'return 0x736C;' } |
|
- { address: 16, value_type: U_WORD, read_lambda: 'return 0x6100;' } |
|
|
|
# Four reserved words (all 0xFFFF) |
|
- { address: 17, value_type: U_WORD, read_lambda: 'return 0xFFFF;' } |
|
- { address: 18, value_type: U_WORD, read_lambda: 'return 0xFFFF;' } |
|
- { address: 19, value_type: U_WORD, read_lambda: 'return 0xFFFF;' } |
|
- { address: 20, value_type: U_WORD, read_lambda: 'return 0xFFFF;' } |
|
|
|
# "012.00020A.H" |
|
- { address: 21, value_type: U_WORD, read_lambda: 'return 0x3031;' } |
|
- { address: 22, value_type: U_WORD, read_lambda: 'return 0x322E;' } |
|
- { address: 23, value_type: U_WORD, read_lambda: 'return 0x3030;' } |
|
- { address: 24, value_type: U_WORD, read_lambda: 'return 0x3032;' } |
|
- { address: 25, value_type: U_WORD, read_lambda: 'return 0x3041;' } |
|
- { address: 26, value_type: U_WORD, read_lambda: 'return 0x2E48;' } |
|
- { address: 27, value_type: U_WORD, read_lambda: 'return 0x0000;' } |
|
|
|
# Reserved |
|
- { address: 28, value_type: U_WORD, read_lambda: 'return 0xFFFF;' } |
|
|
|
# Meter number "90954" |
|
- { address: 29, value_type: U_WORD, read_lambda: 'return 0x3930;' } |
|
- { address: 30, value_type: U_WORD, read_lambda: 'return 0x3935;' } |
|
- { address: 31, value_type: U_WORD, read_lambda: 'return 0x3400;' } |
|
|
|
# Model? "VAH4810AB0231" |
|
- { address: 32, value_type: U_WORD, read_lambda: 'return 0x5641;' } |
|
- { address: 33, value_type: U_WORD, read_lambda: 'return 0x4834;' } |
|
- { address: 34, value_type: U_WORD, read_lambda: 'return 0x3831;' } |
|
- { address: 35, value_type: U_WORD, read_lambda: 'return 0x3041;' } |
|
- { address: 36, value_type: U_WORD, read_lambda: 'return 0x4230;' } |
|
- { address: 37, value_type: U_WORD, read_lambda: 'return 0x3233;' } |
|
- { address: 38, value_type: U_WORD, read_lambda: 'return 0x3100;' } |
|
|
|
# eight more reserved (0xFFFF) |
|
- { address: 39, value_type: U_WORD, read_lambda: 'return 0xFFFF;' } |
|
- { address: 40, value_type: U_WORD, read_lambda: 'return 0xFFFF;' } |
|
- { address: 41, value_type: U_WORD, read_lambda: 'return 0xFFFF;' } |
|
- { address: 42, value_type: U_WORD, read_lambda: 'return 0xFFFF;' } |
|
- { address: 43, value_type: U_WORD, read_lambda: 'return 0xFFFF;' } |
|
- { address: 44, value_type: U_WORD, read_lambda: 'return 0xFFFF;' } |
|
- { address: 45, value_type: U_WORD, read_lambda: 'return 0xFFFF;' } |
|
- { address: 46, value_type: U_WORD, read_lambda: 'return 0xFFFF;' } |
|
|
|
# Mac "04:71:4B:05:68:61" |
|
- { address: 47, value_type: U_WORD, read_lambda: 'return 0x3034;' } |
|
- { address: 48, value_type: U_WORD, read_lambda: 'return 0x3A37;' } |
|
- { address: 49, value_type: U_WORD, read_lambda: 'return 0x313A;' } |
|
- { address: 50, value_type: U_WORD, read_lambda: 'return 0x3442;' } |
|
- { address: 51, value_type: U_WORD, read_lambda: 'return 0x3A30;' } |
|
- { address: 52, value_type: U_WORD, read_lambda: 'return 0x353A;' } |
|
- { address: 53, value_type: U_WORD, read_lambda: 'return 0x3638;' } |
|
- { address: 54, value_type: U_WORD, read_lambda: 'return 0x3A36;' } |
|
- { address: 55, value_type: U_WORD, read_lambda: 'return 0x3100;' } |
|
|
|
# CT1 power W |
|
- { address: 0x88, value_type: FP32, read_lambda: 'return id(ct1_power_w);' } |
|
|
|
# CT2 power W |
|
- { address: 0x8A, value_type: FP32, read_lambda: 'return id(ct2_power_w);' } |
|
|
|
# CT3 power W |
|
- { address: 0x8C, value_type: FP32, read_lambda: 'return id(ct3_power_w);' } |
|
|
|
# CT4 power W |
|
- { address: 0x8E, value_type: FP32, read_lambda: 'return id(ct4_power_w);' } |
|
|
|
# Aggregate watts |
|
- { address: 0x90, value_type: FP32, read_lambda: 'return id(ct_total_w);' } |
|
|
|
# Reserved |
|
- { address: 0x92, value_type: U_WORD, read_lambda: 'return 0;' } |
|
|
|
# CT1 current amps |
|
- { address: 0xF4, value_type: FP32, read_lambda: 'return id(ct1_current_a);' } |
|
|
|
# CT2 current amps |
|
- { address: 0xF6, value_type: FP32, read_lambda: 'return id(ct2_current_a);' } |
|
|
|
# CT3 current amps |
|
- { address: 0xF8, value_type: FP32, read_lambda: 'return id(ct3_current_a);' } |
|
|
|
# CT4 current amps |
|
- { address: 0xFA, value_type: FP32, read_lambda: 'return id(ct4_current_a);' } |
|
|
|
# Total amps |
|
- { address: 0xFC, value_type: FP32, read_lambda: 'return id(ct_total_a);' } |
|
|
|
# Initialization handshake |
|
- { address: 40002, value_type: U_WORD, read_lambda: 'return 0x0001;' } |
|
- { address: 40003, value_type: U_WORD, read_lambda: 'return 0x0042;' } |
|
- { address: 40004, value_type: U_WORD, read_lambda: 'return 0x4765;' } |
|
- { address: 40005, value_type: U_WORD, read_lambda: 'return 0x6E65;' } |
|
- { address: 40006, value_type: U_WORD, read_lambda: 'return 0x7261;' } |
|
- { address: 40007, value_type: U_WORD, read_lambda: 'return 0x6300;' } |