Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
829cf62
#292: Push HA discovery again when HA connects to broker
krombel Jan 10, 2025
881939b
Merge pull request #294 from krombel/mk/add_dynamic_ha_discovery
nanomad Jan 10, 2025
d73e84e
#292: Refactor publish HA discovery on HA reconnection to enable futu…
nanomad Jan 10, 2025
2cfb2e0
add random delay before pushing discovery messages
krombel Jan 10, 2025
e6d5981
Merge pull request #295 from krombel/mk/add_random_delay_before_pushi…
nanomad Jan 11, 2025
d74e5aa
Migrate to poetry build system
nanomad Jan 11, 2025
12ff2ed
Fix ruff warnings
nanomad Jan 11, 2025
afb231b
Fix test running under poetry
nanomad Jan 11, 2025
daf7850
Install GCC
nanomad Jan 12, 2025
3edf754
Start building from the full python 3.12 version
nanomad Jan 12, 2025
6ad7e53
Rebuild over base image with poetry embedded
nanomad Jan 12, 2025
d61f778
Centralize logging configuration
nanomad Jan 13, 2025
b224a01
#296: Detect charging from BMS instead of car state
nanomad Jan 13, 2025
1242d30
#296: Simplify charging detection logic to detect when the battery is…
nanomad Jan 27, 2025
a6b5d58
#296: Fix tests
nanomad Jan 27, 2025
084b91f
#296: Internally mark the car as "shutdown" only after the car state …
nanomad Feb 2, 2025
7e1cab6
#303: Expose journey ID to Home Assistant
nanomad Feb 2, 2025
7392767
#300: Mark 'Last Charge SoC kWh' in HA as a TOTAL_INCRESING sensor so…
nanomad Feb 2, 2025
919c74d
Do not reference configuration globally
nanomad Feb 7, 2025
0a66a36
Update saic-ismart-client-ng to 0.7.1
nanomad Feb 18, 2025
03f426c
Allow replacing dots with _ in topic names
nanomad Feb 18, 2025
f337bb6
Fix allow replacing dots with _ in topic names
nanomad Feb 18, 2025
52ef32b
Fix ruff warnings
nanomad Feb 18, 2025
5376970
Extract main.py
nanomad Feb 26, 2025
198af14
Rewrite for static typing
nanomad May 2, 2025
73dedfa
Use released lib
nanomad May 3, 2025
013b8c0
Run poetry update
nanomad May 3, 2025
65800d5
Update poetry and drop armv6
nanomad May 3, 2025
9e48a72
Run poetry update
nanomad May 3, 2025
5c08993
Configurable read timeout
nanomad May 3, 2025
00d7db0
Keep retrying initial login
nanomad May 3, 2025
b8feac8
Code cleanup
nanomad May 3, 2025
440cb69
Publish window status only if mileage is reported properly
nanomad May 3, 2025
40ffa4f
Update saic-ismart-client-ng to 0.8.2
nanomad May 31, 2025
6be07cb
Prepare changelog for 0.9.0 release
nanomad May 31, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 190 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# Created by .ignore support plugin (hsz.mobi)
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*,cover
.hypothesis/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# IPython Notebook
.ipynb_checkpoints

# pyenv
.python-version

# celery beat schedule file
celerybeat-schedule

# dotenv
.env

# virtualenv
venv/
ENV/

# Spyder project settings
.spyderproject

# Rope project settings
.ropeproject
### VirtualEnv template
# Virtualenv
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
[Bb]in
[Ii]nclude
[Ll]ib
[Ll]ib64
[Ll]ocal
[Ss]cripts
pyvenv.cfg
.venv
pip-selfcheck.json

### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf

# AWS User-specific
.idea/**/aws.xml

# Generated files
.idea/**/contentModel.xml

# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml

# Gradle
.idea/**/gradle.xml
.idea/**/libraries

# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr

# CMake
cmake-build-*/

# Mongo Explorer plugin
.idea/**/mongoSettings.xml

# File-based project format
*.iws

# IntelliJ
out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Cursive Clojure plugin
.idea/replstate.xml

# SonarLint plugin
.idea/sonarlint/

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

# Editor-based Rest Client
.idea/httpRequests

# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser

# idea folder, uncomment if you don't need it
.idea

# Test results
junit/

.github/
37 changes: 28 additions & 9 deletions .github/workflows/build_and_test_python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,47 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: [ "3.12" ]
python-version: [ "3.12", "3.13" ]

steps:
- uses: actions/checkout@v4
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'

- name: Install Poetry
uses: snok/install-poetry@v1
with:
virtualenvs-in-project: true

- name: Load cached venv
id: cached-poetry-dependencies
uses: actions/cache@v4
with:
path: .venv
key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}

- name: Install dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: |
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
- name: Test with pytest
poetry install --no-interaction --no-root

- name: Install library
run: poetry install --no-interaction

- name: Run tests with coverage
run: |
python -m pip install pytest pytest-cov
python -m pytest --doctest-modules --junitxml=junit/test-results-${{ matrix.python-version }}.xml
poetry run pytest tests --cov --junit-xml=junit/test-results-${{ matrix.python-version }}.xml

- name: Lint with Ruff
run: |
python -m pip install ruff
ruff check --output-format=github .
poetry run ruff check . --output-format=github
continue-on-error: true

