Based on https://github.com/b48736/axpert-monitor
Send Axpert inverter data from HID/RS232 to MQTT.
Periodically publishes inverter status over MQTT and reacts to a few commands.
Commands are checked with startsWith to work as a firewall.
All settings are read from environment variables, with sensible defaults so the process also runs without any configuration:
| Variable | Default | Description |
|---|---|---|
MQTT_HOST |
192.168.1.112 |
MQTT broker host |
MQTT_PORT |
1883 |
MQTT broker port |
MQTT_PREFIX |
axpert |
Topic prefix (use a unique one per inverter) |
SERIAL_PORT |
/dev/serial/by-path/platform-3f980000.usb-usb-0:1.5:1.0-port0 |
Serial device of the inverter |
Comment out the port option in index.js to use HID instead of UART.
/dev/ttyUSB* numbers are assigned in plug order and shuffle across reboots, so
use a stable path from /dev/serial/:
ls -l /dev/serial/by-id/ # by adapter serial number — survives moving to another USB port
ls -l /dev/serial/by-path/ # by physical USB port — survives swapping the adapter in the same port
Use by-path when you might replace the USB-serial adapter but keep it in the
same physical port; use by-id to pin to a specific adapter regardless of port.
With prefix axpert (configurable via MQTT_PREFIX):
| Topic | Direction | Payload |
|---|---|---|
axpert/generalStatus |
publish | JSON, general status (every 1 s) |
axpert/totalEnergyProduced |
publish | total produced energy (every 10 s) |
axpert/mode |
publish | inverter mode (every 10 s) |
axpert/cmd |
subscribe | command, e.g. POP0…, PCP…, PBCV, PBDV |
# uses the defaults
pm2 start index.js --name axpert-monitor-mqtt
# or override config
MQTT_PREFIX=axpert SERIAL_PORT=/dev/serial/by-path/...:1.5:...-port0 \
pm2 start index.js --name axpert-monitor-mqtt
pm2 save
ecosystem.config.js runs the same index.js as several pm2 apps, each with its
own prefix and serial port:
module.exports = {
apps: [
{ name: 'axpert-monitor-mqtt', script: 'index.js',
env: { MQTT_PREFIX: 'axpert',
SERIAL_PORT: '/dev/serial/by-path/platform-3f980000.usb-usb-0:1.5:1.0-port0' } },
{ name: 'axpert-monitor-mqtt2', script: 'index.js',
env: { MQTT_PREFIX: 'axpert2',
SERIAL_PORT: '/dev/serial/by-path/platform-3f980000.usb-usb-0:1.2:1.0-port0' } },
],
}pm2 start ecosystem.config.js # start all apps
pm2 start ecosystem.config.js --only axpert-monitor-mqtt2 # start one app
pm2 save # persist across reboots
Note:
envis only applied when starting from the ecosystem file. To change the env of an app that was started withpm2 start index.js,pm2 delete <name>first, then start it again fromecosystem.config.js.
# Node-RED
bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --confirm-install --confirm-pi
cd ~/.node-red
npm install node-red-dashboard node-red-contrib-persist
cd
sudo systemctl enable nodered.service
sudo systemctl start nodered.service
# MQTT broker
sudo apt install -y mosquitto mosquitto-clients
sudo systemctl enable mosquitto.service
sudo systemctl start mosquitto.service
sudo apt install -y git
git clone https://github.com/hubmartin/axpert-monitor-mqtt.git
cd axpert-monitor-mqtt
sudo apt install libusb-1.0-0-dev
# if node is too new, try nvm install 18.15.0
npm install
sudo npm install pm2 -g
pm2 install pm2-logrotate
pm2 start ecosystem.config.js
#pm2 startup
sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u pi --hp /home/pi
pm2 save
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
On older RPI I had to run this before npm install: sudo apt install libusb-dev libudev-dev.
Import node-red-flow.json file in Node-RED.