dzikus99/shelly-speedwire-gateway

By dzikus99

Updated 8 months ago

Gateway for ShellyEM3 to SMA Speedwire protocol. Enables SMA inverters to read data from Shelly EM3.

Image
Networking
Message queues
Internet of things
0

1.5K

dzikus99/shelly-speedwire-gateway repository overview

Shelly EM3 to SMA Speedwire Gateway

GitHub Docker Pulls Docker Image Size

A Python-based gateway that enables Shelly EM3 three-phase energy meters to communicate with SMA inverters by emulating the SMA Energy Meter protocol via Speedwire.

Features

  • Real-time energy monitoring - Forwards power, voltage, current, and energy data from Shelly EM3 to SMA devices
  • Three-phase support - Full support for all three phases with individual measurements
  • SMA Speedwire protocol - Implementation of SMA EMETER protocol v1.0 with reactive/apparent power
  • CT clamp orientation support - Built-in invert_values option for backwards-mounted current transformers
  • Multiple deployment options - Run as standalone Python script, systemd service, or Docker container
  • Flexible networking - Supports multicast, broadcast, and direct unicast communication
  • Auto-discovery - Responds to SMA device discovery requests
  • Low latency - Configurable transmission intervals with immediate updates on data change

Requirements

Hardware
  • Shelly EM3 energy meter connected to your electrical installation
  • SMA inverter or device that supports Speedwire protocol
  • Network connectivity between Shelly EM3, MQTT broker, and SMA devices
Software
  • Python 3.7+ (for standalone installation)
  • Docker (for containerized deployment)
  • MQTT broker (e.g., Mosquitto)

Quick Start

version: '3.8'

services:
  shelly-speedwire-gateway:
    image: dzikus99/shelly-speedwire-gateway:latest
    container_name: shelly-speedwire
    restart: unless-stopped
    network_mode: host  # REQUIRED for multicast/broadcast
    environment:
      - MQTT_BROKER_HOST=192.168.1.123
      - MQTT_BASE_TOPIC=shellies/shellyem3-XXXXXXXXXXXXX
      - SPEEDWIRE_SERIAL=1234567890
      - MQTT_INVERT_VALUES=false  # Set to true if CT clamps are backwards
docker-compose up -d
Docker Run
docker run -d \
  --name shelly-speedwire \
  --network host \
  --restart unless-stopped \
  -e MQTT_BROKER_HOST=192.168.1.123 \
  -e MQTT_BASE_TOPIC=shellies/shellyem3-XXXXXXXXXXXXX \
  -e SPEEDWIRE_SERIAL=1234567890 \
  -e LOG_LEVEL=INFO \
  dzikus99/shelly-speedwire-gateway:latest

Installation

Option 1: Docker Container

Pull the image from Docker Hub:

docker pull dzikus99/shelly-speedwire-gateway:latest

Or build locally:

docker build -t shelly-speedwire-gateway .
Option 2: Systemd Service (Linux)
  1. Clone the repository:
git clone https://github.com/dzikus/shelly-speedwire-gateway
cd shelly-speedwire-gateway
  1. Install dependencies:
pip3 install -r requirements.txt
  1. Copy files to system location:
sudo mkdir -p /opt/shelly-speedwire-gateway
sudo cp shelly_speedwire_gateway.py /opt/shelly-speedwire-gateway/
sudo cp shelly_speedwire_gateway_config.yaml /opt/shelly-speedwire-gateway/
  1. Install systemd service:
sudo cp shelly-speedwire-gateway.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable shelly-speedwire-gateway
sudo systemctl start shelly-speedwire-gateway
  1. Check status:
sudo systemctl status shelly-speedwire-gateway
sudo journalctl -u shelly-speedwire-gateway -f
Option 3: Standalone Python
  1. Install dependencies:
pip3 install paho-mqtt pyyaml
  1. Configure the gateway (see Configuration section)

  2. Run the gateway:

python3 shelly_speedwire_gateway.py

Configuration

The gateway can be configured using either a YAML configuration file or environment variables (Docker only).

Configuration File

Create or edit shelly_speedwire_gateway_config.yaml:

mqtt:
  broker_host: 192.168.1.123          # Your MQTT broker IP
  broker_port: 1883
  base_topic: shellies/shellyem3-XXXXXXXXXXXXX  # Your Shelly EM3 topic
  keepalive: 60
  invert_values: false                # Set to true if CT clamps are mounted backwards
  # username: mqtt_user               # Optional MQTT auth
  # password: mqtt_pass

