forked from sthope/battery2mqtt
		
	Initial commit
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					.env
 | 
				
			||||||
@@ -1,8 +1,8 @@
 | 
				
			|||||||
FROM python:3-alpine
 | 
					FROM python:3-alpine
 | 
				
			||||||
MAINTAINER sthopeless <hopelessautomations@gmail.com>
 | 
					MAINTAINER sthopeless <hopelessautomations@gmail.com>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ADD battery2mqtt.py /
 | 
					ADD laptop2mqtt.py /
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN pip install paho.mqtt
 | 
					RUN pip install paho.mqtt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CMD [ "python", "./battery2mqtt.py" ]
 | 
					CMD [ "python", "./laptop2mqtt.py" ]
 | 
				
			||||||
							
								
								
									
										30
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								README.md
									
									
									
									
									
								
							@@ -1,30 +1,30 @@
 | 
				
			|||||||
# battery2mqtt
 | 
					# laptop2mqtt
 | 
				
			||||||
*Push information about batteries in your system to MQTT*
 | 
					*Push information about batteries in your system to MQTT*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
I thought of this project when I switched to using my old laptop as my Home Assistant server. I wanted to track its battery level in Home Assistant to use in automations. Hopefully others can find it useful as well.
 | 
					I thought of this project when I switched to using my old laptop as my Home Assistant server. I wanted to track its battery level in Home Assistant to use in automations. Hopefully others can find it useful as well.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Summary
 | 
					# Summary
 | 
				
			||||||
`battery2mqtt` can monitor current battery percentage, charging status, etc. for any batteries present at `/sys/class/power_supply`. The MQTT topic format is `battery2mqtt/$TOPIC/$NAME` where `$TOPIC` is the topic you define and `$NAME` is the name of each battery. For example, if `/sys/class/power_supply/BAT0` is present in your system and you choose `server` to be the topic, the full topic will be `battery2mqtt/server/BAT0`. The topic for sensor availability would be `battery2mqtt/server/status`.
 | 
					`laptop2mqtt` can monitor current battery percentage, charging status, etc. for any batteries present at `/sys/class/power_supply`. The MQTT topic format is `laptop2mqtt/$TOPIC/$NAME` where `$TOPIC` is the topic you define and `$NAME` is the name of each battery. For example, if `/sys/class/power_supply/BAT0` is present in your system and you choose `server` to be the topic, the full topic will be `laptop2mqtt/server/BAT0`. The topic for sensor availability would be `laptop2mqtt/server/status`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Instructions
 | 
					# Instructions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**Option 1: Manual build**
 | 
					**Option 1: Manual build**
 | 
				
			||||||
1. Clone repo: `git clone https://github.com/sthopeless/battery2mqtt`
 | 
					1. Clone repo: `git clone https://github.com/sthopeless/laptop2mqtt`
 | 
				
			||||||
2. Enter directory: `cd battery2mqtt`
 | 
					2. Enter directory: `cd laptop2mqtt`
 | 
				
			||||||
3. Build image: `docker build . -t battery2mqtt`
 | 
					3. Build image: `docker build . -t laptop2mqtt`
 | 
				
			||||||
4. Customize `docker-compose.yaml` to fit your needs
 | 
					4. Customize `docker-compose.yaml` to fit your needs
 | 
				
			||||||
5. `docker-compose up -d`
 | 
					5. `docker-compose up -d`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
**Option 2: Docker Hub**
 | 
					**Option 2: Docker Hub**
 | 
				
			||||||
1. Follow steps 4 and 5 above using `sthopeless/battery2mqtt:latest` as the image.
 | 
					1. Follow steps 4 and 5 above using `sthopeless/laptop2mqtt:latest` as the image.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Example docker-compose.yaml with all possible environmental variables listed:
 | 
					Example docker-compose.yaml with all possible environmental variables listed:
 | 
				
			||||||
```yaml
 | 
					```yaml
 | 
				
			||||||
version: '3'
 | 
					version: '3'
 | 
				
			||||||
services:
 | 
					services:
 | 
				
			||||||
  battery2mqtt:
 | 
					  laptop2mqtt:
 | 
				
			||||||
    container_name: battery2mqtt
 | 
					    container_name: laptop2mqtt
 | 
				
			||||||
    image: battery2mqtt:latest
 | 
					    image: laptop2mqtt:latest
 | 
				
			||||||
    environment:
 | 
					    environment:
 | 
				
			||||||
    - MQTT_HOST=10.0.0.2
 | 
					    - MQTT_HOST=10.0.0.2
 | 
				
			||||||
    - MQTT_PORT=1883
 | 
					    - MQTT_PORT=1883
 | 
				
			||||||