- name: Surface failing tests
uses: pmeier/pytest-results-action@main
with:
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/build_python_mqtt_dev_images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ jobs:
if: env.DOCKERHUB_ORGANIZATION == null
with:
context: .
platforms: linux/amd64,linux/arm64,linux/arm/v7
platforms: linux/amd64,linux/arm64
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
tags: |
ghcr.io/${{ steps.lowercase-repository.outputs.lowercase }}/saic-mqtt-gateway:dev
ghcr.io/${{ steps.lowercase-repository.outputs.lowercase }}/saic-mqtt-gateway:${{ env.RELEASE_VERSION }}
Expand All @@ -63,8 +65,10 @@ jobs:
if: env.DOCKERHUB_ORGANIZATION != null
with:
context: .
platforms: linux/amd64,linux/arm64,linux/arm/v7
platforms: linux/amd64,linux/arm64
push: true
cache-from: type=gha
cache-to: type=gha,mode=max
tags: |
ghcr.io/${{ steps.lowercase-repository.outputs.lowercase }}/saic-mqtt-gateway:dev
ghcr.io/${{ steps.lowercase-repository.outputs.lowercase }}/saic-mqtt-gateway:${{ env.RELEASE_VERSION }}
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/build_python_mqtt_images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:
if: env.DOCKERHUB_ORGANIZATION == null
with:
context: .
platforms: linux/amd64,linux/arm64,linux/arm/v7
platforms: linux/amd64,linux/arm64
push: true
tags: |
ghcr.io/${{ steps.lowercase-repository.outputs.lowercase }}/saic-mqtt-gateway:latest
Expand All @@ -63,7 +63,7 @@ jobs:
if: env.DOCKERHUB_ORGANIZATION != null
with:
context: .
platforms: linux/amd64,linux/arm64,linux/arm/v7
platforms: linux/amd64,linux/arm64
push: true
tags: |
ghcr.io/${{ steps.lowercase-repository.outputs.lowercase }}/saic-mqtt-gateway:latest
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -185,4 +185,5 @@ fabric.properties
.idea

# Test results
junit/
junit/
.run/
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Change Log

## 0.9.0

### What's Changed
* Compatibiltity with the latest mobile app release
* #292: Push HA discovery again when HA connects to broker by @krombel in https://github.com/SAIC-iSmart-API/saic-python-mqtt-gateway/pull/294
* add random delay before pushing discovery by @krombel in https://github.com/SAIC-iSmart-API/saic-python-mqtt-gateway/pull/295
* #296: Detect charging from BMS instead of car state by @nanomad in https://github.com/SAIC-iSmart-API/saic-python-mqtt-gateway/pull/298
* Mark 'Last Charge SoC kWh' in HA as a TOTAL_INCRESING sensor so that it can be used in Energy Dashboard by @nanomad
* Expose journey ID to Home Assistant by @nanomad
* Internally mark the car as "shutdown" only after the car state changes.
This avoids looking for a "charging started" event as soon as the charging is completed by @nanomad
* Keep retrying initial login by @nanomad in https://github.com/SAIC-iSmart-API/saic-python-mqtt-gateway/pull/319
* Publish window status only if mileage is reported properly by @nanomad in https://github.com/SAIC-iSmart-API/saic-python-mqtt-gateway/pull/320

### New Contributors
* @krombel made their first contribution in https://github.com/SAIC-iSmart-API/saic-python-mqtt-gateway/pull/294

**Full Changelog**: https://github.com/SAIC-iSmart-API/saic-python-mqtt-gateway/compare/0.7.1...0.9.0

## 0.7.1

## What's changed
Expand Down
55 changes: 45 additions & 10 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,15 +1,50 @@
FROM python:3.12-slim
ARG POETRY_VERSION=2.1.2
ARG PYTHON_VERSION=3.12

FROM weastur/poetry:${POETRY_VERSION}-python-${PYTHON_VERSION} AS builder

ENV POETRY_HOME=/opt/poetry
ENV POETRY_NO_INTERACTION=1
ENV POETRY_VIRTUALENVS_IN_PROJECT=1
ENV POETRY_VIRTUALENVS_CREATE=1
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
# Tell Poetry where to place its cache and virtual environment
ENV POETRY_CACHE_DIR=/opt/.cache

# Install build-time deps for poetry and FFI
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
g++ \
gcc \
libffi-dev \
libssl-dev \
pkg-config \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /usr/src/app

# --- Reproduce the environment ---
# You can comment the following two lines if you prefer to manually install
# the dependencies from inside the container.
COPY pyproject.toml poetry.lock /usr/src/app/

# Install the dependencies and clear the cache afterwards.
# This may save some MBs.
RUN --mount=type=tmpfs,target=/root/.cargo poetry install --no-root && rm -rf $POETRY_CACHE_DIR

# Now let's build the runtime image from the builder.
# We'll just copy the env and the PATH reference.
FROM python:${PYTHON_VERSION}-slim AS runtime

WORKDIR /usr/src/app

COPY requirements.txt ./
RUN apt-get update \
&& apt-get install -y --no-install-recommends gcc python3-dev \
&& rm -rf /var/lib/apt/lists/* \
&& pip install --no-cache-dir -r requirements.txt \
&& apt-get purge -y --auto-remove gcc python3-dev
# the --no-install-recommends helps limit some of the install so that you can be more explicit about what gets installed
ENV VIRTUAL_ENV=/usr/src/app/.venv
ENV PATH="/usr/src/app/.venv/bin:$PATH"

COPY . .
COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV}
COPY src/ .
COPY examples/ .

CMD [ "python", "./mqtt_gateway.py"]
CMD [ "python", "./main.py"]
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ An [openWB](https://openwb.de) charging station is capable of providing informat
need to provide the configuration in the file charging-stations.json. A sample configuration for two cars connected to
an openWB charging station would be the following.

Check-out the [sample file](charging-stations.json.sample)
Check-out the [sample file](examples\charging-stations.json.sample)

The key-value pairs in the JSON express the following:

Expand Down
Loading
Loading