Running OpenEMS Edge on a Raspberry PI
Release 2025.11.0
This guide walksexplains throughhow runningto:
-
Install and run OpenEMS Edge on a Raspberry Pi
and -
itConfigure
toWebSocketan+ simulation -
Run OpenEMS UI
running as a Docker containeron aseparatemacOS machineover(notaonlocalthenetwork.Pi) -
TheConnectgoaltheisUIatosimple, reproduciblelocalthe Edge+ local UIsetup suitable for development, simulation, and early deployments.Architecture OverviewThis setup consists of two main components connectedover the internet:
The structure is intentionally split into two clear parts:
-
EdgePART A — Raspberry Pi (Raspberry Pi)Edge)RunsOpenEMS Edgeas a systemd service and connects to the internet viaWi‑Fi. -
ClientPART B — macOS Machine (Laptop / Desktop)Runs theOpenEMSUIUI)inside a Docker container. The UI may run on a different network (home, office, cloud VM).
Communication:
The UI communicates with the Edge via aWebSocket connection(default port8085) over the public internet.
This means the Edge must be reachable via a public IP, port forwarding, or a secure tunnel.
Assumptions & Prerequisites
Before starting, ensure:
Raspberry Pi hasworking Wi‑Fi internet accessYou haveoneof the following for remote access to the Pi:Public IPv4 address withport forwarding, orAstatic public IP, orA secure tunnel (e.g. WireGuard, Tailscale, Cloudflare Tunnel)
Ports80,443, and8085are reachablefrom the ClientYou havesudo accesson the Raspberry PiRaspberry Pi OS is64‑bit (ARM64)
Strong recommendation:For production or long‑running setups, use a VPN or tunnel instead of exposing ports directly.
Requirements
Hardware
Raspberry Pi–based Edge device(e.g. SL-RP4 with embedded Raspberry Pi 4B)2 GB RAM (minimum)16 GB micro-SD card + reader
Software / Dependencies
SSHRsync or WinSCP (Windows)Raspberry Pi ImagerDocker DesktopOpenEMS source code (release2025.11.0)Adoptium OpenJDK Temurin 21 (ARM64)
Fresh============================
DevicePART Deployment
A —
This guide usesheadless setuponly. No monitor or keyboard is required for the Raspberry Pi.
Format SD Card (Client)
Install and launch Raspberry Pi Imager,(Edge)
then
============================
1. Raspberry Pi OS Setup (Headless)
Use Raspberry Pi Imager:
-
Device: Raspberry Pi 4
-
Operating System:OS: Raspberry Pi OS Lite (64-64‑bit)(Debian Trixie – 2025-10-01) -
Storage:Target SD card
Click Next → Edit Settings.
These settings are written to the SD card and applied on thefirst boot.
OS Customisation — General
Mandatory:Configure:
-
Hostname
-
Username
and& password -
Enable SSH
-
Configure Wi‑Fi
-
Enable Raspberry Pi Connect
Boot the Pi and connect via:
-
SSH
-
OR Raspberry Pi Connect
2. Install Java 21 (Temurin ARM64)
On the Pi:
sudo apt update
sudo apt install -y wget apt-transport-https gpg
wget -qO - https://packages.adoptium.net/artifactory/api/gpg/key/public \
| gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/adoptium.gpg > /dev/null
echo "deb https://packages.adoptium.net/artifactory/deb \
$(awk -F= '/^VERSION_CODENAME/{print $2}' /etc/os-release) main" \
| sudo tee /etc/apt/sources.list.d/adoptium.list
sudo apt update
sudo apt install -y temurin-21-jdk
Verify:
java -version
3. Install OpenEMS Edge
mkdir -p ~/downloads
cd ~/downloads
wget https://github.com/OpenEMS/openems/releases/download/2025.11.0/openems-edge.jar
sudo chmod +x openems-edge.jar
sudo mkdir -p /usr/lib/openems
sudo mv openems-edge.jar /usr/lib/openems/
sudo mkdir -p /etc/openems.d
4. Configure systemd Service
Create:
sudo nano /etc/systemd/system/openems.service
Paste:
[Unit]
Description=OpenEMS Edge
After=network.target
[Service]
User=root
Group=root
Type=notify
WorkingDirectory=/usr/lib/openems
ExecStart=/usr/bin/java -Dfelix.cm.dir=/etc/openems.d/ \
-jar /usr/lib/openems/openems-edge.jar
SuccessExitStatus=143
Restart=always
RestartSec=10
WatchdogSec=60
[Install]
WantedBy=multi-user.target
Enable & start:
sudo systemctl daemon-reload
sudo systemctl enable openems
sudo systemctl start openems
Check:
systemctl status openems
5. Access OpenEMS Config Manager
On the Pi, open:
http://localhost:8080/system/console/configMgr
6. Add Required forComponents
In setup:Config Manager:
-
Add a Scheduler (any default scheduler)
-
Add Controller.Api.Websocket
-
ConfigurePort:Wi‑Fi8085SSID, -
andEnabled:
countrytrue
password, -
Restart Edge:
sudo systemctl restart openems
Verify WebSocket is listening:
sudo ss -lntp | grep 8085
You should see Java listening on port 8085.
7. (Optional) Add Simulation Components
In Config Manager, add:
-
Simulator ESS
-
Simulator Grid Meter
-
Simulator PV
AlsoSave configure:
- restart
TimezoneKeyboard layout
OS Customisation — Services
Enable the following:
✅Enable SSH(key-based auth recommended)✅Enable Raspberry Pi Connect
Raspberry Pi Connect allows secure remote access to the Pi over the internet, even behind NAT, without port forwarding.
Proceed to format the SD card.OpenEMS.
Raspberry=====================================
PiPART ConnectB (Remote Access)
Raspberry Pi Connect provides a secure, browser-based and SSH-like remote access method for headless Raspberry Pi devices without exposing ports or requiring a VPN.
Why Use Raspberry Pi Connect
No monitor or keyboard requiredWorks behind NAT and firewallsSecure, encrypted connectionAccessible from anywhere via a browser
Requirements
Raspberry Pi OS (64-bit)Internet access via Wi-FiRaspberry Pi ID account
First Login via Raspberry Pi Connect
During first boot, ensure the Pi is connected to Wi-FiSign in to Raspberry Pi Connect from another device:
https://connect.raspberrypi.com
Log in with your Raspberry Pi IDSelect your Pi from the device listOpen aremote shellordesktop session(if enabled)
Once Raspberry Pi Connect is active, SSH is optional but still recommended for automation.
Install & Run OpenEMS UI on— macOS Machine (Client Machine)
In this setup, theOpenEMSUIUI)runs=====================================
on yourmacOS machine, not on the Raspberry Pi.
1. Install Docker Desktop (macOS)
If not already installed:
brew install --cask docker
open -a Docker
Wait until the Docker whalereports icon shows "Docker is running".
Verify:
docker version
You must see both Client and Server sections.Server.
2. Clone OpenEMS Source Code (on macOS)
git clone -b 2025.11.0 https://github.com/OpenEMS/openems
cd openems
3. Build the OpenEMS UI Docker Image
docker build . \
-t openems_ui \
-f tools/docker/ui/Dockerfile.edge
Verify image exists:
docker images | grep openems_ui
4. Run the OpenEMS UI Container
Replace YOUR_PI_IP with:
-
Public IP
address of your Raspberry Pi -
OR VPN IP
(recommended) -
OR Public DNS
name
Example:
docker container run \
-e WEBSOCKET_HOST=YOUR_PI_IP \
-p 80:80 \
-p 443:443 \
--restart unless-stopped \
--name openems_ui_container \
openems_ui
Donotincludehttp://or ports inWEBSOCKET_HOST.
OpenEMS5. Open the UI Login (macOS)
OpenOn your browser on the same Mac where Docker is running:Mac:
http://localhost/login
Default login:
-
Username: admin
-
Password: admin
If the dashboard loads butUI shows "disconnected",:
-
theConfirm
RaspberryportPi8085 is listening onport 8085:sudo ss -lntp | grep 8085And confirm thatController.Api.Websocketis configured intheOpenEMS Config Manager on the Pi.Create & Launch the UI Docker Container (Client)Start the UI by accessing:http://localhost/loginDefault password:adminChange language via:Top-left menu → Admin icon → “Sprache wählen”Pi-
RefreshConfirmorWebSocketusecontrollertheexistsback -
toConfirm
returnWEBSOCKET_HOSTtoisthe overviewcorrect
arrow
Tailscale/WireGuard) over port forwardingCreate & Launch theWhy UI Runs on macOS and Edge Runs on Pi
-
Edge interacts with hardware and benefits from native systemd management
-
UI behaves like a stateless web application and is ideal for containerization
-
Separating them improves stability and flexibility
Troubleshooting
-
UI loads but no connection → check port 8085
-
Nothing listening on 8085 → WebSocket not configured
-
Docker
Containererrors on Mac → ensure Docker Desktop is running
Security Notes
-
Prefer VPN/tunnel (
Client)
-
SetUseSSHWEBSOCKET_HOSTtokey-basedoneauthenticationof -
following:Do not expose ConfigMgr (8080) publicly
You now have:
-
PublicOpenEMSIPEdgeaddressrunningof theon Raspberry Pi -
PublicWebSocketDNS name (recommended)enabled -
VPNOptional/simulationtunnel IP or hostname
Example using a public hostname:
docker container run \
-e WEBSOCKET_HOST=edge.example.com \
-p 443:443 -p 80:80 \
--restart unless-stopped \
--name openems_ui_container \
openems_ui
Why UI is Containerized but Edge Runs as a Service
In this guide, the OpenEMS UI runs in Docker while OpenEMS Edge runs as a native systemd service on the Raspberry Pi.
Why containerize the UI
The UI behaves like a web application: it’s comparativelyportableand easier to run consistently across machines.components-
Docker makes it simple to package dependencies, run upgrades/rollbacks, and expose theOpenEMS UIviarunningstandardonports.macOS -
TheUItypicallyconnectedneedsoveronly a small set of runtime settings (e.g.,WEBSOCKET_HOST).internet
Why run Edge as a system service
OpenEMS Edge is closer to an appliance / gateway and is often more reliable when managed directly by the host OS:
Boot reliability:systemdstarts Edge on boot and restarts it if it crashes.Hardware & networking access:Edge may need stable access to devices and networking (serial/USB/Modbus/etc.). Running directly on the OS avoids Docker-specific device mapping and networking edge cases.Persistent configuration:Externalized configs in/etc/openems.dare straightforward to manage and back up.Simpler troubleshooting:Standard Linux tooling works immediately (systemctl status,journalctl).
When running Edge in Docker can make sense
You are runningsimulation only(no direct hardware I/O)You already use container fleet management (e.g., docker-compose, k3s, balena)You can standardize volumes, device mappings, and networking mode
Troubleshooting
UI loads but no Edge connection→ Check public reachability of port 8085Works on LAN but not remotely→ Router port forwarding or firewall missingPublic IP keeps changing→ Use Dynamic DNS or a tunnelConnection drops frequently→ Use VPN/tunnel instead of raw port forwarding
Security Notes (Important)
When exposing OpenEMS Edge over the internet:
Avoid running long‑term setups with raw port forwardingPreferWireGuard, Tailscale, or Cloudflare TunnelConsider TLS termination and authenticationRestrict SSH access (key‑based auth only)
This setup is suitable for remote development, pilots, and managed deployments.