Sign inSign up

dzikus99/shelly-speedwire-gateway

By dzikus99

•Updated 10 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

5.2K

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

10 months ago

docker pull dzikus99/shelly-speedwire-gateway