I’ve used PVE (Proxmox Virtual Environment) for a while now for Node-RED, MQTT Broker, Emoncms etc and it really is bullet proof. My preferred setup is on an old laptop so this setup has a built-in UPS (its battery). I’ve thought for a while that I really should cycle the battery to enhance how long it runs and preserve the lifespan.
Needing to get a new laptop so I can upgrade the old system to V8, I decided to work out the best way to monitor the battery. I have installed Netdata and then accessed the Battery chart via the API previously and while I do Install Netdata, this means of battery monitoring was not great. ACPI provides more data including a status value.
First step, install acpi and a parser called jc that I have used in the past to take the acpi data and transform it into a JSON output. You also need the mosquitto-clients for publishing the data. These are installed via apt-get install acpi jc mosquitto-clients. Test it.
|
1 2 3 4 5 6 7 8 9 10 |
# acpi -b | jc --acpi -r -p [ { "type": "Battery", "id": "0", "state": "Charging", "charge_percent": "98", "until_charged": "00:08:02" } ] |
Now for the easy part and although I knew how, I used Co-Pilot to generate the script and the systemd unit to run it.
Shell script
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#!/bin/bash # Get the hostname HOSTNAME=$(hostname) # MQTT Broker details MQTT_BROKER="broker.address" MQTT_PORT=1883 MQTT_TOPIC="$HOSTNAME/acpi/data" # MQTT Authentication MQTT_USER="user" MQTT_PASSWORD="password" # Sleep time between data transmissions (in seconds) SLEEP_TIME=30 while true; do # Originally done as separate lines, but on a newer system, it didn't like it so all done in one now # Read ACPI data # ACPI_DATA=$(acpi -b| jc --acpi -r) # Read ACPI data and replace word 'state' with 'mode' # ACPI_DATA=$(acpi -b| jc --acpi -r | sed 's/"state"/"mode"/g') # Publish data to MQTT broker with authentication # mosquitto_pub -h "$MQTT_BROKER" -p "$MQTT_PORT" -u "$MQTT_USER" -P "$MQTT_PASSWORD" -t "$MQTT_TOPIC" -m "$ACPI_DATA" acpi -b | jc --acpi -r | jq -c 'map(if has("state") then .mode = .state | del(.state) else . end)' \ | mosquitto_pub -h "$MQTT_BROKER" -p "$MQTT_PORT" -u "$MQTT_USER" -P "$MQTT_PASSWORD" -t "$MQTT_TOPIC" -l # Wait for the configured sleep time sleep "$SLEEP_TIME" done |
Save this script to /usr/local/bin/acpi_mqtt_data.sh
Create a systemd Unit in /usr/lib/systemd/system as acpi-mqtt.service. If you put the various Environment values in, you do not need them in the Shell script.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[Unit] Description=ACPI Data MQTT Publisher After=network.target [Service] ExecStart=/usr/local/bin/acpi_mqtt_data.sh Restart=always User=your_user Group=your_group Environment="MQTT_BROKER=mqtt.example.com" Environment="MQTT_PORT=1883" Environment="MQTT_TOPIC=$(hostname)/acpi/data" Environment="MQTT_USER=your_username" Environment="MQTT_PASSWORD=your_password" Environment="SLEEP_TIME=30" [Install] WantedBy=multi-user.target |
Save the file then
|
1 |
systemctl reload |
Reload the daemon, enable the unit (so it auto starts at boot) and start it.
Adding this information into a Sensor in HomeAssistant, plugging in a Smart Switch and creating the automation to cycle the battery will be just as easy.
Job done.
[edit]
If only. The HA part turned out to be a bit of a PITA. The MQTT sensor refused to process the key named state. Modified the script above to change that key to mode.
|
1 2 3 4 5 6 7 |
sensor: - name: "pve_battery" state_topic: "pve/acpi/data" value_template: "{{ value_json[0].charge_percent }}" # Using charge_percent as the state unit_of_measurement: '%' json_attributes_topic: "pve/acpi/data" json_attributes_template: '{{ value_json[0] | tojson }}' # attributes: |