speedwire:
  interval: 1.0                       # Send interval in seconds
  use_broadcast: false                # Use broadcast instead of multicast
  dualcast: false                     # Send both multicast and broadcast
  push_on_update: true                # Send immediately on MQTT update
  min_send_interval: 0.2              # Minimum seconds between packets
  heartbeat_interval: 10.0            # Maximum seconds without sending
  serial: 1234567890                  # Unique serial number
  susy_id: 349                        # SUSy ID (349 = standard EMETER-20)
  include_voltage_current: true       # Include V, I, PF, Hz data
  include_sw_version: true            # Include software version

  # Optional: Direct unicast to specific devices
  # unicast_targets:
  #   - 192.168.1.50                  # SMA inverter IP
  #   - 192.168.1.51

logging:
  level: INFO                         # DEBUG, INFO, WARNING, ERROR
Environment Variables (Docker)

When using Docker, you can configure the gateway using environment variables instead of a configuration file.

MQTT Configuration
VariableDefaultDescriptionRequired
MQTT_BROKER_HOSTlocalhostMQTT broker IP address or hostnameNo
MQTT_BROKER_PORT1883MQTT broker portNo
MQTT_BASE_TOPICshellies/shellyem3-XXXXXXXXXXXXXYour Shelly EM3 MQTT topic. Format: shellies/shellyem3-[DEVICE_ID]Yes
MQTT_KEEPALIVE60MQTT connection keepalive interval in secondsNo
MQTT_INVERT_VALUESfalseSet to true if CT clamps are mounted backwards (reverses power sign and swaps total/total_returned)No
MQTT_USERNAME-MQTT broker username for authenticationNo
MQTT_PASSWORD-MQTT broker password for authenticationNo
Speedwire Configuration
VariableDefaultDescriptionRequired
SPEEDWIRE_INTERVAL1.0How often to send data packets in seconds. Lower values = more frequent updatesNo
SPEEDWIRE_USE_BROADCASTfalseUse UDP broadcast (255.255.255.255) instead of multicast. Enable if multicast doesn't work in your networkNo
SPEEDWIRE_DUALCASTfalseSend both multicast and broadcast packets. Useful for mixed network environmentsNo
SPEEDWIRE_PUSH_ON_UPDATEtrueSend packet immediately when new MQTT data arrives (reduces latency)No
SPEEDWIRE_MIN_SEND_INTERVAL0.2Minimum seconds between packets when push_on_update is enabledNo
SPEEDWIRE_HEARTBEAT_INTERVAL10.0Maximum seconds without sending a packet (ensures SMA device knows gateway is alive)No
SPEEDWIRE_SERIAL1234567890Unique serial number for the emulated energy meter. Change this to a unique value!Yes
SPEEDWIRE_SUSY_ID349SUSy ID for device identification. 349 (0x015D) = standard SMA EMETER-20No
SPEEDWIRE_INCLUDE_VOLTAGE_CURRENTtrueInclude voltage, current, power factor, and frequency in packetsNo
SPEEDWIRE_INCLUDE_SW_VERSIONtrueInclude emulated software version (2.3.4.R) in packetsNo
Logging Configuration
VariableDefaultDescriptionRequired
LOG_LEVELINFOLogging verbosity: DEBUG, INFO, WARNING, ERRORNo
Using Configuration File with Docker

To use a configuration file instead of environment variables:

version: '3.8'

services:
  shelly-speedwire-gateway:
    image: dzikus99/shelly-speedwire-gateway:latest
    container_name: shelly-speedwire
    restart: unless-stopped
    network_mode: host
    volumes:
      - ./shelly_speedwire_gateway_config.yaml:/app/shelly_speedwire_gateway_config.yaml:ro

Note: When mounting a config file, environment variables are ignored.

Network Configuration

Network Requirements
  • UDP Port 9522 - Must be open for Speedwire communication
  • Multicast - Address 239.12.255.254 (default mode)
  • Broadcast - Address 255.255.255.255 (alternative mode)
  • Network mode - Docker containers MUST use network_mode: host
