A lightweight Python bridge that connects to a NUT (Network UPS Tools) server and publishes UPS data to an MQTT broker. Features native Home Assistant integration via MQTT Discovery. No external binaries required - pure Python implementation.
- Home Assistant MQTT Discovery - Automatic sensor creation with proper units, device classes, and icons
- Pure Python NUT client implementation (no
upscor other binaries needed) - Configurable via YAML file
- Supports authentication for both NUT and MQTT
- Two publish modes:
- Individual topics: Each UPS variable published to separate MQTT topic
- JSON mode: All variables published as single JSON payload
- Auto-discovery of UPS devices
- Device grouping in Home Assistant (all sensors grouped under one UPS device)
- Availability tracking (online/offline status)
- Configurable polling interval
- Automatic reconnection on connection loss
- Comprehensive logging
- Install Python dependencies:
pip install -r requirements.txtEdit config.yaml to match your environment:
nut:
host: "10.10.102.2" # Your NUT server IP
port: 3493
ups_name: "10.10.102.2" # UPS name (leave empty for auto-detect)
username: null # Set if NUT requires authentication
password: null
mqtt:
host: "localhost" # Your MQTT broker IP
port: 1883
username: null # Set if MQTT requires authentication
password: null
topic_prefix: "nut"
format: "individual" # "individual" or "json"
homeassistant:
discovery: true # Enable Home Assistant MQTT Discovery
discovery_prefix: "homeassistant" # HA Discovery prefix
poll_interval: 30 # Poll every 30 seconds
log_level: "INFO"Run the bridge:
python nut2mqtt.py config.yamlOr make it executable:
chmod +x nut2mqtt.py
./nut2mqtt.py config.yamlEach UPS variable is published to a separate topic:
nut/10.10.102.2/battery.charge → "91"
nut/10.10.102.2/battery.voltage → "13.5"
nut/10.10.102.2/input.voltage → "225.7"
nut/10.10.102.2/ups.status → "OL CHRG"
...
All variables published to a single topic as JSON:
nut/10.10.102.2 → {"battery.charge": "91", "battery.voltage": "13.5", ...}
When homeassistant.discovery: true is set in the config, the bridge will automatically:
- Create a UPS device in Home Assistant with all metadata (manufacturer, model, serial number)
- Add all available sensors as entities under this device
- Configure proper units of measurement (%, V, W, Hz, A, etc.)
- Assign appropriate device classes for correct visualization
- Set custom icons for each sensor
- Enable availability tracking (shows online/offline status)
Based on your UPS, sensors will include:
- Battery Charge (%) - with battery device class
- Battery Voltage (V) - with voltage device class
- Battery Runtime (s) - estimated runtime in seconds
- Input Voltage (V) - line voltage with measurement state class
- Input Frequency (Hz) - line frequency
- Output Voltage (V) - output voltage with measurement state class
- Output Power (W) - current power draw with measurement state class
- Output Current (A) - current in amperes
- UPS Load (%) - load percentage
- UPS Status - status string (OL=Online, CHRG=Charging, etc.)
- UPS Model, Manufacturer, Serial Number, etc.
All sensors are grouped under a single device in Home Assistant for easy organization.
Once running, you'll see a device named after your UPS model (e.g., "TOWER_1000VA_230V") with all sensors organized underneath. The device card will show:
- Real-time battery status and charge level
- Input/output voltage and power
- Current load and estimated runtime
- All with appropriate icons and units
Create /etc/systemd/system/nut2mqtt.service:
[Unit]
Description=NUT to MQTT Bridge
After=network.target
[Service]
Type=simple
User=your-user
WorkingDirectory=/path/to/Nut2MQTT
ExecStart=/usr/bin/python3 /path/to/Nut2MQTT/nut2mqtt.py /path/to/Nut2MQTT/config.yaml
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.targetEnable and start:
sudo systemctl enable nut2mqtt
sudo systemctl start nut2mqtt
sudo systemctl status nut2mqtt-
Make sure your
config.yamlis in the project directory -
Start the container:
docker-compose up -d- View logs:
docker-compose logs -f- Stop the container:
docker-compose downThe docker-compose.yaml uses host networking for easy access to your NUT server and MQTT broker. Adjust the timezone in the environment section if needed.
Build the image:
docker build -t nut2mqtt .Run the container:
docker run -d \
--name nut2mqtt \
--restart unless-stopped \
--network host \
-v $(pwd)/config.yaml:/config/config.yaml:ro \
-e TZ=Europe/Rome \
nut2mqttView logs:
docker logs -f nut2mqttSet log_level: "DEBUG" in config.yaml to see detailed connection and data information.
- Verify NUT server is accessible:
telnet 10.10.102.2 3493 - Check firewall rules allow connections to NUT (port 3493) and MQTT (port 1883)
- Verify UPS name is correct (check NUT server configuration)
If your NUT server requires authentication, set username and password in the nut section of config.yaml.
- Ensure MQTT integration is configured in Home Assistant
- Check
homeassistant.discovery: trueinconfig.yaml - Verify the discovery prefix matches your Home Assistant MQTT config (default:
homeassistant) - Check MQTT broker logs to confirm discovery messages are being received
- Restart the bridge to re-send discovery messages
- Check Home Assistant logs for any MQTT-related errors
MIT License - feel free to use and modify as needed.