@@ -46,7 +46,7 @@ services:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Example `docker run` command with all possible environmental variables:
 | 
					Example `docker run` command with all possible environmental variables:
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
docker run --name battery2mqtt \
 | 
					docker run --name laptop2mqtt \
 | 
				
			||||||
-e MQTT_HOST=10.0.0.2 \
 | 
					-e MQTT_HOST=10.0.0.2 \
 | 
				
			||||||
-e MQTT_PORT=1883 \
 | 
					-e MQTT_PORT=1883 \
 | 
				
			||||||
-e MQTT_USER=user \
 | 
					-e MQTT_USER=user \
 | 
				
			||||||
@@ -61,7 +61,7 @@ docker run --name battery2mqtt \
 | 
				
			|||||||
-e AC_ADAPTER=1 \
 | 
					-e AC_ADAPTER=1 \
 | 
				
			||||||
-e LOG_LEVEL=info \
 | 
					-e LOG_LEVEL=info \
 | 
				
			||||||
-v /sys/class/power_supply:/sys/class/power_supply:ro \
 | 
					-v /sys/class/power_supply:/sys/class/power_supply:ro \
 | 
				
			||||||
sthopeless/battery2mqtt:latest
 | 
					sthopeless/laptop2mqtt:latest
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Configuration
 | 
					# Configuration
 | 
				
			||||||
@@ -73,7 +73,7 @@ sthopeless/battery2mqtt:latest
 | 
				
			|||||||
| `MQTT_PASSWORD` | `None` | False | The password to send to the MQTT broker. |
 | 
					| `MQTT_PASSWORD` | `None` | False | The password to send to the MQTT broker. |
 | 
				
			||||||
| `MQTT_TOPIC` | `server` | True | The topic prefix to send the payload to. |
 | 
					| `MQTT_TOPIC` | `server` | True | The topic prefix to send the payload to. |
 | 
				
			||||||
| `MQTT_QOS` | `1` | False | The MQTT QoS level. |
 | 
					| `MQTT_QOS` | `1` | False | The MQTT QoS level. |
 | 
				
			||||||
| `INTERVAL` | `60` | False | How often (in seconds) battery2mqtt polls for battery info. |
 | 
					| `INTERVAL` | `60` | False | How often (in seconds) laptop2mqtt polls for battery info. |
 | 
				
			||||||
| `MONITORED_CONDITIONS` | (See below) | True | Battery properties to send to MQTT (must be a comma-separated string). |
 | 
					| `MONITORED_CONDITIONS` | (See below) | True | Battery properties to send to MQTT (must be a comma-separated string). |
 | 
				
			||||||
| `BATTERY_HEALTH` | `1` | False | Enable/disable battery health percentage calculation. Set to 0 to disable. |
 | 
					| `BATTERY_HEALTH` | `1` | False | Enable/disable battery health percentage calculation. Set to 0 to disable. |
 | 
				
			||||||
| `TIME_REMAINING` | `1` | False | Enable/disable time remaining estimate (in hours). Set to 0 to disable. |
 | 
					| `TIME_REMAINING` | `1` | False | Enable/disable time remaining estimate (in hours). Set to 0 to disable. |
 | 
				
			||||||
@@ -82,7 +82,7 @@ sthopeless/battery2mqtt:latest
 | 
				
			|||||||
| `LOG_LEVEL` | `info` | False | Set minimum log level. Valid options are `debug`, `info`, `warning`, and `error`. |
 | 
					| `LOG_LEVEL` | `info` | False | Set minimum log level. Valid options are `debug`, `info`, `warning`, and `error`. |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Multiple instances
 | 
					# Multiple instances
 | 
				
			||||||
If you plan on using `battery2mqtt` on more than one machine, it is very important that you use a **different MQTT_TOPIC for each instance**; otherwise, you _will_ experience issues with LWT.
 | 
					If you plan on using `laptop2mqtt` on more than one machine, it is very important that you use a **different MQTT_TOPIC for each instance**; otherwise, you _will_ experience issues with LWT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Monitored conditions
 | 
					# Monitored conditions
 | 
				
			||||||
You can specify only those conditions that you'd like to track. The default is to track `status, capacity, energy_now, energy_full, energy_full_design, power_now, voltage_now`. You can add more conditions (found at `/sys/class/power_supply/$NAME`) or choose only those you want to track. The variable in your `docker-compose.yaml` must follow this comma-separated format:
 | 
					You can specify only those conditions that you'd like to track. The default is to track `status, capacity, energy_now, energy_full, energy_full_design, power_now, voltage_now`. You can add more conditions (found at `/sys/class/power_supply/$NAME`) or choose only those you want to track. The variable in your `docker-compose.yaml` must follow this comma-separated format:
 | 
				
			||||||
@@ -115,11 +115,11 @@ You can monitor the status of the AC adapter (online or offline) by setting `AC_
 | 
				
			|||||||
sensor:
 | 
					sensor:
 | 
				
			||||||
- platform: mqtt
 | 
					- platform: mqtt
 | 
				
			||||||
  name: Server battery
 | 
					  name: Server battery
 | 
				
			||||||
  state_topic: &server_battery_topic "battery2mqtt/server/BAT0"
 | 
					  state_topic: &server_battery_topic "laptop2mqtt/server/BAT0"
 | 
				
			||||||
  value_template: "{{ value_json.capacity }}"
 | 
					  value_template: "{{ value_json.capacity }}"
 | 
				
			||||||
  unit_of_measurement: '%'
 | 
					  unit_of_measurement: '%'
 | 
				
			||||||
  json_attributes_topic: *server_battery_topic
 | 
					  json_attributes_topic: *server_battery_topic
 | 
				
			||||||
  availability_topic: "battery2mqtt/server/status"
 | 
					  availability_topic: "laptop2mqtt/server/status"
 | 
				
			||||||
  device_class: battery
 | 
					  device_class: battery
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,15 +1,15 @@
 | 
				
			|||||||
---
 | 
					---
 | 
				
			||||||
version: "3.8"
 | 
					version: "3.8"
 | 
				
			||||||
services:
 | 
					services:
 | 
				
			||||||
  battery2mqtt:
 | 
					  laptop2mqtt:
 | 
				
			||||||
    container_name: battery2mqtt
 | 
					    container_name: laptop2mqtt
 | 
				
			||||||
    image: sthopeless/battery2mqtt:${TAG-latest}
 | 
					    image: sthopeless/laptop2mqtt:${TAG-latest}
 | 
				
			||||||
    environment:
 | 
					    environment:
 | 
				
			||||||
      - MQTT_HOST=${MQTT_HOST}
 | 
					      - MQTT_HOST=${MQTT_HOST}
 | 
				
			||||||
      - MQTT_PORT=${MQTT_PORT-1883}
 | 
					      - MQTT_PORT=${MQTT_PORT-1883}
 | 
				
			||||||
      - MQTT_USER=${MQTT_USERNAME}
 | 
					      - MQTT_USER=${MQTT_USERNAME}
 | 
				
			||||||
      - MQTT_PASSWORD=${MQTT_PASSWORD}
 | 
					      - MQTT_PASSWORD=${MQTT_PASSWORD}
 | 
				
			||||||
      - MQTT_TOPIC=${MQTT_TOPIC-battery2mqtt}
 | 
					      - MQTT_TOPIC=${MQTT_TOPIC-laptop2mqtt}
 | 
				
			||||||
      - MQTT_QOS=1
 | 
					      - MQTT_QOS=1
 | 
				
			||||||
      - INTERVAL=60
 | 
					      - INTERVAL=60
 | 
				
			||||||
      - MONITORED_CONDITIONS=${SENSORS-status,capacity,energy_now,energy_full,energy_full_design,power_now,voltage_now}
 | 
					      - MONITORED_CONDITIONS=${SENSORS-status,capacity,energy_now,energy_full,energy_full_design,power_now,voltage_now}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@ MQTT_USERNAME=username
 | 
				
			|||||||
MQTT_PASSWORD=password
 | 
					MQTT_PASSWORD=password
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#MQTT_PORT=1883
 | 
					#MQTT_PORT=1883
 | 
				
			||||||
#MQTT_TOPIC=battery2mqtt
 | 
					#MQTT_TOPIC=laptop2mqtt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Choose one
 | 
					### Choose one
 | 
				
			||||||
#LOG_LEVEL=info
 | 
					#LOG_LEVEL=info
 | 
				
			||||||
@@ -102,13 +102,13 @@ class Battery:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    if not dir.startswith('AC'):
 | 
					                    if not dir.startswith('AC'):
 | 
				
			||||||
                        client.publish("battery2mqtt/" + MQTT_TOPIC + '/' + dir, json.dumps(self.payload), MQTT_QOS, False)
 | 
					                        client.publish("laptop2mqtt/" + MQTT_TOPIC + '/' + dir, json.dumps(self.payload), MQTT_QOS, False)
 | 
				
			||||||
                        if LOG_LEVEL == 'DEBUG':
 | 
					                        if LOG_LEVEL == 'DEBUG':
 | 
				
			||||||
                            logging.debug('Sending MQTT payload: ' + str(self.payload))
 | 
					                            logging.debug('Sending MQTT payload: ' + str(self.payload))
 | 
				
			||||||
                except Exception as e:
 | 
					                except Exception as e:
 | 
				
			||||||
                    logging.error(f'Message send failed: {e}')
 | 
					                    logging.error(f'Message send failed: {e}')
 | 
				
			||||||
            try:
 | 
					            try:
 | 
				
			||||||
                client.publish("battery2mqtt/" + MQTT_TOPIC + '/status', 'online', 0, True)
 | 
					                client.publish("laptop2mqtt/" + MQTT_TOPIC + '/status', 'online', 0, True)
 | 
				
			||||||
            except Exception as e:
 | 
					            except Exception as e:
 | 
				
			||||||
                logging.error(f'Message send failed: {e}')
 | 
					                logging.error(f'Message send failed: {e}')
 | 
				
			||||||
            sleep(INTERVAL)
 | 
					            sleep(INTERVAL)
 | 
				
			||||||
@@ -117,9 +117,9 @@ def mqtt_connect():
 | 
				
			|||||||
    # Connect to MQTT broker and set LWT
 | 
					    # Connect to MQTT broker and set LWT
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
        client.username_pw_set(MQTT_USER, MQTT_PASSWORD)
 | 
					        client.username_pw_set(MQTT_USER, MQTT_PASSWORD)
 | 
				
			||||||
        client.will_set("battery2mqtt/" + MQTT_TOPIC + '/status', 'offline', 0, True)
 | 
					        client.will_set("laptop2mqtt/" + MQTT_TOPIC + '/status', 'offline', 0, True)
 | 
				
			||||||
        client.connect(MQTT_HOST, MQTT_PORT)
 | 
					        client.connect(MQTT_HOST, MQTT_PORT)
 | 
				
			||||||
        client.publish("battery2mqtt/" + MQTT_TOPIC + '/status', 'online', 0, True)
 | 
					        client.publish("laptop2mqtt/" + MQTT_TOPIC + '/status', 'online', 0, True)
 | 
				
			||||||
        logging.info('Connected to MQTT broker.')
 | 
					        logging.info('Connected to MQTT broker.')
 | 
				
			||||||
    except Exception as e:
 | 
					    except Exception as e:
 | 
				
			||||||
        logging.error(f'Unable to connect to MQTT broker: {e}')
 | 
					        logging.error(f'Unable to connect to MQTT broker: {e}')
 | 
				
			||||||
@@ -136,7 +136,7 @@ if __name__ == '__main__':
 | 
				
			|||||||
    else:
 | 
					    else:
 | 
				
			||||||
        logging.basicConfig(level=LOG_LEVEL, format='%(asctime)s %(levelname)s: %(message)s')
 | 
					        logging.basicConfig(level=LOG_LEVEL, format='%(asctime)s %(levelname)s: %(message)s')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client = mqtt.Client(f'battery2mqtt_{MQTT_TOPIC}')
 | 
					    client = mqtt.Client(f'laptop2mqtt_{MQTT_TOPIC}')
 | 
				
			||||||
    path = "/sys/class/power_supply/"
 | 
					    path = "/sys/class/power_supply/"
 | 
				
			||||||
    dirs = os.listdir(path)
 | 
					    dirs = os.listdir(path)
 | 
				
			||||||
    b = Battery()
 | 
					    b = Battery()
 | 
				
			||||||
		Reference in New Issue
	
	Block a user