Shelly EM Gen4¶
Gen4 / ESP32-C6.
| Fact | Value |
|---|---|
| Profile | EMG4 |
| Flash | 16 MB |
| Official package | 2.1.0 |
| Partition table | 0x10000 |
| App slot size | 0x300000 |
Before you start¶
Check first:
- the device runs Shelly's own firmware, not ESPHome yet
- you know its IP address (
--ip), or this PC is on the device's own access point (default192.168.33.1) - the device can reach this PC: same network, port 8000 (
--port) not blocked - your ESPHome config uses the partition table below and is compiled
- a UART adapter is at hand as your way back (Recovery over UART)
ESPHome config¶
Important
build refuses a config without Shelly's partition table. Copy partitions/EMG4-stock.csv from this repository next to your
YAML and keep CONFIG_PARTITION_TABLE_OFFSET: "0x10000".
esp32:
variant: ESP32C6
board: esp32-c6-devkitc-1
flash_size: 16MB
partitions: EMG4-stock.csv # copy from partitions/ in this repository
framework:
type: esp-idf
sdkconfig_options:
CONFIG_PARTITION_TABLE_OFFSET: "0x10000"
advanced:
enable_ota_rollback: false
ota:
- platform: esphome
allow_partition_access: true
The C6 needs the 80 MHz flash header, otherwise build refuses to replace the bootloader. If it complains, add under esphome::
esphome:
platformio_options:
board_build.flash_mode: dio
board_build.f_flash: 80000000L
board_build.flash_size: 16MB
Flash it¶
- Install the requirements (once):
pip install -r requirements.txt
- Fetch the official package:
python ota.py fetch EMG4 --insecure
- Build: put your app into it; the ZIP goes to
out/:
python ota.py build EMG4 app.ota.bin --esphome-factory app.factory.bin --esphome-yaml app.yaml
- Check the device first. Nothing is sent:
python ota.py send EMG4 out/EMG4-app-<date>.zip --ip <device IP> --dry-run
- Flash it and watch the log:
python ota.py send EMG4 out/EMG4-app-<date>.zip --ip <device IP> --watch 120
app.ota.bin and app.factory.bin are the two files ESPHome compiles. --dry-run only checks the device and, for this
package, reads the update target slot. Command reference: Commands.
What to expect¶
In the --watch log look for these lines, in this order:
| # | Log line | Meaning |
|---|---|---|
| 1 | Update target slot: 0 ... |
The slot check of send. Anything else: run python ota.py restore EMG4 first |
| 2 | Boot: cur ... min ... update? 1 |
The installer will write ESPHome's bootloader. update? 0 means it will not: build again with a higher --boot-min-version (why) |
| 3 | ota_progress up to 95 %, then ota_success |
The device restarts into ESPHome |
Notes for this device¶
No device-specific findings yet. Please report the --watch log, especially the lines Update target slot, Boot: cur ... update? and Will write to slot.
The profile sets boot_min_version: "1.0.9": devices of this family run Shelly's loader 1.0.3, which would otherwise skip ESPHome's bootloader (update? 0).
This device has a 16 MB flash layout (an extra data area), so flash_size is 16MB and a dev board for the DevKit image needs 16 MB.
Way back¶
python ota.py restore EMG4 sends the official firmware back while Shelly firmware still runs.
Warning
- Wipes Wi-Fi and settings. ESPHome opens its own access point or joins the Wi-Fi from your config; if nothing comes up, power-cycle the device (help).
- No way back over the network once ESPHome's bootloader runs:
restoregets no answer, only UART brings Shelly OS back (Recovery over UART). Take a flash backup first if you can. - Flashed it? Tell us, also when it worked: open a device report.