Network Modes
  1. Multicast (Default)

    • Most efficient for multiple SMA devices
    • Requires multicast routing enabled
    • Uses address 239.12.255.254
  2. Broadcast

    • Works in all network configurations
    • Higher network load
    • Enable with SPEEDWIRE_USE_BROADCAST=true
  3. Dualcast

    • Sends both multicast and broadcast
    • Maximum compatibility
    • Enable with SPEEDWIRE_DUALCAST=true
  4. Unicast

    • Direct communication to specific devices
    • Configure via unicast_targets in config file
    • Most reliable for single device setups

CT Clamp Orientation

Important: Current Transformer (CT) Clamp Direction

The Shelly EM3 uses CT clamps to measure current flow. The direction these clamps are installed affects the power readings:

  • Correct installation: Power values indicate actual energy flow direction
  • Backwards installation: Power values are inverted (consumption shows as generation and vice versa)
Using invert_values Parameter

If your CT clamps are mounted backwards, set invert_values: true in your configuration:

mqtt:
  invert_values: true  # Fixes backwards CT clamp installation

Or with Docker:

-e MQTT_INVERT_VALUES=true

What invert_values does:

  • Reverses the sign of all power values (positive ↔ negative)
  • Swaps total and total_returned energy counters
  • Reverses power factor signs
  • Does NOT affect voltage, current, or frequency values

Data Mapping

The gateway translates Shelly EM3 MQTT data to SMA Speedwire protocol using OBIS codes with reactive power, apparent power, and per-phase power factor.

Shelly EM3 DataSMA Speedwire FieldOBIS CodeUnitDescription
Active Power
Total PowerTotal Active Power1.4.0 / 2.4.0WPositive = Import, Negative = Export
Phase A PowerL1 Active Power21.4.0 / 22.4.0WPhase 1 instantaneous power
Phase B PowerL2 Active Power41.4.0 / 42.4.0WPhase 2 instantaneous power
Phase C PowerL3 Active Power61.4.0 / 62.4.0WPhase 3 instantaneous power
Reactive Power
Calculated TotalTotal Reactive Power3.4.0 / 4.4.0VArCalculated from V, I, PF
Calculated L1L1 Reactive Power23.4.0 / 24.4.0VArCalculated per phase
Calculated L2L2 Reactive Power43.4.0 / 44.4.0VArCalculated per phase
Calculated L3L3 Reactive Power63.4.0 / 64.4.0VArCalculated per phase
Apparent Power
Calculated TotalTotal Apparent Power9.4.0 / 10.4.0VACalculated from V, I
Calculated L1L1 Apparent Power29.4.0 / 30.4.0VACalculated per phase
Calculated L2L2 Apparent Power49.4.0 / 50.4.0VACalculated per phase
Calculated L3L3 Apparent Power69.4.0 / 70.4.0VACalculated per phase
Electrical Parameters
Phase A VoltageL1 Voltage32.4.0VPhase 1 voltage
Phase B VoltageL2 Voltage52.4.0VPhase 2 voltage
Phase C VoltageL3 Voltage72.4.0VPhase 3 voltage
Phase A CurrentL1 Current31.4.0APhase 1 current
Phase B CurrentL2 Current51.4.0APhase 2 current
Phase C CurrentL3 Current71.4.0APhase 3 current
Power Factor
Phase A PFL1 Power Factor33.4.0-Phase 1 power factor (supports negative values)
Phase B PFL2 Power Factor53.4.0-Phase 2 power factor (supports negative values)
Phase C PFL3 Power Factor73.4.0-Phase 3 power factor (supports negative values)
Worst PFTotal Power Factor13.4.0-Worst (closest to zero) phase PF
Grid FrequencyFrequency14.4.0HzGrid frequency
Energy Counters
Energy ConsumedImport Energy1.8.0 / 21.8.0 / 41.8.0 / 61.8.0WhCumulative energy from grid
Energy ExportedExport Energy2.8.0 / 22.8.0 / 42.8.0 / 62.8.0WhCumulative energy to grid
Power Flow Direction

By default, the gateway assumes:

  • Positive power = Energy consumption from grid
  • Negative power = Energy export to grid (solar feed-in)

If your CT clamps are installed backwards, use invert_values: true to correct the readings.

Finding Your Shelly EM3 Topic

Method 1: MQTT Explorer
  1. Connect to your MQTT broker using MQTT Explorer
  2. Look for topics starting with shellies/shellyem3-
  3. The device ID is the part after shellyem3-
