Shelly PM Mini Gen3¶
The first device that was flashed and reported by someone else: thanks to imsandli for the device report (October 2026) and the notes on this page. This device only measures: there is no relay in it. Do not confuse it with the Mini 1PM Gen3, which has one and is a different application in Shelly's update API (Mini1PMG3).
| Fact | Value |
|---|---|
| Profile | MiniPMG3 |
| Model | S3PM-001PCEU16 (device id shellypmminig3-...) |
| Flash | 8 MB |
| Official package | 2.1.0 (the reported flash started from stock 2.0.1, see the notes) |
| Partition table | 0xf000 (not 0x10000) |
| App slot size | 0x280000 |
Bootloader min_version |
1.0.9 (set in the profile) |
| ESPHome device page | Shelly PM Mini Gen3 |
Note
Confirmed: the whole chain ran on a real device: send from stock 2.0.1 with --esphome-factory; ESPHome boots, six and more ESPHome OTAs took effect, BLE, Wi-Fi and the power meter work.
Before you start¶
Check first:
- the device runs Shelly's own firmware, not ESPHome yet, and it is 1.3.3 or newer (better 2.x):
sendrefuses older ones (why) - 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)
Also:
- The device is a PM Mini Gen3 (
MiniPMG3, S3PM-001PCEU16), not the Mini 1PM Gen3 (that one has a relay).
ESPHome config¶
Important
build refuses a config without Shelly's partition table. Copy partitions/MiniPMG3-stock.csv from this repository next to your
YAML and keep CONFIG_PARTITION_TABLE_OFFSET: "0xf000".
esp32:
variant: ESP32C3
board: esp32-c3-devkitm-1
flash_size: 8MB
flash_mode: dio
partitions: MiniPMG3-stock.csv # copy from partitions/ in this repository
framework:
type: esp-idf
sdkconfig_options:
CONFIG_PARTITION_TABLE_OFFSET: "0xf000"
advanced:
enable_ota_rollback: false
ota:
- platform: esphome
allow_partition_access: true
The esp32: block is the tester's working one (the report did not include the ota: block, this is the usual one). Like the H&T Gen3, the device keeps its partition table at 0xf000, so a default ESPHome build does not match and build refuses it.
Tip
The ESPHome device page has the pins and an example config. Replace its esp32: block with the one above, or build refuses it.
Tip
Keep a way into the device after the flash. The update wipes NVS, so the old Wi-Fi is gone. Put your Wi-Fi in wifi: and, at least for the first flash, a fallback access point (ap:): if the network or a fixed IP is wrong, the device otherwise stays silent and only UART or USB helps, and there is no log to tell why. A fixed IP and no ap: are fine once the device is known to work. Not needed for the update itself. See the guide.
Pins¶
From the running ESPHome config of the report:
| Function | Pin |
|---|---|
| BL0942 power meter (UART, 9600 baud, 8N1) | ESP TX GPIO6, ESP RX GPIO7 |
| Relay | none |
uart:
tx_pin: GPIO6
rx_pin:
number: GPIO7
mode:
input: true
pullup: true
baud_rate: 9600
stop_bits: 1
- The RX pin needs the internal pull-up. Without it every 23-byte reply of the BL0942 arrives with stray bytes around it (
00before the55header,00:FE:00:FEafter the checksum), so every checksum fails and all values staynan. With the pull-up the packets are clean. - Voltage calibration: with ESPHome's default
voltage_reference(15883) the voltage reads about 10 % low.voltage_reference: 14357was correct against the electricity meter on this one unit; the stock firmware read about 2 % low. Compare with a reference on your unit. - Button and LED pins were not read.
Flash it¶
- Install the requirements (once):
pip install -r requirements.txt
- Fetch the official package:
python ota.py fetch MiniPMG3 --insecure
- Build: put your app into it; the ZIP goes to
out/:
python ota.py build MiniPMG3 app.ota.bin --esphome-factory app.factory.bin --esphome-yaml app.yaml
- Check the device first. Nothing is sent:
python ota.py send MiniPMG3 out/MiniPMG3-app-<date>.zip --ip <device IP> --dry-run
- Flash it (the log goes to a file with
--log-file):
python ota.py send MiniPMG3 out/MiniPMG3-app-<date>.zip --ip <device IP> --log-file
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¶
send shows these lines at the default log level, in this order:
| # | Log line | Meaning |
|---|---|---|
| 1 | Update target slot: 0 ... |
The slot check of send. Anything else: run python ota.py restore MiniPMG3 first |
| 2 | Device: The bootloader will be replaced ... (raw log: Boot: cur ... min ... update? 1) |
The installer will write ESPHome's bootloader. WARNING: ESPHome's bootloader was NOT written (update? 0) means it will not: build again with a higher --boot-min-version (why) |
| 3 | The progress (Update: ... %, one line that updates in place) up to 100 %, then Done: update installed, the device confirmed it |
The device restarts into ESPHome |
The reported run, from stock 2.0.1 (the first line comes from send, the rest from the device):
Update target slot: 0 (the slot ESPHome's bootloader starts).
log| shelly_update.cpp:511 Incoming fw signatures: 00
log| 2xx_ota_backend.cpp:409 Will write to slot 0
log| 2xx_ota_backend.cpp:689 Boot: cur 010002ff, new 00000000, min 010009ff, update? 1
log| 2xx_ota_backend.cpp:171 Installing BL 20960@app_0(0x20000) -> boot(0)...
log| shelly_update.cpp:631 EFUSE write error bit[1]: 5636
log| shos_system.c:66 Rebooting in 1000 ms
The EFUSE write error line also appeared on the H&T Gen3; the update still succeeded (eFuse note).
Notes for this device¶
- Old stock firmware (1.1.x to 1.3.2):
sendrefuses the package. One unit on stock 1.1.99 (loader00040405) accepted the ESPHome package without an error and then stayed silent, also after a power cycle, until it was flashed over UART/USB (#113, thanks to aanban). Its log lacks the linesBS is being moved,PT is being movedandInstalling BL, which the updater of 1.3.3 prints on a dev board; so the old updater most likely changes neither the layout nor the bootloader. This is inferred from the log: the 1.1.99 package is not available (Shelly's update API names 1.3.3 as the next step for it). Update such a device with Shelly's own update first (the web interface or app), then send. - Stock 1.3.3 on a dev board: the updater moves the partition table (
0x8000to0xf000) and boot state (0x10000to0x11000) and replaces the bootloader, but it does not name its update target slot beforehand, sosendcannot check it. In the test it wrote to slot 1 and the old firmware came back;restorefirst (see the Slot note below) is the way: on a dev board,restoreput 2.1.1 in slot 1 and replaced the bootloader (010000ffto010003ff), the nextsend --dry-runnamed slot 0, andsendthen worked (ESPHome's access point appeared). - The installed loader was 1.0.2, which is why the profile sets
boot_min_version: 1.0.9: a lower value would have been skipped by the installer. - Slot: the first
send --dry-runrefused because the installer would have written to slot 1.python ota.py restore MiniPMG3fixed that (the device then ran from slot 1, and the next dry run reported slot 0). The restore kept Wi-Fi and settings on this unit (2.0.1 to 2.0.1). - Network: the tester's Shelly sat in an IoT VLAN that could reach nothing on the PC's network, while the PC could reach the Shelly. The device's own RPC finds this before anything is sent:
http://<Shelly IP>/rpc/HTTP.GET?url="http://<PC IP>:8000/"answeredConnection error: -13. Any HTTP status in the answer (a 404 is fine) means the way is open. - Package versions: the profile and
MiniPMG3-stock.csvwere made from the 2.1.0 package; the flash on the tester's unit was done with the 2.0.1 table. The two tables were not compared. - Check the app name (
MiniPMG3) and the model (S3PM-001PCEU16) before you use this page. The Mini 1PM Gen3 (Mini1PMG3) has a relay, another partition layout (app slot0x2a0000) and was not tested.
Way back¶
python ota.py restore MiniPMG3 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.