Skip to content

Commit

Permalink
Merge pull request #4 from b2un0/main
Browse files Browse the repository at this point in the history
Fixing ble_password not being passed to manager; adding docker for ease-of-use and updated readme.me - including previous shortcomings in terms of license and misplaced requirements.txt.
  • Loading branch information
slespersen authored Dec 3, 2024
2 parents b70fee2 + 129b3b1 commit abe2d1d
Show file tree
Hide file tree
Showing 8 changed files with 244 additions and 116 deletions.
51 changes: 51 additions & 0 deletions .github/workflows/container.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: 'container'

on:
push:
workflow_dispatch:

jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Docker meta
id: meta
uses: docker/metadata-action@v4
with:
# images: ${{ vars.DOCKER_USERNAME }}/${{ vars.DOCKER_IMAGE }},ghcr.io/${{ github.repository }}
images: ghcr.io/${{ github.repository }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
# - name: Login to DockerHub
# uses: docker/login-action@v2
# with:
# username: ${{ vars.DOCKER_USERNAME }}
# password: ${{ secrets.DOCKER_TOKEN }}

- name: Login to ghcr.io
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v2

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
# platforms: linux/amd64,linux/arm64
platforms: linux/amd64
push: true
provenance: false
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ venv/
ENV/
env.bak/
venv.bak/
.env

# Installed packages
*.egg-info/
Expand Down
19 changes: 19 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM python:3-alpine

RUN apk add bluez

ENV BLE_ADDRESS="" \
BLE_PASSWORD="" \
MQTT_BROKER="" \
MQTT_PORT="1883" \
MQTT_USERNAME="" \
MQTT_PASSWORD="" \
LOGGING_LEVEL="INFO"

ADD . /app

WORKDIR /app

RUN pip install -r requirements.txt

CMD ["sh", "-c", "python main.py --address ${BLE_ADDRESS} --password ${BLE_PASSWORD} --mqtt --mqtt_broker ${MQTT_BROKER} --mqtt_port ${MQTT_PORT} --mqtt_user ${MQTT_USERNAME} --mqtt_password ${MQTT_PASSWORD} --logging_level ${LOGGING_LEVEL}"]
19 changes: 19 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
The MIT License (MIT)

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
260 changes: 149 additions & 111 deletions readme.md → README.md
Original file line number Diff line number Diff line change
@@ -1,112 +1,150 @@
# evseMQTT
`evseMQTT` is a Python library designed for communicating with EVSE-based Electric Vehicle Charging Wallboxes using Bluetooth Low Energy (BLE), and exposing its data and controls to Home Assistant using MQTT Discovery. Due to potential security concerns of WiFi connectivity, this library facilitates a local, no cloud connection to your EVSE device. It has been tested on the Besen BS20 model using a Raspberry Pi Zero 2 W.

The code base is by no means perfect or especially beautiful -- pragmatic hacks are applied where needed.
![Home Assistant Device view](https://raw.githubusercontent.com/slespersen/evseMQTT/refs/heads/main/evseMQTT_home_assistant.png)
## Features

`evseMQTT` provides the following functionalities:

- **Start/Stop Charging:** Control the charging process.
- **Set Maximum Amps:** Define the maximum amperage for a charging session.
- **Change Language:** Modify the language setting (note: this affects the smartphone app rather than the wallbox itself).
- **Device Name:** Set or change the name of the device.
- **Temperature Unit:** Set the preferred unit of temperature.
- **Phase detection**: Available phases are automatically identified.
- **Max amp detection**: Maximum amperage output is automatically detected.
- **Automatic Reconnect**: In case the Bluetooth connection is stale, and no message has been received for more than 35 seconds, the script will automatically reinitialize.

Additionally, `evseMQTT` allows you to read:
- **Current Consumption of Energy:** Monitor the energy consumption in kilowatt-hours (kWh).
- **Errors**: Monitor potential errors.
- **Phase characteristics**: Monitor voltage and amperage across the phases present on the charger.
- **Messages**: Monitor messages defined by the state of both the plug, the output and the status.
- **Total Consumption**: Monitor the total energy consumption (since last reset) in kilowatt-hours (kWh).
- **Temperature**: Monitor the current temperature.
- **Date & Time**: Get the devices current date and time.

## Home Assistant Integration

`evseMQTT` exposes basic control functionalities to Home Assistant via MQTT Discovery, enabling seamless integration and control within your home automation setup.

## Upcoming features

The following functions are in the making:

- **Automatic Temperature Unit Update**: Automatically updating of the enabled and disabled temperature unit sensor in Home Assistant to not pollute the different statistics.
- **Additional Status Messages**: Additional messages for both charge_start and charge_stop.

## Installation

Since `evseMQTT` is not yet available on pip, it needs to be installed manually. Follow these steps:

1. Clone the repository:
```bash
git clone https://github.com/slespersen/evseMQTT.git
```

2. Create a symbolic link to your Python library directory:
```bash
ln -s /path/to/evseMQTT /path/to/your/python/lib
```

## Usage

`main.py` is provided for running the library. Below are the arguments it accepts:

### Arguments

- `--address`: (Required) The BLE device address.
- `--password`: (Optional) The BLE device password. Default is "123456".
- `--mqtt`: (Optional) Enable MQTT.
- `--mqtt_broker`: (Optional) The MQTT broker address.
- `--mqtt_port`: (Optional) The MQTT broker port.
- `--mqtt_user`: (Optional) The MQTT username.
- `--mqtt_password`: (Optional) The MQTT password.
- `--logging_level`: (Optional) The logging level. Default is "INFO".

### Example Command

Here's an example of how to run `main.py` with the necessary arguments:
```bash
python main.py --address "your_device_address" --mqtt --mqtt_broker "your_mqtt_broker_address" --mqtt_port 1883 --mqtt_user "your_mqtt_username" --mqtt_password "your_mqtt_password" --logging_level "DEBUG"
```
## Caveats
This library is in no means complete, when compared to the original app - some features missing:
- Charging History
- LCD Brightness
- Password Reset
- Device Reset
- WiFi setup
Seemingly unexpected behavior, but working as intended:
- When changing the device name, the device will disconnect and the script will wait for 35 seconds, since the last received message, before reconnecting.
## Acknowledgements
A big thank you to the following contributors:
- [bakkers](https://github.com/bakkers) for documenting findings: https://gist.github.com/bakkerrs/cb75e3c3a337f8f38a3f84f4b49beaa5
- [johnwoo-nl](https://github.com/johnwoo-nl) for building emproto: https://github.com/johnwoo-nl/emproto/tree/main?tab=readme-ov-file
- [Phil242](https://github.com/Phil242), [FlorentVTT](https://github.com/FlorentVTT), and [DutchDevelop](https://github.com/DutchDevelop) for their original efforts in decoding the EVSE protocol
## Tested Devices
- **Besen BS20:** This library has been tested and verified to work with the Besen BS20 Electric Vehicle Charging Wallbox.
## License
This project is licensed under the MIT License.
## Contributing
Contributions are welcome! Please feel free to submit a pull request or open an issue.
## Support
# evseMQTT
`evseMQTT` is a Python library designed for communicating with EVSE-based Electric Vehicle Charging Wallboxes using Bluetooth Low Energy (BLE), and exposing its data and controls to Home Assistant using MQTT Discovery. Due to potential security concerns of WiFi connectivity, this library facilitates a local, no cloud connection to your EVSE device. It has been tested on the Besen BS20 model using a Raspberry Pi Zero 2 W.

The code base is by no means perfect or especially beautiful -- pragmatic hacks are applied where needed.
![Home Assistant Device view](https://raw.githubusercontent.com/slespersen/evseMQTT/refs/heads/main/evseMQTT_home_assistant.png)
## Features

`evseMQTT` provides the following functionalities:

- **Start/Stop Charging:** Control the charging process.
- **Set Maximum Amps:** Define the maximum amperage for a charging session.
- **Change Language:** Modify the language setting (note: this affects the smartphone app rather than the wallbox itself).
- **Device Name:** Set or change the name of the device.
- **Temperature Unit:** Set the preferred unit of temperature.
- **Phase detection**: Available phases are automatically identified.
- **Max amp detection**: Maximum amperage output is automatically detected.
- **Automatic Reconnect**: In case the Bluetooth connection is stale, and no message has been received for more than 35 seconds, the script will automatically reinitialize.

Additionally, `evseMQTT` allows you to read:
- **Current Consumption of Energy:** Monitor the energy consumption in kilowatt-hours (kWh).
- **Errors**: Monitor potential errors.
- **Phase characteristics**: Monitor voltage and amperage across the phases present on the charger.
- **Messages**: Monitor messages defined by the state of both the plug, the output and the status.
- **Total Consumption**: Monitor the total energy consumption (since last reset) in kilowatt-hours (kWh).
- **Temperature**: Monitor the current temperature.
- **Date & Time**: Get the devices current date and time.

## Home Assistant Integration

`evseMQTT` exposes basic control functionalities to Home Assistant via MQTT Discovery, enabling seamless integration and control within your home automation setup.

## Upcoming features

The following functions are in the making:

- **Automatic Temperature Unit Update**: Automatically updating of the enabled and disabled temperature unit sensor in Home Assistant to not pollute the different statistics.
- **Additional Status Messages**: Additional messages for both charge_start and charge_stop.

## Installation

Since `evseMQTT` is not yet available on pip, it needs to be installed manually. Follow these steps:

1. Clone the repository:
```bash
git clone https://github.com/slespersen/evseMQTT.git
```

2. Create a symbolic link to your Python library directory:
```bash
ln -s /path/to/evseMQTT /path/to/your/python/lib
```

## Usage

`main.py` is provided for running the library. Below are the arguments it accepts:

### Arguments

- `--address`: (Required) The BLE device address.
- `--password`: (Optional) The BLE device password. Default is "123456".
- `--mqtt`: (Optional) Enable MQTT.
- `--mqtt_broker`: (Optional) The MQTT broker address.
- `--mqtt_port`: (Optional) The MQTT broker port.
- `--mqtt_user`: (Optional) The MQTT username.
- `--mqtt_password`: (Optional) The MQTT password.
- `--logging_level`: (Optional) The logging level. Default is "INFO".

### Example Command

Here's an example of how to run `main.py` with the necessary arguments:
```bash
python main.py --address "your_device_mac_address" \
--password "your_6_digit_pin" \
--mqtt \
--mqtt_broker "your_mqtt_broker_address" \
--mqtt_port 1883 \
--mqtt_user "your_mqtt_username" \
--mqtt_password "your_mqtt_password" \
--logging_level "DEBUG"
```
### run as container
```bash
docker run -d --name evseMQTT \
--restart always \
-v /var/run/dbus:/run/dbus \
-e BLE_ADDRESS="your_device_mac_address" \
-e BLE_PASSWORD="your_6_digit_pin" \
-e MQTT_BROKER="your_mqtt_broker_address" \
-e MQTT_PORT=1883 \
-e MQTT_USER="your_mqtt_username" \
-e MQTT_PASSWORD="your_mqtt_password" \
-e LOGGING_LEVEL="INFO" \
ghcr.io/slespersen/evsemqtt:latest
```
### determine BLE address for your EVSE
look for a mac address started with `ACP#` like this:
```bash
bluetoothctl scan le
```
results in something like this:
```plain
Discovery started
[CHG] Controller B8:27:EB:B4:51:EB Discovering: yes
[NEW] Device 12:34:56:78:99:00 ACP#NamedEVSE
```
## Caveats
This library is in no means complete, when compared to the original app - some features missing:
- Charging History
- LCD Brightness
- Password Reset
- Device Reset
- WiFi setup
Seemingly unexpected behavior, but working as intended:
- When changing the device name, the device will disconnect and the script will wait for 35 seconds, since the last received message, before reconnecting.
## Acknowledgements
A big thank you to the following contributors:
- [bakkers](https://github.com/bakkers) for documenting findings: https://gist.github.com/bakkerrs/cb75e3c3a337f8f38a3f84f4b49beaa5
- [johnwoo-nl](https://github.com/johnwoo-nl) for building emproto: https://github.com/johnwoo-nl/emproto/tree/main?tab=readme-ov-file
- [Phil242](https://github.com/Phil242), [FlorentVTT](https://github.com/FlorentVTT), and [DutchDevelop](https://github.com/DutchDevelop) for their original efforts in decoding the EVSE protocol
## Tested Devices
- **Besen BS20:** This library has been tested and verified to work with the Besen BS20 Electric Vehicle Charging Wallbox.
## License
This project is licensed under the MIT License.
## Contributing
Contributions are welcome! Please feel free to submit a pull request or open an issue.
## Support
For any questions or issues, please open an issue.
2 changes: 0 additions & 2 deletions evseMQTT/requirements.txt

This file was deleted.

6 changes: 3 additions & 3 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from evseMQTT import BLEManager, Constants, Device, EventHandlers, Commands, Logger, MQTTClient, MQTTCallback, MQTTPayloads, Utils

class Manager:
def __init__(self, address, ble_password="123456", mqtt_enabled=False, mqtt_settings=None, logging_level=logging.INFO):
def __init__(self, address, ble_password, mqtt_enabled=False, mqtt_settings=None, logging_level=logging.INFO):
self.setup_logging(logging_level)
self.logger = logging.getLogger("evseMQTT")
debug = logging_level == logging.DEBUG # Determine if debug logging is enabled
Expand Down Expand Up @@ -114,7 +114,7 @@ async def restart_run(self, address = None):
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="BLE Manager")
parser.add_argument("--address", type=str, required=True, help="BLE device address")
parser.add_argument("--password", type=str, help="BLE device password")
parser.add_argument("--password", type=str, required=True, help="BLE device password")
parser.add_argument("--mqtt", action='store_true', help="Enable MQTT")
parser.add_argument("--mqtt_broker", type=str, help="MQTT broker address")
parser.add_argument("--mqtt_port", type=int, help="MQTT broker port")
Expand All @@ -133,5 +133,5 @@ async def restart_run(self, address = None):

logging_level = getattr(logging, args.logging_level.upper(), logging.INFO)

manager = Manager(args.address, mqtt_enabled=args.mqtt, mqtt_settings=mqtt_settings, logging_level=logging_level)
manager = Manager(args.address, ble_password=args.password, mqtt_enabled=args.mqtt, mqtt_settings=mqtt_settings, logging_level=logging_level)
asyncio.run(manager.run(args.address))
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bleak==0.20.2
paho-mqtt==1.6.1

0 comments on commit abe2d1d

Please sign in to comment.