# Shelly EM Gen3 # Model number: S3EM-002CXCEU50 # PCB markings: "EM Gen3_v0.1.3", "B2519" # SoC: ESP-Shelly-C38F (similar to ESP32-C3) # CPU: ESP32-C3 (QFN32) (revision v0.4) # Features: Wi-Fi, BT 5 (LE), Single Core, 160MHz, Embedded Flash 8MB (GD) # Crystal frequency: 40MHz # References: # - https://devices.esphome.io/devices/shelly-em-gen3/ # - https://community.home-assistant.io/t/shelly-em-gen3-solved/944171 # - https://kb.shelly.cloud/knowledge-base/shelly-em-gen3 # # GPIOs: # GPIO0 - Dry-contact relay (normally open) # GPIO1 - Pushbutton # GPIO3 - ADC for NTC temperature sensor # GPIO4 - ADE7953 IRQ pin (active low) # GPIO5 - ADE7953 RESET pin (active low) # GPIO6 - I2C SCL # GPIO7 - I2C SDA # GPIO9 - Status LED (active low) # GPIO18 - Pin 1 of 7-pin header # GPIO20 - UART receive (U0RXD) # GPIO21 - UART transmit (U0TXD) # # I2C devices: # 0x38 - ADE7953 Power Sensor # 0x51 - AiP8563 Battery-backed real-time clock (not currently supported by ESPHome) # Outputting LOW on GPIO5 seems to produce HIGH on GPIO4, and vice versa substitutions: # Set dual_sensors to false to remove the "B" and "Total" sensors dual_sensors: true # How often to update the power meter. update_interval: 20s # Calibrated on US-style 120V power with 50A current transformers. # You may need to calibrate this yourself if the numbers are inaccurate. calibration_voltage_gain: 0x32c78f # Calibrated on device E4:B0:63:D4:3E:00 calibration_current_gain_a: 0x490bb5 # Calibrated on device E4:B0:63:D4:3E:00 calibration_current_gain_b: 0x498c15 # Calibrated on device E4:B0:63:D4:3E:00 # GPIOs for this type of device shelly_button_gpio_number: GPIO1 shelly_header_gpio_number: GPIO18 shelly_ntc_temperature_pin: GPIO3 dashboard_import: package_import_url: github://dlitz/esphome-configs-dlitz/shelly-em-gen3.yaml@${git_branch} packages: - !include common/esp-shelly-c38f.yaml - !include common/cpu-temperature.yaml - !include common/factory-reset.yaml - !include common/flash-write-interval.yaml - !include common/git-branch.yaml - !include common/ota.yaml - !include common/ota-update-password.yaml - !include common/restart.yaml - !include common/safe-mode.yaml - !include common/shelly-button.yaml - !include common/shelly-header-gpio.yaml - !include common/shelly-ntc-temperature.yaml - !include common/time.yaml - !include common/uptime-info.yaml - !include common/wifi-info.yaml esphome: name: "shelly-em-gen3" friendly_name: "Shelly EM Gen3" comment: "Shelly EM Gen3 - Smart wifi and bluetooth energy meter with dual current transformers" name_add_mac_suffix: true project: name: "dlitz.shelly-em-gen3" version: "v0.0.0" min_version: 2025.11.3 # for ade7953 bugfix #12180 # Enable logging logger: level: DEBUG hardware_uart: uart0 # debug: # Enable Home Assistant API with dynamic key api: encryption: wifi: # ssid: !secret wifi_ssid # password: !secret wifi_password # fast_connect: true enable_btm: true enable_rrm: true min_auth_mode: WPA2 # Enable fallback hotspot (captive portal) in case wifi connection fails ap: password: !secret default_ap_password captive_portal: network: enable_ipv6: true i2c: scl: GPIO6 sda: GPIO7 scan: true improv_serial: esp32_improv: authorizer: shelly_button_id esp32_ble_tracker: scan_parameters: active: false bluetooth_proxy: active: false light: - platform: status_led name: "Status LED" id: status_led_id disabled_by_default: true entity_category: diagnostic pin: number: GPIO9 inverted: true ignore_strapping_warning: true switch: # Dry-contact relay - normally open - platform: gpio name: Relay id: relay pin: GPIO0 sensor: # Note that on the Shelly EM Gen3, channels "A" and "B" are swapped between the chipset and the labels on the device. # The nIRQ pin of the ade7953 device seems to be connected to pin 9 (GPIO4) # of the ESP-Shelly-C38F. - platform: ade7953_i2c id: ade7953_id irq_pin: GPIO4 update_interval: ${update_interval} use_accumulated_energy_registers: true voltage_gain: ${calibration_voltage_gain} current_gain_a: ${calibration_current_gain_a} current_gain_b: ${calibration_current_gain_b} voltage: id: line_voltage name: Voltage frequency: id: line_frequency name: Frequency current_b: id: current_a name: ${ "Current A" if dual_sensors else "Current" } accuracy_decimals: 3 current_a: id: current_b name: Current B accuracy_decimals: 3 power_factor_b: id: power_factor_a name: ${ "Power Factor A" if dual_sensors else "Power Factor" } filters: - multiply: -1 power_factor_a: id: power_factor_b name: "Power Factor B" filters: - multiply: -1 apparent_power_b: id: apparent_power_a name: ${ "Apparent Power A" if dual_sensors else "Apparent Power" } apparent_power_a: id: apparent_power_b name: "Apparent Power B" active_power_b: id: active_power_a name: ${ "Power A" if dual_sensors else "Power" } active_power_a: id: active_power_b name: "Power B" reactive_power_b: id: reactive_power_a name: ${ "Reactive Power A" if dual_sensors else "Reactive Power" } filters: - multiply: -1 reactive_power_a: id: reactive_power_b name: "Reactive Power B" filters: - multiply: -1 - platform: integration id: energy_a name: ${ "Energy A" if dual_sensors else "Energy" } sensor: active_power_a restore: false time_unit: h icon: mdi:meter-electric unit_of_measurement: "kWh" state_class: total_increasing device_class: energy accuracy_decimals: 3 filters: - multiply: 0.001 - platform: integration id: energy_b name: 'Energy B' sensor: active_power_b restore: false time_unit: h icon: mdi:meter-electric unit_of_measurement: "kWh" state_class: total_increasing device_class: energy accuracy_decimals: 3 filters: - multiply: 0.001 - platform: total_daily_energy id: daily_energy_consumed_a name: ${ "Daily Energy Consumed A" if dual_sensors else "Daily Energy Consumed" } power_id: active_power_a icon: "mdi:hours-24" unit_of_measurement: "kWh" state_class: total_increasing device_class: energy accuracy_decimals: 3 filters: - multiply: 0.001 - platform: total_daily_energy id: daily_energy_consumed_b name: "Daily Energy Consumed B" power_id: active_power_b icon: "mdi:hours-24" unit_of_measurement: "kWh" state_class: total_increasing device_class: energy accuracy_decimals: 3 filters: - multiply: 0.001 - platform: combination id: power_ab type: sum name: "Power Total" sources: - source: active_power_a - source: active_power_b device_class: power state_class: measurement - platform: combination id: energy_ab type: sum name: "Energy Total" sources: - source: energy_a - source: energy_b state_class: total_increasing accuracy_decimals: 3 - platform: combination id: daily_energy_consumed_ab type: sum name: "Daily Energy Consumed Total" sources: - source: daily_energy_consumed_a - source: daily_energy_consumed_b state_class: total_increasing accuracy_decimals: 3 - id: !remove ${ "active_power_b" if not dual_sensors else "" } - id: !remove ${ "apparent_power_b" if not dual_sensors else "" } - id: !remove ${ "current_b" if not dual_sensors else "" } - id: !remove ${ "daily_energy_consumed_b" if not dual_sensors else "" } - id: !remove ${ "daily_energy_consumed_ab" if not dual_sensors else "" } - id: !remove ${ "energy_ab" if not dual_sensors else "" } - id: !remove ${ "energy_b" if not dual_sensors else "" } - id: !remove ${ "power_ab" if not dual_sensors else "" } - id: !remove ${ "power_factor_b" if not dual_sensors else "" } - id: !remove ${ "reactive_power_b" if not dual_sensors else "" }