Hi,
this was triggered by a comment on the “Home Assistant” group in FB and it made me research how I can avoid that the laptop, which is used as my proxmox server for Home Assistant, will be charging its battery all the time. Lithium batteries don’t really like this and having them plugged in all the time can actually even shorten their lifetime.
I used my old MacBook especially because it has a battery, sort of a “free” UPS if you like. So in order to get this working in Home Assistant I did the following.
I first of all need a tool which can retrieve the battery status, after some looking around I decided to install upower and use this to retrieve the battery status. So if you want to do this too, login to the shell of your proxmox server (mine is called PVE01) as root and use apt to install upower:
apt install upower
Test it with this command:
power -i $(upower -e | grep BAT) | grep --color=never -E “state|to\ full|to\ empty|percentage”
The output will look something like this:
state: charging
time to full: 2.6 hours
percentage: 39%
I found that the “time to full” is not always shown, especially when the device is fully charged.
Next make sure you have python3, pip3 and the paho mqtt client libraries installed. If not these commands can help you:
apt install python3 pip3
pip3 install paho.mqtt.client
If you installed or updated to proxmox 8, you might have to replace the command above with the apt version:
apt install python3-paho-mqtt
I wrote this simple Python script to send the data to my MQTT server, running under Home Assistant. Make sure you adapt the correct IP addresses and username/password.
#!/bin/python3
#
import subprocess
import time
import json
from paho.mqtt import client as mqtt_client
broker="mqtt.local.lan"
port=1883
topic="/proxmox/PVE01/battery"
username="xxxxxxxx"
password="pppppppp"
client_id = "PVE01"
debug = 0
cmd = 'upower -i $(upower -e | grep BAT) | grep --color=never -E "state|to\ full|to\ empty|percentage"'
battery = {
"state":"empty",
"time_to_empty" : "0 hours",
"percentage" : 0
}
def connect_mqtt():
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected to MQTT Broker!")
else:
print("Failed to connect, return code %d\n", rc)
client = mqtt_client.Client(client_id)
client.username_pw_set(username, password)
client.on_connect = on_connect
client.connect(broker, port)
return client
def publish(client):
msg_count = 1
while True:
returned_output1 = subprocess.check_output(cmd, shell=True, text=True)
list = returned_output1.splitlines()
ll = len(list)
v = list[0].split(":")
battery["state"] = v[1].strip();
if ll == 3:
v = list[1].split(":")
battery["time_to_empty"] = v[1].strip()
v = list[2].split(":")
battery["percentage"] = int(float(v[1].strip()[:-1]))
else:
v = list[1].split(":")
battery["percentage"] = int(float(v[1].strip()[:-1]))
battery["time_to_empty"] = "unknown"
msg = json.dumps(battery)
if debug != 0:
print(msg)
result = client.publish(topic, msg)
# result: [0, 1]
status = result[0]
if status == 0:
if debug != 0:
print(f"Send `{msg}` to topic `{topic}`")
else:
print(f"Failed to send message to topic {topic}")
msg_count += 1
time.sleep(60)
def run():
client = connect_mqtt()
client.loop_start()
publish(client)
client.loop_stop()
if __name__ == '__main__':
run()
So to get this value (I am mostly interested in the percentage), I defined the sensor in my MQTT entry in my configuration.
configuration.xml
mqtt: !include mqtt.yaml
mqtt.yaml
sensor:
- name: "PVE01 battery"
unit_of_measurement: "%"
state_topic: "/proxmox/PVE01/battery"
value_template: "{{ value_json.percentage }}"
device_class: battery
unique_id: pve01_battery
My LIDL switch is connected through Zigbee2MQTT, but I guess you can use any remote switch to do the necessary automation, so that your laptop will be disconnected when it is 90% full and reconnected when the battery goes below 30%.
This is how I see the values on my testing dashboard:
The yaml code looks like this:
- square: false
type: grid
cards:
- graph: line
type: sensor
entity: sensor.pve01_battery
detail: 1
- show_name: true
show_icon: true
type: button
tap_action:
action: toggle
entity: switch.lidl_proxmox
name: PVE01 Charger
columns: 2
And the last step I implemented was an automation which checks the battery level every time it is reported to my HA through MQTT.
alias: PVE01 Battery Charging
description: ""
trigger:
- platform: time_pattern
minutes: /5
condition: []
action:
- choose:
- conditions:
- condition: numeric_state
entity_id: sensor.pve01_battery
above: 90
sequence:
- service: switch.turn_off
data: {}
target:
device_id: f6e4db0c95d342f6b7d9b542f3a08aae
- conditions:
- condition: numeric_state
entity_id: sensor.pve01_battery
below: 30
sequence:
- service: switch.turn_on
data: {}
target:
device_id: f6e4db0c95d342f6b7d9b542f3a08aae
mode: single
And to run it, I just added this entry to my crontab:
# m h dom mon dow command
*/5 * * * * /root/dev/battery.py
I hope this will be helpful to some!