Skip to content

shellypro3em_old fails to bind on UDP 1010 (PermissionError) on Raspberry Pi, while Shelly broadcasts from Venus battery are visible #367

@Gizzbert

Description

@Gizzbert

Hi, first of all: thanks for AstraMeter – really nice piece of work.

I’m running into a very specific issue with the Shelly Pro 3EM emulation (for a Marstek Venus E v3.0 battery) on a Raspberry Pi. The short version:

  • shellypro3em_new starts and listens on UDP 2220
  • shellypro3em_old fails to start with PermissionError: [Errno 13] Permission denied when binding the UDP socket (presumably on 1010)
  • At the same time, I can see the Venus continuously broadcasting UDP packets to 192.168.0.255:1010, so the device is sending discovery traffic
  • Because the “old” listener never comes up on 1010, the Venus will never find the emulated Shelly

Environment

  • Device: Raspberry Pi 4 (4 GB)
  • OS: Raspberry Pi OS DietPi v10.3.3 (64‑bit) (up to date)
  • Docker: version 29.4.3, build 055a478
  • Docker Compose: version v5.1.3
  • AstraMeter image: ghcr.io/tomquist/astrameter:latest
  • AstraMeter Git commit reported in log: cc8d94d

Network:

  • Raspberry Pi 4b on Wi‑Fi (wlan0)
  • Marstek Venus E v3.0 on same Wi‑Fi / same L2 LAN
  • Router: R7800 running OpenWrt 24.10.5, default LAN firewall (input/output/forward ACCEPT, intra‑zone ACCEPT)

docker-compose service

services:
  astrameter:
    image: ghcr.io/tomquist/astrameter:latest
    container_name: astrameter
    restart: unless-stopped
    network_mode: host
    environment:
      - TZ=Europe/Amsterdam
      - LOG_LEVEL=debug
    security_opt:
      - apparmor=unconfined
    # (no extra ports, host network)
    volumes:
      - ./config/config.ini:/app/config.ini

config.ini (relevant parts)

[GENERAL]
DEVICE_TYPE = shellypro3em
THROTTLE_INTERVAL = 2

[HOMEASSISTANT]
IP = 192.168.0.130
PORT = 8123
ACCESSTOKEN = <redacted>

POWER_CALCULATE = True
POWER_INPUT_ALIAS = sensor.electricity_meter_power_consumption
POWER_OUTPUT_ALIAS = sensor.electricity_meter_power_production
THROTTLE_INTERVAL = 2

No [SHELLY] input powermeter section is configured – the only powermeter is Home Assistant.

AstraMeter log
On startup I consistently get:

2026-05-16 19:11:07 INFO:astrameter:started astrameter application
2026-05-16 19:11:07 INFO:astrameter:Git commit: cc8d94d3320b1b4e90d2320f291bc93228228407
2026-05-16 19:11:07 INFO:astrameter:Device Types: ['shellypro3em_old', 'shellypro3em_new']
2026-05-16 19:11:07 INFO:astrameter:Device IDs: ['shellypro3em-ec4609c439c1', 'shellypro3em-ec4609c439c1']
2026-05-16 19:11:07 INFO:astrameter:Skip Test: False
2026-05-16 19:11:07 DEBUG:asyncio:Using selector: EpollSelector
2026-05-16 19:11:07 INFO:astrameter:Starting web server...
2026-05-16 19:11:07 INFO:astrameter:Web server started on 0.0.0.0:52500
2026-05-16 19:11:07 INFO:astrameter:Web server started successfully
2026-05-16 19:11:07 INFO:astrameter:Applying section-specific throttling (2.0s) to HOMEASSISTANT
2026-05-16 19:11:07 DEBUG:astrameter:Testing powermeter configuration... (attempt 1/4)
2026-05-16 19:11:07 INFO:astrameter:Home Assistant WebSocket connected to 192.168.0.130
2026-05-16 19:11:07 DEBUG:astrameter:Home Assistant: auth required, sending token
2026-05-16 19:11:07 INFO:astrameter:Home Assistant: authenticated
2026-05-16 19:11:07 DEBUG:astrameter:Home Assistant: update_entity_value: sensor.electricity_meter_power_consumption, 0.28
2026-05-16 19:11:07 DEBUG:astrameter:Home Assistant: update_entity_value: sensor.electricity_meter_power_production, 0.0
2026-05-16 19:11:07 DEBUG:astrameter:Throttling: Fetched fresh values: [0.28]
2026-05-16 19:11:07 INFO:astrameter:Successfully fetched ThrottledPowermeter powermeter value (filter 0.0.0.0/0): 0.28W

