Unable to upload images on Shelly PM mini gen3, Unexpected response from ESP: 0x04

I’ve got two new Shelly PM mini gen 3’s flashed to esphome, but running into issues flashing new “prod” images. The devices are not bricked.

I’ve followed these steps in a “temp” environment:

So, the “temp” environment is based on Read/Write bootloader, partition table and any partition via OTA by angelnu · Pull Request #5535 · esphome/esphome · GitHub

After this I’m using my regular “prod” esphome environment (latest version) to create and upload a new image.
However, this gives me this error:
ERROR Error auth: Unexpected response from ESP: 0x04

The log output on Shelly shows:

16:20:25	[W]	[ota:380]	Failed to read 1 bytes of data, errno: 104
16:20:25	[E]	[ota:282]	Reading command failed!
16:20:25	[W]	[ota:411]	Failed to write 1 bytes of data, errno: 104

Now… When I go to the “temp” environment and compile the bigger config (from prod), then it does upload successfully.

I’ve played around with clearing the OTA password, safe_boot and using OTA version 1 etc. Nothing allowed the prod image to be uploaded.

The only difference between “temp” and “prod” config is “unprotected_writes: True” under ota: as required for the initial flashing and the addition of " - platform: esphome" under ota as per thew new structure.

The weird thing is that my other Shelly PM mini gen3’s are working just fine. It’s just these 2 newer ones.

This ain’t a massive thing as I can make changes, but it would be nice to be able to upgrade esphome. Now they’re stuck on 2024.1.0-dev :slight_smile:

Hope anyone has some clues. Happy to provide any further details if required of course!

News flash, it works!

Turns out compiling and flashing using an esphome version <= 2024.5.1 did the trick!

docker run --rm -v "${PWD}":/config -it ghcr.io/esphome/esphome:2024.5.1 run config.yaml
Config.yaml I used does have “version: 1” under ota:

After this I am able to flash the latest and greatest. No idea why it didn’t work initially…
Just sharing in case anyone runs into this as well.

2 Likes

Hi @Marcel,
would you mind sharing your config.yaml?
I am at the same point you were, but whenever I try to build a new firmware image with the older esphome version and a newer prod config I end up with a rabbit hole of dependency issues and esphome errors.

I’m assuming you did the -v upload-factory-ota already, right? That’s key to ensure you can flash the Shelly going forward.

The key is that after -v upload-factory-ota there is an additional flash using version 2024.5.1. It really doesn’t need to be a full config.yaml so I guess you can even use the one you used as initial flash, just the basics (board, wifi) and a reboot button just in case.

I didn’t save my “intermediate” config, but I guess this should work:

substitutions:
  devicename: zolder-meter
  update_time: 10s

esphome:
  name: $devicename
  friendly_name: $devicename
  platformio_options:
    board_build.flash_mode: dio

esp32:
  board: esp32-c3-devkitm-1
  flash_size: 8MB
  framework:
    type: esp-idf
    sdkconfig_options:
      COMPILER_OPTIMIZATION_SIZE: y

logger:
  baud_rate: 0

api:

ota:
  password: "This is my PW, perhaps"
  version: 1

wifi:
  networks:
    - ssid: "My_SSID"
      password: "MY_PWD"
      priority: 0.0
    - ssid: "My_SSID"
      bssid: B4:FB:E4:xx:yy:zz
      password: "MY_PWD"
      priority: 10.0

web_server:
  port: 80

switch:
  - platform: restart
    name: "${devicename} Restart Button"

text_sensor:
  - platform: version
    name: ${devicename} ESPHome Version

Bonus tip, this WiFi conifg “forces” my Shelly PM Gen3 mini to the AP broadcasting my SSID closest to where I place the Shelly. Get the Mac address via the text sensor :wink:

I am getting an error, when uploading the factory-ota-test.yaml:

INFO Uploading .esphome/build/brunnenschalter/.pioenvs/brunnenschalter/firmware.bin (1504976 bytes)
DEBUG Partition info: [1, 4, 0, 22, 246, 208, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 97, 112, 112, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
ERROR Error binary size: Error: device aborted flash that would have overriden running partition. Check your device log for more information.
INFO Trying to restore the partition table backup ...
INFO Resolving IP address of brunnenschalter.local

the logs in the webui say:

19:38:55	[W]	[component:215]	

Components should block for at most 20-30ms.

19:38:56	[D]	[ota:148]	

Starting OTA Update from 192.168.64.36...

19:38:56	[D]	[esp32_ble_tracker:233]	

Stopping scan.

19:38:56	[I]	[ota:464]	

OTA type is 4 and size is 1504976 bytes

19:38:56	[E]	[ota:110]	

Aborting to avoid overriding running partition

19:38:56	[E]	[ota:111]	

New partition - addr: 0x010000; size: 0x170000

19:38:56	[E]	[ota:113]	

Running partition - addr: 0x0f0000; size: 0x530000

19:38:57	[I]	[ota:282]	

PARTITION TABLE

19:38:57	[I]	[ota:283]	

===============

19:38:57	[I]	[ota:287]	

type: 0x01; subtype: 0x00; addr: 0x009000; size: 0x002000; label: ota

19:38:57	[I]	[ota:287]	

type: 0x01; subtype: 0x01; addr: 0x00b000; size: 0x001000; label: phy_

19:38:57	[I]	[ota:287]	

type: 0x00; subtype: 0x10; addr: 0x010000; size: 0x1c0000; label: 

19:38:57	[I]	[ota:287]	

type: 0x00; subtype: 0x11; addr: 0x1d0000; size: 0x1c0000; label: 

19:38:57	[I]	[ota:287]	

type: 0x01; subtype: 0x02; addr: 0x390000; size: 0x06d000; label:

19:38:57	[W]	[component:214]	

Component ota took a long time for an operation (0.06 s).

19:38:57	[W]	[component:215]	

Components should block for at most 20-30ms.

19:38:57	[D]	[ota:148]	

Starting OTA Update from 192.168.64.36...

19:38:57	[D]	[esp32_ble_tracker:233]	

Stopping scan.

19:38:57	[I]	[ota:464]	

OTA type is 3 and size is 4096 bytes

19:38:57	[D]	[ota:519]	

OTA in progress: 0.1%

19:38:57	[I]	[ota:282]	

PARTITION TABLE

19:38:57	[I]	[ota:283]	

===============

19:38:57	[I]	[ota:287]	

type: 0x01; subtype: 0x00; addr: 0x010000; size: 0x002000; label: ota

19:38:57	[I]	[ota:287]	

So maybe something is already broken here?

That doesn’t look too good I’m afraid. It could be bricked already.
Did you include this in “factory-ota-test.yaml”:

ota:
  password: "OTAPASSWORD"
  unprotected_writes: True

The unprotected_writes is key.
Re-compile (with the dev version) your factory-ota-test.yaml with that option in there, and then re-attempt to upload with python -m esphome -v upload-factory-ota factory-ota-test.yaml.
This is the guide I used: Shelly Gen 3 OTA Conversion Keeping OTA Capabilities

If that one is succesful, it might work. If you forgot to use the ‘-v upload-factory-ota’ right after uploaded the initial firmware.bin to the Tasmota interface, then I think your out of luck (unless you manage to get the pins connected and flash via serial).

PS, this was my factory-ota-test.yaml:

esphome:
  name: zolder-meter
  platformio_options:
    board_build.flash_mode: dio
esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: esp-idf
    platform_version: 6.4.0
    version: 5.1.1
  variant: esp32c3
wifi:
  networks:
  - ssid: "My_SSID"
    password: "My_Password"
ota:
  password: "My OTA Password"
  unprotected_writes: True
logger:
  hardware_uart: USB_SERIAL_JTAG
web_server:
button:
- platform: restart
  name: Restart

Thank you for your honesty, I did have unprotected writes included:

substitutions:
  device_name: "brunnenschalter"
  friendly_name : "brunnenschalter"

esphome:
  name: ${device_name}
  friendly_name: ${friendly_name}
  platformio_options:
    board_build.flash_mode: dio

esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: esp-idf
    platform_version: 6.4.0
    version: 5.1.1
  variant: esp32c3

wifi:
  ssid: "mySSID"
  password: "SSIDPW"
  fast_connect: on

ota:
  unprotected_writes: True # This is mandatory if you want to flash the partition table or bootloader!

api:
  encryption:
    key: "myAPIkey"

logger:
  hardware_uart: USB_SERIAL_JTAG

time:
  - platform: homeassistant

captive_portal:

esp32_ble_tracker:

bluetooth_proxy:

web_server:

debug:
  update_interval: 5s

button:
- platform: restart
  name: Restart
...

I followed this guide: Flashing esphome on Shelly 1 mini gen3 – brunner.ninja and glanced at the one you mentioned, but didn’t follow up on it, because there was cd esphome-1 twice in it and that didn’t work.

The ota update command results in an error due to partition table issues, so maybe it is indeed softbricked right now. :frowning:

I will try to figure out if there is a way to override a running partition, not much to loose at this moment I guess.

Thank you very much for your help.

@daxy thank you very much for the help!

I just wanted to add for anyone else reading this and getting into the same situation:

angelnu’s extension to esphome actually also allows repartitioning over the air via the commands here: Read/Write bootloader, partition table and any partition via OTA by angelnu · Pull Request #5535 · esphome/esphome · GitHub and that is one of the upload-factory-ota steps.

So if you get stuck like me you can try to set up a new yaml in the same esphome-1 directory (i actually copied @daxy 's yaml 1:1 and only added static ip addresses so esphome would not use .local + wifi and ota credentials) and then rebuild a new image that you can now upload and thereby rewrite the partition table.

nano zolder-meter.yaml
python -m esphome compile zolder-meter.yaml 
python -m esphome -v upload-factory-ota zolder-meter.yaml 

After that I created a legacy binary based on Shelly 1PM Mini Gen3 | ESPHome Devices , did:

python -m esphome -v upload zolder-meter.yaml --file brunnensteuerung.ota.bin

and now it seems good, still testing though.

I’m really glad it works!!!
Now you’ve flashed the partition table and if you cannot upload your new and full config because of a “ESP: 0x04” message, then you can use the temp flash using version 2024.5.1 I mentioned before :grinning:. Have fun!

1 Like