Method 2: Command Line
mosquitto_sub -h YOUR_BROKER_IP -t "shellies/#" -v
Method 3: Shelly Web Interface
  1. Access your Shelly EM3 web interface
  2. Go to Settings → Device Info
  3. The device ID is shown there

Troubleshooting

Gateway Not Starting

Check MQTT connectivity:

ping YOUR_BROKER_IP
mosquitto_sub -h YOUR_BROKER_IP -t "shellies/shellyem3-XXXXXXXXXXXXX/#" -v

Enable debug logging to see detailed error messages:

# Docker
docker run -e LOG_LEVEL=DEBUG dzikus99/shelly-speedwire-gateway:latest

# Systemd
# Edit /opt/shelly-speedwire-gateway/shelly_speedwire_gateway_config.yaml
# Set logging.level to DEBUG, then restart:
sudo systemctl restart shelly-speedwire-gateway

# Standalone
# Set LOG_LEVEL=DEBUG in config file or run directly

Check logs:

# Docker
docker logs shelly-speedwire

# Systemd
journalctl -u shelly-speedwire-gateway -f

# Standalone
python3 shelly_speedwire_gateway.py
SMA Device Not Receiving Data

Try different network modes:

  1. Enable broadcast: SPEEDWIRE_USE_BROADCAST=true
  2. Enable dualcast: SPEEDWIRE_DUALCAST=true
  3. Add device IP to unicast targets
Wrong Power Flow Direction

Check these settings in order:

  1. CT clamp orientation - Check if clamps are installed backwards
  2. Enable invert_values - Set invert_values: true if CT clamps are backwards
Debug Commands
# Monitor all Shelly MQTT messages
mosquitto_sub -h BROKER_IP -t "shellies/#" -v

# Check if gateway is sending packets
tcpdump -i any -n udp port 9522

# Check Docker network mode
docker inspect shelly-speedwire | grep NetworkMode

# Monitor specific power values with invert_values
mosquitto_sub -h BROKER_IP -t "shellies/shellyem3-XXXXXXXXXXXXX/emeter/+/power" -v

Protocol Implementation

SMA Speedwire Protocol

The gateway implements the SMA Speedwire EMETER protocol v1.0:

  • Protocol ID: 0x6069 (EMETER)
  • Discovery ID: 0x6081
  • Port: UDP 9522
  • Multicast: 239.12.255.254
  • Update Rate: Configurable (default 1s)
  • Reactive/apparent power support
  • Per-phase power factor with negative value support

Development

Building from Source
# Clone repository
git clone https://github.com/dzikus/shelly-speedwire-gateway
cd shelly-speedwire-gateway

# Create virtual environment
python3 -m venv venv
source venv/bin/activate

# Install dependencies
pip install -r requirements.txt

# Run gateway
python3 shelly_speedwire_gateway.py
Docker Build
# Single architecture
docker build -t shelly-speedwire-gateway .

# Multi-architecture
docker buildx create --use
docker buildx build --platform linux/amd64,linux/arm64,linux/riscv64,linux/s390x,linux/386,linux/arm/v7,linux/arm/v6 \
  --tag your-registry/shelly-speedwire-gateway:latest --push .

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

Guidelines
  1. Test your changes with real hardware if possible
  2. Update documentation for new features
  3. Follow Python PEP 8 style guidelines
  4. Add debug logging for troubleshooting

License

MIT License - See LICENSE file for details.

Acknowledgments

Support

Changelog

v2.0.0 (2025)
  • Added invert_values parameter for backwards CT clamp installations
  • Reactive power (VAr) calculation and transmission
  • Apparent power (VA) calculation and transmission
  • Per-phase power factor support with negative values
  • Complete SMA EMETER protocol implementation (all OBIS channels)
  • Software version emulation updated to 2.3.4.R
  • Removed flip_import_export parameter (replaced by invert_values)
v1.0.0 (2025)
  • Initial release
  • Full Shelly EM3 support
  • SMA Speedwire EMETER protocol implementation
  • Docker, systemd, and standalone deployment options
  • Multicast, broadcast, and unicast transmission modes
  • Automatic discovery response
  • Configurable via environment variables or YAML

Note: This is an unofficial gateway not affiliated with Shelly or SMA. Use at your own risk.

Tag summary

Content type

Image

Digest

sha256:bdfffbd1c

Size

38.2 MB

Last updated

8 months ago

docker pull dzikus99/shelly-speedwire-gateway:2.0.0