2026-05-16 19:11:07 DEBUG:astrameter:Starting device: shellypro3em_old
2026-05-16 19:11:07 DEBUG:astrameter:Shelly Pro 3EM Settings:
2026-05-16 19:11:07 DEBUG:astrameter:Device ID: shellypro3em-ec4609c439c1
2026-05-16 19:11:07 ERROR:astrameter:Device shellypro3em_old (shellypro3em-ec4609c439c1) failed to start
Traceback (most recent call last):
  File "/app/.venv/lib/python3.12/site-packages/astrameter/main.py", line 326, in run_device
    await device.start()
  File "/app/.venv/lib/python3.12/site-packages/astrameter/shelly/shelly.py", line 294, in start
    transport, protocol = await loop.create_datagram_endpoint(
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1433, in create_datagram_endpoint
    raise exceptions[0]
  File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1417, in create_datagram_endpoint
    sock.bind(local_address)
PermissionError: [Errno 13] Permission denied

2026-05-16 19:11:07 DEBUG:astrameter:Starting device: shellypro3em_new
2026-05-16 19:11:07 DEBUG:astrameter:Shelly Pro 3EM Settings:
2026-05-16 19:11:07 DEBUG:astrameter:Device ID: shellypro3em-ec4609c439c1
2026-05-16 19:11:07 INFO:astrameter:Shelly emulator listening on UDP port 2220...
So: shellypro3em_new is fine, shellypro3em_old cannot bind its UDP socket.

On the host:

bash
sudo ss -lunp | grep ':1010\|:2220'
UNCONN 0      0            0.0.0.0:2220      0.0.0.0:*    users:(("astrameter",pid=3114578,fd=8))

No other process is listening on 1010.

tcpdump from the Raspberry Pi
While the Venus is configured to use a Shelly Pro 3EM as meter, and during the pairing/connection attempts, I see this on the Pi:

bash
sudo tcpdump -ni any udp port 1010 or udp port 2220

Output (shortened):

19:53:42.120772 wlan0 B   IP 192.168.0.227.22222 > 192.168.0.255.1010: UDP, length 50
19:53:42.742624 wlan0 B   IP 192.168.0.227.22222 > 192.168.0.255.1010: UDP, length 50
19:53:43.358145 wlan0 B   IP 192.168.0.227.22222 > 192.168.0.255.1010: UDP, length 50
...
19:54:05.705293 wlan0 B   IP 192.168.0.227.22222 > 192.168.0.255.1010: UDP, length 50

So the Venus (192.168.0.227) is clearly broadcasting to 192.168.0.255:1010 on the same Wi‑Fi/L2 network.

What I expected
Given the README and the Shelly Pro 3EM emulation:

  • shellypro3em_old should be able to bind on the appropriate UDP port (presumably 1010) on the Raspberry Pi
  • It should then be able to receive these broadcasts from the Venus on 1010 and respond accordingly
  • shellypro3em_new listening on 2220 is fine, but for my Venus firmware it seems the 1010 listener is the one that matters

Question
Is there a known reason why the shellypro3em_old UDP bind would hit PermissionError on some hosts (here: Raspberry Pi + Docker + host network), even when:

  • no other process is bound to 1010
  • the container runs with network_mode: host
  • apparmor=unconfined and cap_add: [NET_ADMIN, NET_RAW] are set?

And more practically: could there be a bug or missing option in the way the “old” Shelly socket is created/bound that causes this on some Linux platforms?

Happy to run additional tests or builds and provide more logs if needed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions