7.0 KiB
Operations and troubleshooting
HTTP endpoints
| Path | Purpose | Device access |
|---|---|---|
/metrics |
Prometheus/OpenMetrics output. Each request triggers collection from all configured devices. | yes |
/-/healthy |
Exporter process health; returns HTTP 200 and OK. |
no |
The health endpoint proves that the HTTP process can respond. It deliberately does not contact Shelly devices. Use shelly_up to monitor individual device availability.
Native deployment
go build -trimpath -o shelly-exporter .
./shelly-exporter -config config.yaml
The process handles SIGINT and SIGTERM, stops accepting requests, and gives the HTTP server up to 10 seconds to shut down.
Example systemd unit:
[Unit]
Description=Shelly Prometheus Exporter
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=shelly-exporter
Group=shelly-exporter
ExecStart=/usr/local/bin/shelly-exporter -config /etc/shelly-exporter/config.yaml
Restart=on-failure
RestartSec=5s
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadOnlyPaths=/etc/shelly-exporter/config.yaml
[Install]
WantedBy=multi-user.target
Ensure the service account can read the configuration and reach every device over the network.
Docker deployment
Build the image:
docker build --rm -t shelly-exporter:latest .
Run it with a read-only configuration mount:
docker run --rm -d \
--name shelly-exporter \
-p 9090:9090 \
-v "$PWD/config.yaml:/opt/shelly-exporter/config.yaml:ro" \
shelly-exporter:latest
The image runs as an unprivileged user and includes a health check against /-/healthy. The configuration bundled in the image is only an example; mount the actual configuration for production.
Prometheus setup
scrape_configs:
- job_name: shelly
scrape_interval: 30s
scrape_timeout: 15s
static_configs:
- targets:
- shelly-exporter:9090
Keep the Prometheus scrape_timeout greater than shelly.timeoutSeconds plus a small allowance for metric encoding and network latency. Devices are queried concurrently, so the worst normal collection duration is close to the slowest device request rather than the sum of all requests.
The exporter contacts every device for every Prometheus scrape. Very short scrape intervals add unnecessary work to low-power hardware. A 15–60 second interval is a reasonable starting point for powered devices.
Battery-powered sensors
Shelly Gen1 H&T, Flood, Door/Window, Button1, and similar battery devices sleep to conserve power. They may be unavailable during most scheduled scrapes, causing expected shelly_up == 0 results. Consider MQTT or event callbacks when continuous collection from these products is required.
Useful PromQL
Current power per standard meter:
shelly_meter_power_watts
Consumed energy over 24 hours in kWh:
increase(shelly_meter_energy_watt_hours_total[24h]) / 1000
EM/3EM imported and exported energy over 24 hours in kWh:
increase(shelly_emeter_energy_watt_hours_total[24h]) / 1000
increase(shelly_emeter_returned_energy_watt_hours_total[24h]) / 1000
Devices currently unavailable:
shelly_up == 0
Free RAM percentage where both fields are reported:
100 * shelly_ram_free_bytes / shelly_ram_size_bytes
Example alert rules
Adjust durations and exclude sleeping products according to the installation.
groups:
- name: shelly
rules:
- alert: ShellyDeviceDown
expr: shelly_up == 0
for: 5m
labels:
severity: warning
annotations:
summary: "Shelly {{ $labels.device }} is unreachable"
- alert: ShellyDeviceOvertemperature
expr: shelly_overtemperature == 1
for: 1m
labels:
severity: critical
annotations:
summary: "Shelly {{ $labels.device }} reports overtemperature"
- alert: ShellyWeakWiFi
expr: shelly_wifi_rssi_dbm < -80
for: 10m
labels:
severity: warning
annotations:
summary: "Shelly {{ $labels.device }} has weak Wi-Fi signal"
Security
- Store
config.yamloutside source control and restrict it to the exporter account, for example with mode0600on Linux. - Prefer a trusted management network. HTTPS encrypts credentials in transit, but the exporter does not verify device certificates and therefore does not authenticate the remote endpoint.
- The exporter endpoints themselves do not require authentication. Restrict port 9090 with firewall, reverse proxy, or network policy when necessary.
- Device passwords are not metric labels, but request failures can include the target URL in logs. Do not put credentials in URL user-info; use
usernameandpasswordfields. - HTTPS device certificates are not verified. Restrict device traffic to a trusted network to reduce man-in-the-middle risk.
Troubleshooting
Exporter does not start
Read the fatal error first. Configuration loading is strict, and common causes are:
- an unknown or misspelled YAML key;
- a hostname in
hostinstead of a literal IP address; - an empty device list;
- duplicate device names;
- an unsupported product identifier;
- a URL missing
http://orhttps://.
Increase logLevel to 5 or 6 only after configuration validation succeeds.
shelly_up is zero
Test the same request from the exporter host or container network:
curl -v -u admin:password http://192.168.0.30/status
Check routing, firewall rules, device power, credentials, and the configured timeout. HTTP errors and JSON decoding failures increment shelly_scrape_errors_total.
HTTP 401 Unauthorized
Confirm that the configured username and password match the device. The exporter uses HTTP Basic Authentication. A device configured for a different authentication scheme will not work with the current client.
TLS certificate error
The exporter deliberately ignores certificate validity for HTTPS device connections, including trust, expiry, and hostname checks. A certificate validation error therefore indicates that an older exporter build may still be running; update and restart it. Other TLS errors, such as unsupported protocol versions or cipher suites, are not certificate validation errors and can still fail the scrape.
Device is up but an expected metric is absent
Metrics are intentionally conditional. Capture the raw /status JSON and verify that the corresponding field is present. Firmware versions and device modes can change response blocks—for example, Shelly 2.5 reports either relays or rollers depending on its operating mode.
For an unlisted Gen1 device, try product: gen1. If the field exists but is not modeled, follow the extension guide.
Scrapes time out
- Increase
shelly.timeoutSecondsand Prometheusscrape_timeouttogether. - Verify Wi-Fi RSSI and packet loss.
- Avoid overly short scrape intervals.
- Check whether a configured battery device is normally asleep.