├── tests
└── __init__.py
├── src
└── govee_ble
│ ├── py.typed
│ ├── __init__.py
│ └── parser.py
├── docs
├── source
│ ├── _static
│ │ └── .gitkeep
│ ├── changelog.md
│ ├── contributing.md
│ ├── usage.md
│ ├── installation.md
│ ├── index.md
│ └── conf.py
├── Makefile
└── make.bat
├── .flake8
├── renovate.json
├── .gitpod.yml
├── setup.py
├── commitlint.config.mjs
├── .all-contributorsrc
├── .github
├── ISSUE_TEMPLATE
│ ├── 1-bug_report.md
│ └── 2-feature-request.md
├── workflows
│ ├── hacktoberfest.yml
│ ├── labels.yml
│ ├── issue-manager.yml
│ └── ci.yml
├── dependabot.yml
└── labels.toml
├── .idea
├── govee-ble.iml
├── workspace.xml
└── watcherTasks.xml
├── .editorconfig
├── .readthedocs.yml
├── .pre-commit-config.yaml
├── .gitignore
├── pyproject.toml
├── README.md
├── CONTRIBUTING.md
├── LICENSE
└── CHANGELOG.md
/tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/govee_ble/py.typed:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/source/_static/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.flake8:
--------------------------------------------------------------------------------
1 | [flake8]
2 | exclude = docs
3 | max-line-length = 120
4 |
--------------------------------------------------------------------------------
/docs/source/changelog.md:
--------------------------------------------------------------------------------
1 | ```{include} ../../CHANGELOG.md
2 |
3 | ```
4 |
--------------------------------------------------------------------------------
/docs/source/contributing.md:
--------------------------------------------------------------------------------
1 | ```{include} ../../CONTRIBUTING.md
2 |
3 | ```
4 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["github>browniebroke/renovate-configs:python"]
3 | }
4 |
--------------------------------------------------------------------------------
/docs/source/usage.md:
--------------------------------------------------------------------------------
1 | # Usage
2 |
3 | To use this package, import it:
4 |
5 | ```python
6 | import govee_ble
7 | ```
8 |
9 | TODO: Document usage
10 |
--------------------------------------------------------------------------------
/docs/source/installation.md:
--------------------------------------------------------------------------------
1 | # Installation
2 |
3 | The package is published on [PyPI](https://pypi.org/project/deezer-python/) and can be installed with `pip` (or any equivalent):
4 |
5 | ```bash
6 | pip install govee-ble
7 | ```
8 |
--------------------------------------------------------------------------------
/.gitpod.yml:
--------------------------------------------------------------------------------
1 | tasks:
2 | - command: |
3 | pip install poetry
4 | PIP_USER=false poetry install
5 | - command: |
6 | pip install pre-commit
7 | pre-commit install
8 | PIP_USER=false pre-commit install-hooks
9 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # This is a shim to allow GitHub to detect the package, build is done with poetry
4 | # Taken from https://github.com/Textualize/rich
5 |
6 | import setuptools
7 |
8 | if __name__ == "__main__":
9 | setuptools.setup(name="govee-ble")
10 |
--------------------------------------------------------------------------------
/commitlint.config.mjs:
--------------------------------------------------------------------------------
1 | export default {
2 | extends: ["@commitlint/config-conventional"],
3 | rules: {
4 | "header-max-length": [0, "always", Infinity],
5 | "body-max-line-length": [0, "always", Infinity],
6 | "footer-max-line-length": [0, "always", Infinity],
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/docs/source/index.md:
--------------------------------------------------------------------------------
1 | # Welcome to Govee BLE documentation!
2 |
3 | ```{toctree}
4 | :caption: Installation & Usage
5 | :maxdepth: 2
6 |
7 | installation
8 | usage
9 | ```
10 |
11 | ```{toctree}
12 | :caption: Project Info
13 | :maxdepth: 2
14 |
15 | changelog
16 | contributing
17 | ```
18 |
19 | ```{include} ../../README.md
20 |
21 | ```
22 |
--------------------------------------------------------------------------------
/.all-contributorsrc:
--------------------------------------------------------------------------------
1 | {
2 | "projectName": "govee-ble",
3 | "projectOwner": "bluetooth-devices",
4 | "repoType": "github",
5 | "repoHost": "https://github.com",
6 | "files": ["README.md"],
7 | "imageSize": 80,
8 | "commit": true,
9 | "commitConvention": "angular",
10 | "contributors": [],
11 | "contributorsPerLine": 7,
12 | "skipCi": true
13 | }
14 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/1-bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | labels: bug
5 | ---
6 |
7 | **Describe the bug**
8 | A clear and concise description of what the bug is.
9 |
10 | **To Reproduce**
11 | Steps to reproduce the behavior:
12 |
13 | **Additional context**
14 | Add any other context about the problem here.
15 |
--------------------------------------------------------------------------------
/.idea/govee-ble.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 |
3 | root = true
4 |
5 | [*]
6 | indent_style = space
7 | indent_size = 4
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 | charset = utf-8
11 | end_of_line = lf
12 |
13 | [*.bat]
14 | indent_style = tab
15 | end_of_line = crlf
16 |
17 | [LICENSE]
18 | insert_final_newline = false
19 |
20 | [Makefile]
21 | indent_style = tab
22 |
--------------------------------------------------------------------------------
/.github/workflows/hacktoberfest.yml:
--------------------------------------------------------------------------------
1 | name: Hacktoberfest
2 |
3 | on:
4 | schedule:
5 | # Run every day in October
6 | - cron: "0 0 * 10 *"
7 | # Run on the 1st of November to revert
8 | - cron: "0 13 1 11 *"
9 |
10 | jobs:
11 | hacktoberfest:
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | - uses: browniebroke/hacktoberfest-labeler-action@v2.3.0
16 | with:
17 | github_token: ${{ secrets.GH_PAT }}
18 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/2-feature-request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | labels: enhancement
5 | ---
6 |
7 | **Is your feature request related to a problem? Please describe.**
8 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
9 |
10 | **Describe the solution you'd like**
11 | A clear and concise description of what you want to happen.
12 |
13 | **Additional context**
14 | Add any other context or screenshots about the feature request here.
15 |
--------------------------------------------------------------------------------
/.github/workflows/labels.yml:
--------------------------------------------------------------------------------
1 | name: Sync Github labels
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | paths:
8 | - ".github/**"
9 |
10 | jobs:
11 | labels:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v5
15 | - name: Set up Python
16 | uses: actions/setup-python@v6
17 | with:
18 | python-version: 3.8
19 | - name: Install labels
20 | run: pip install labels
21 | - name: Sync config with Github
22 | run: labels -u ${{ github.repository_owner }} -t ${{ secrets.GITHUB_TOKEN }} sync -f .github/labels.toml
23 |
--------------------------------------------------------------------------------
/.readthedocs.yml:
--------------------------------------------------------------------------------
1 | # Read the Docs configuration file
2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3 |
4 | # Required
5 | version: 2
6 |
7 | # Build documentation in the docs/ directory with Sphinx
8 | sphinx:
9 | configuration: docs/source/conf.py
10 |
11 | # Set the version of Python and other tools you might need
12 | build:
13 | os: ubuntu-20.04
14 | tools:
15 | python: "3.9"
16 |
17 | # Optionally declare the Python requirements required to build your docs
18 | python:
19 | install:
20 | - method: pip
21 | path: .
22 | extra_requirements:
23 | - docs
24 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line, and also
5 | # from the environment for the first two.
6 | SPHINXOPTS ?=
7 | SPHINXBUILD ?= sphinx-build
8 | SOURCEDIR = source
9 | BUILDDIR = build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
21 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "github-actions"
9 | directory: "/"
10 | schedule:
11 | interval: "monthly"
12 | commit-message:
13 | prefix: "chore(ci): "
14 | groups:
15 | github-actions:
16 | patterns:
17 | - "*"
18 | - package-ecosystem: "pip" # See documentation for possible values
19 | directory: "/" # Location of package manifests
20 | schedule:
21 | interval: "weekly"
22 |
--------------------------------------------------------------------------------
/.github/workflows/issue-manager.yml:
--------------------------------------------------------------------------------
1 | name: Issue Manager
2 |
3 | on:
4 | schedule:
5 | - cron: "0 0 * * *"
6 | issue_comment:
7 | types:
8 | - created
9 | issues:
10 | types:
11 | - labeled
12 | pull_request_target:
13 | types:
14 | - labeled
15 | workflow_dispatch:
16 |
17 | jobs:
18 | issue-manager:
19 | runs-on: ubuntu-latest
20 | steps:
21 | - uses: tiangolo/issue-manager@0.5.1
22 | with:
23 | token: ${{ secrets.GITHUB_TOKEN }}
24 | config: >
25 | {
26 | "answered": {
27 | "message": "Assuming the original issue was solved, it will be automatically closed now."
28 | },
29 | "waiting": {
30 | "message": "Automatically closing. To re-open, please provide the additional information requested."
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | set SOURCEDIR=source
11 | set BUILDDIR=build
12 |
13 | if "%1" == "" goto help
14 |
15 | %SPHINXBUILD% >NUL 2>NUL
16 | if errorlevel 9009 (
17 | echo.
18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
19 | echo.installed, then set the SPHINXBUILD environment variable to point
20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
21 | echo.may add the Sphinx directory to PATH.
22 | echo.
23 | echo.If you don't have Sphinx installed, grab it from
24 | echo.http://sphinx-doc.org/
25 | exit /b 1
26 | )
27 |
28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29 | goto end
30 |
31 | :help
32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33 |
34 | :end
35 | popd
36 |
--------------------------------------------------------------------------------
/src/govee_ble/__init__.py:
--------------------------------------------------------------------------------
1 | """Parser for Govee BLE advertisements.
2 |
3 | This file is shamelessly copied from the following repository:
4 | https://github.com/Ernst79/bleparser/blob/c42ae922e1abed2720c7fac993777e1bd59c0c93/package/bleparser/govee.py
5 |
6 | MIT License applies.
7 | """
8 |
9 | from __future__ import annotations
10 |
11 | from sensor_state_data import (
12 | BinarySensorDeviceClass,
13 | BinarySensorValue,
14 | DeviceKey,
15 | SensorDescription,
16 | SensorDeviceClass,
17 | SensorDeviceInfo,
18 | SensorUpdate,
19 | SensorValue,
20 | Units,
21 | )
22 | from sensor_state_data import (
23 | DeviceClass,
24 | )
25 |
26 | from .parser import GoveeBluetoothDeviceData, SensorType, get_model_info, ModelInfo
27 |
28 | __version__ = "1.0.0"
29 |
30 | __all__ = [
31 | "GoveeBluetoothDeviceData",
32 | "BinarySensorDeviceClass",
33 | "SensorDeviceClass",
34 | "BinarySensorValue",
35 | "SensorType",
36 | "SensorDescription",
37 | "SensorDeviceInfo",
38 | "DeviceClass",
39 | "DeviceKey",
40 | "SensorUpdate",
41 | "SensorDeviceInfo",
42 | "SensorValue",
43 | "Units",
44 | "get_model_info",
45 | "ModelInfo",
46 | ]
47 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | # See https://pre-commit.com for more information
2 | # See https://pre-commit.com/hooks.html for more hooks
3 | exclude: "CHANGELOG.md"
4 | default_stages: [pre-commit]
5 |
6 | ci:
7 | autofix_commit_msg: "chore(pre-commit.ci): auto fixes"
8 | autoupdate_commit_msg: "chore(pre-commit.ci): pre-commit autoupdate"
9 |
10 | repos:
11 | - repo: https://github.com/commitizen-tools/commitizen
12 | rev: v4.9.1
13 | hooks:
14 | - id: commitizen
15 | stages: [commit-msg]
16 | - repo: https://github.com/pre-commit/pre-commit-hooks
17 | rev: v6.0.0
18 | hooks:
19 | - id: debug-statements
20 | - id: check-builtin-literals
21 | - id: check-case-conflict
22 | - id: check-docstring-first
23 | - id: check-json
24 | - id: check-toml
25 | - id: check-xml
26 | - id: check-yaml
27 | - id: detect-private-key
28 | - id: end-of-file-fixer
29 | - id: trailing-whitespace
30 | - id: debug-statements
31 | - repo: https://github.com/pre-commit/mirrors-prettier
32 | rev: v4.0.0-alpha.8
33 | hooks:
34 | - id: prettier
35 | args: ["--tab-width", "2"]
36 | - repo: https://github.com/asottile/pyupgrade
37 | rev: v3.20.0
38 | hooks:
39 | - id: pyupgrade
40 | args: [--py310-plus]
41 | - repo: https://github.com/astral-sh/ruff-pre-commit
42 | rev: v0.13.3
43 | hooks:
44 | - id: ruff
45 | args: [--fix, --exit-non-zero-on-fix]
46 | - id: ruff-format
47 | - repo: https://github.com/codespell-project/codespell
48 | rev: v2.4.1
49 | hooks:
50 | - id: codespell
51 | - repo: https://github.com/PyCQA/flake8
52 | rev: 7.3.0
53 | hooks:
54 | - id: flake8
55 | - repo: https://github.com/pre-commit/mirrors-mypy
56 | rev: v1.18.2
57 | hooks:
58 | - id: mypy
59 | additional_dependencies: []
60 |
--------------------------------------------------------------------------------
/docs/source/conf.py:
--------------------------------------------------------------------------------
1 | # Configuration file for the Sphinx documentation builder.
2 | #
3 | # This file only contains a selection of the most common options. For a full
4 | # list see the documentation:
5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html
6 |
7 | # -- Path setup --------------------------------------------------------------
8 |
9 | # If extensions (or modules to document with autodoc) are in another directory,
10 | # add these directories to sys.path here. If the directory is relative to the
11 | # documentation root, use os.path.abspath to make it absolute, like shown here.
12 | #
13 | # import os
14 | # import sys
15 | # sys.path.insert(0, os.path.abspath('.'))
16 | from typing import Any
17 |
18 | # -- Project information -----------------------------------------------------
19 |
20 | project = "Govee BLE"
21 | copyright = "2020, J. Nick Koston"
22 | author = "J. Nick Koston"
23 |
24 |
25 | # -- General configuration ---------------------------------------------------
26 |
27 | # Add any Sphinx extension module names here, as strings. They can be
28 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
29 | # ones.
30 | extensions = [
31 | "myst_parser",
32 | ]
33 |
34 | # The suffix of source filenames.
35 | source_suffix = [".rst", ".md"]
36 |
37 | # Add any paths that contain templates here, relative to this directory.
38 | templates_path = ["_templates"]
39 |
40 | # List of patterns, relative to source directory, that match files and
41 | # directories to ignore when looking for source files.
42 | # This pattern also affects html_static_path and html_extra_path.
43 | exclude_patterns: list[Any] = []
44 |
45 |
46 | # -- Options for HTML output -------------------------------------------------
47 |
48 | # The theme to use for HTML and HTML Help pages. See the documentation for
49 | # a list of builtin themes.
50 | #
51 | html_theme = "sphinx_rtd_theme"
52 |
53 | # Add any paths that contain custom static files (such as style sheets) here,
54 | # relative to this directory. They are copied after the builtin static files,
55 | # so a file named "default.css" will overwrite the builtin "default.css".
56 | html_static_path = ["_static"]
57 |
--------------------------------------------------------------------------------
/.github/labels.toml:
--------------------------------------------------------------------------------
1 | [breaking]
2 | color = "ffcc00"
3 | name = "breaking"
4 | description = "Breaking change."
5 |
6 | [bug]
7 | color = "d73a4a"
8 | name = "bug"
9 | description = "Something isn't working"
10 |
11 | [dependencies]
12 | color = "0366d6"
13 | name = "dependencies"
14 | description = "Pull requests that update a dependency file"
15 |
16 | [github_actions]
17 | color = "000000"
18 | name = "github_actions"
19 | description = "Update of github actions"
20 |
21 | [documentation]
22 | color = "1bc4a5"
23 | name = "documentation"
24 | description = "Improvements or additions to documentation"
25 |
26 | [duplicate]
27 | color = "cfd3d7"
28 | name = "duplicate"
29 | description = "This issue or pull request already exists"
30 |
31 | [enhancement]
32 | color = "a2eeef"
33 | name = "enhancement"
34 | description = "New feature or request"
35 |
36 | ["good first issue"]
37 | color = "7057ff"
38 | name = "good first issue"
39 | description = "Good for newcomers"
40 |
41 | ["help wanted"]
42 | color = "008672"
43 | name = "help wanted"
44 | description = "Extra attention is needed"
45 |
46 | [invalid]
47 | color = "e4e669"
48 | name = "invalid"
49 | description = "This doesn't seem right"
50 |
51 | [nochangelog]
52 | color = "555555"
53 | name = "nochangelog"
54 | description = "Exclude pull requests from changelog"
55 |
56 | [question]
57 | color = "d876e3"
58 | name = "question"
59 | description = "Further information is requested"
60 |
61 | [removed]
62 | color = "e99695"
63 | name = "removed"
64 | description = "Removed piece of functionalities."
65 |
66 | [tests]
67 | color = "bfd4f2"
68 | name = "tests"
69 | description = "CI, CD and testing related changes"
70 |
71 | [wontfix]
72 | color = "ffffff"
73 | name = "wontfix"
74 | description = "This will not be worked on"
75 |
76 | [discussion]
77 | color = "c2e0c6"
78 | name = "discussion"
79 | description = "Some discussion around the project"
80 |
81 | [hacktoberfest]
82 | color = "ffa663"
83 | name = "hacktoberfest"
84 | description = "Good issues for Hacktoberfest"
85 |
86 | [answered]
87 | color = "0ee2b6"
88 | name = "answered"
89 | description = "Automatically closes as answered after a delay"
90 |
91 | [waiting]
92 | color = "5f7972"
93 | name = "waiting"
94 | description = "Automatically closes if no answer after a delay"
95 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | ### Python template
3 | # Byte-compiled / optimized / DLL files
4 | __pycache__/
5 | *.py[cod]
6 | *$py.class
7 |
8 | # C extensions
9 | *.so
10 |
11 | # Distribution / packaging
12 | .Python
13 | build/
14 | develop-eggs/
15 | dist/
16 | downloads/
17 | eggs/
18 | .eggs/
19 | lib/
20 | lib64/
21 | parts/
22 | sdist/
23 | var/
24 | wheels/
25 | share/python-wheels/
26 | *.egg-info/
27 | .installed.cfg
28 | *.egg
29 | MANIFEST
30 |
31 | # PyInstaller
32 | # Usually these files are written by a python script from a template
33 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
34 | *.manifest
35 | *.spec
36 |
37 | # Installer logs
38 | pip-log.txt
39 | pip-delete-this-directory.txt
40 |
41 | # Unit test / coverage reports
42 | htmlcov/
43 | .tox/
44 | .nox/
45 | .coverage
46 | .coverage.*
47 | .cache
48 | nosetests.xml
49 | coverage.xml
50 | *.cover
51 | *.py,cover
52 | .hypothesis/
53 | .pytest_cache/
54 | cover/
55 |
56 | # Translations
57 | *.mo
58 | *.pot
59 |
60 | # Django stuff:
61 | *.log
62 | local_settings.py
63 | db.sqlite3
64 | db.sqlite3-journal
65 |
66 | # Flask stuff:
67 | instance/
68 | .webassets-cache
69 |
70 | # Scrapy stuff:
71 | .scrapy
72 |
73 | # Sphinx documentation
74 | docs/_build/
75 |
76 | # PyBuilder
77 | .pybuilder/
78 | target/
79 |
80 | # Jupyter Notebook
81 | .ipynb_checkpoints
82 |
83 | # IPython
84 | profile_default/
85 | ipython_config.py
86 |
87 | # pyenv
88 | # For a library or package, you might want to ignore these files since the code is
89 | # intended to run in multiple environments; otherwise, check them in:
90 | # .python-version
91 |
92 | # pipenv
93 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
94 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
95 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
96 | # install all needed dependencies.
97 | #Pipfile.lock
98 |
99 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
100 | __pypackages__/
101 |
102 | # Celery stuff
103 | celerybeat-schedule
104 | celerybeat.pid
105 |
106 | # SageMath parsed files
107 | *.sage.py
108 |
109 | # Environments
110 | .env
111 | .venv
112 | env/
113 | venv/
114 | ENV/
115 | env.bak/
116 | venv.bak/
117 |
118 | # Spyder project settings
119 | .spyderproject
120 | .spyproject
121 |
122 | # Rope project settings
123 | .ropeproject
124 |
125 | # mkdocs documentation
126 | /site
127 |
128 | # mypy
129 | .mypy_cache/
130 | .dmypy.json
131 | dmypy.json
132 |
133 | # Pyre type checker
134 | .pyre/
135 |
136 | # pytype static type analyzer
137 | .pytype/
138 |
139 | # Cython debug symbols
140 | cython_debug/
141 |
--------------------------------------------------------------------------------
/.idea/watcherTasks.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 |
9 | concurrency:
10 | group: ${{ github.head_ref || github.run_id }}
11 | cancel-in-progress: true
12 |
13 | jobs:
14 | lint:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - uses: actions/checkout@v5
18 | - uses: actions/setup-python@v6
19 | with:
20 | python-version: "3.9"
21 | - uses: pre-commit/action@v3.0.1
22 |
23 | # Make sure commit messages follow the conventional commits convention:
24 | # https://www.conventionalcommits.org
25 | commitlint:
26 | name: Lint Commit Messages
27 | runs-on: ubuntu-latest
28 | steps:
29 | - uses: actions/checkout@v5
30 | with:
31 | fetch-depth: 0
32 | - uses: wagoid/commitlint-github-action@v6
33 |
34 | test:
35 | strategy:
36 | fail-fast: false
37 | matrix:
38 | python-version:
39 | - "3.10"
40 | - "3.11"
41 | - "3.12"
42 | - "3.13"
43 | os:
44 | - ubuntu-latest
45 | runs-on: ${{ matrix.os }}
46 | steps:
47 | - uses: actions/checkout@v5
48 | - name: Set up Python
49 | uses: actions/setup-python@v6
50 | with:
51 | python-version: ${{ matrix.python-version }}
52 | - uses: snok/install-poetry@v1
53 | - name: Install Dependencies
54 | shell: bash
55 | run: poetry install
56 | - name: Test with Pytest
57 | shell: bash
58 | run: poetry run pytest --cov-report=xml
59 | - name: Upload coverage to Codecov
60 | uses: codecov/codecov-action@v5
61 | with:
62 | token: ${{ secrets.CODECOV_TOKEN }}
63 |
64 | release:
65 | runs-on: ubuntu-latest
66 | environment: release
67 | if: github.ref == 'refs/heads/main'
68 | needs:
69 | - test
70 | - lint
71 | - commitlint
72 | permissions:
73 | id-token: write
74 | contents: write
75 |
76 | steps:
77 | - uses: actions/checkout@v5
78 | with:
79 | fetch-depth: 0
80 |
81 | # Run semantic release:
82 | # - Update CHANGELOG.md
83 | # - Update version in code
84 | # - Create git tag
85 | # - Create GitHub release
86 | - name: Python Semantic Release
87 | id: release
88 | uses: python-semantic-release/python-semantic-release@v10.4.1
89 | with:
90 | github_token: ${{ secrets.GITHUB_TOKEN }}
91 | - name: Upload package to PyPI
92 | uses: pypa/gh-action-pypi-publish@release/v1
93 | if: steps.release.outputs.released == 'true'
94 | - name: Upload Github Release Assets
95 | uses: python-semantic-release/publish-action@v10.4.1
96 | if: steps.release.outputs.released == 'true'
97 | with:
98 | github_token: ${{ secrets.GITHUB_TOKEN }}
99 | tag: ${{ steps.release.outputs.tag }}
100 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [project]
2 | name = "govee-ble"
3 | version = "1.0.0"
4 | license = "Apache-2.0"
5 | description = "Manage Govee BLE devices"
6 | authors = [{ name = "J. Nick Koston", email = "nick@koston.org" }]
7 | readme = "README.md"
8 | requires-python = ">=3.10"
9 | dynamic = ["classifiers", "dependencies", "optional-dependencies"]
10 |
11 | [project.urls]
12 | "Repository" = "https://github.com/bluetooth-devices/govee-ble"
13 | "Documentation" = "https://govee-ble.readthedocs.io"
14 | "Bug Tracker" = "https://github.com/bluetooth-devices/govee-ble/issues"
15 | "Changelog" = "https://github.com/bluetooth-devices/govee-ble/blob/main/CHANGELOG.md"
16 |
17 | [tool.poetry]
18 | classifiers = [
19 | "Development Status :: 2 - Pre-Alpha",
20 | "Intended Audience :: Developers",
21 | "Natural Language :: English",
22 | "Operating System :: OS Independent",
23 | "Topic :: Software Development :: Libraries",
24 | ]
25 | packages = [
26 | { include = "govee_ble", from = "src" },
27 | ]
28 |
29 | [tool.poetry.dependencies]
30 | python = "^3.10"
31 |
32 | # Documentation Dependencies
33 | Sphinx = {version = ">=5,<9", optional = true}
34 | sphinx-rtd-theme = {version = ">=1,<4", optional = true}
35 | myst-parser = {version = ">=0.18,<4.1", optional = true}
36 | home-assistant-bluetooth = ">=1.3.0"
37 | sensor-state-data = ">=2.18.0"
38 | bluetooth-sensor-state-data = ">=1.5.0"
39 | bluetooth-data-tools = ">=0.1.2"
40 | cryptography = ">=42.0.0"
41 |
42 | [tool.poetry.extras]
43 | docs = [
44 | "myst-parser",
45 | "sphinx",
46 | "sphinx-rtd-theme",
47 | ]
48 |
49 | [tool.poetry.dev-dependencies]
50 | pytest = "^8.4"
51 | pytest-cov = "^7.0"
52 |
53 | [tool.semantic_release]
54 | branch = "main"
55 | version_toml = ["pyproject.toml:project.version"]
56 | version_variables = ["src/govee_ble/__init__.py:__version__"]
57 | build_command = "pip install poetry && poetry build"
58 |
59 | [tool.pytest.ini_options]
60 | addopts = "-v -Wdefault --cov=govee_ble --cov-report=term-missing:skip-covered"
61 | pythonpath = ["src"]
62 |
63 | [tool.coverage.run]
64 | branch = true
65 |
66 | [tool.coverage.report]
67 | exclude_lines = [
68 | "pragma: no cover",
69 | "@overload",
70 | "if TYPE_CHECKING",
71 | "raise NotImplementedError",
72 | ]
73 |
74 | [tool.isort]
75 | profile = "black"
76 | known_first_party = ["govee_ble", "tests"]
77 |
78 | [tool.mypy]
79 | check_untyped_defs = true
80 | disallow_any_generics = true
81 | disallow_incomplete_defs = true
82 | disallow_untyped_defs = true
83 | mypy_path = "src/"
84 | no_implicit_optional = true
85 | show_error_codes = true
86 | warn_unreachable = true
87 | warn_unused_ignores = true
88 | exclude = [
89 | 'docs/.*',
90 | 'setup.py',
91 | ]
92 |
93 | [[tool.mypy.overrides]]
94 | module = "tests.*"
95 | allow_untyped_defs = true
96 |
97 | [[tool.mypy.overrides]]
98 | module = "docs.*"
99 | ignore_errors = true
100 |
101 | [build-system]
102 | requires = ["poetry-core>=2.0.0"]
103 | build-backend = "poetry.core.masonry.api"
104 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Govee BLE
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 | Manage Govee BLE devices
34 |
35 | ## Installation
36 |
37 | Install this via pip (or your favourite package manager):
38 |
39 | `pip install govee-ble`
40 |
41 | ## Contributors ✨
42 |
43 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
53 |
54 | ## Credits
55 |
56 | This package was created with
57 | [Cookiecutter](https://github.com/audreyr/cookiecutter) and the
58 | [browniebroke/cookiecutter-pypackage](https://github.com/browniebroke/cookiecutter-pypackage)
59 | project template.
60 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Contributions are welcome, and they are greatly appreciated! Every little helps, and credit will always be given.
4 |
5 | You can contribute in many ways:
6 |
7 | ## Types of Contributions
8 |
9 | ### Report Bugs
10 |
11 | Report bugs to [our issue page][gh-issues]. If you are reporting a bug, please include:
12 |
13 | - Your operating system name and version.
14 | - Any details about your local setup that might be helpful in troubleshooting.
15 | - Detailed steps to reproduce the bug.
16 |
17 | ### Fix Bugs
18 |
19 | Look through the GitHub issues for bugs. Anything tagged with "bug" and "help wanted" is open to whoever wants to implement it.
20 |
21 | ### Implement Features
22 |
23 | Look through the GitHub issues for features. Anything tagged with "enhancement" and "help wanted" is open to whoever wants to implement it.
24 |
25 | ### Write Documentation
26 |
27 | Govee BLE could always use more documentation, whether as part of the official Govee BLE docs, in docstrings, or even on the web in blog posts, articles, and such.
28 |
29 | ### Submit Feedback
30 |
31 | The best way to send feedback [our issue page][gh-issues] on GitHub. If you are proposing a feature:
32 |
33 | - Explain in detail how it would work.
34 | - Keep the scope as narrow as possible, to make it easier to implement.
35 | - Remember that this is a volunteer-driven project, and that contributions are welcome 😊
36 |
37 | ## Get Started!
38 |
39 | Ready to contribute? Here's how to set yourself up for local development.
40 |
41 | 1. Fork the repo on GitHub.
42 |
43 | 2. Clone your fork locally:
44 |
45 | ```shell
46 | $ git clone git@github.com:your_name_here/govee-ble.git
47 | ```
48 |
49 | 3. Install the project dependencies with [Poetry](https://python-poetry.org):
50 |
51 | ```shell
52 | $ poetry install
53 | ```
54 |
55 | 4. Create a branch for local development:
56 |
57 | ```shell
58 | $ git checkout -b name-of-your-bugfix-or-feature
59 | ```
60 |
61 | Now you can make your changes locally.
62 |
63 | 5. When you're done making changes, check that your changes pass our tests:
64 |
65 | ```shell
66 | $ poetry run pytest
67 | ```
68 |
69 | 6. Linting is done through [pre-commit](https://pre-commit.com). Provided you have the tool installed globally, you can run them all as one-off:
70 |
71 | ```shell
72 | $ pre-commit run -a
73 | ```
74 |
75 | Or better, install the hooks once and have them run automatically each time you commit:
76 |
77 | ```shell
78 | $ pre-commit install
79 | ```
80 |
81 | 7. Commit your changes and push your branch to GitHub:
82 |
83 | ```shell
84 | $ git add .
85 | $ git commit -m "feat(something): your detailed description of your changes"
86 | $ git push origin name-of-your-bugfix-or-feature
87 | ```
88 |
89 | Note: the commit message should follow [the conventional commits](https://www.conventionalcommits.org). We run [`commitlint` on CI](https://github.com/marketplace/actions/commit-linter) to validate it, and if you've installed pre-commit hooks at the previous step, the message will be checked at commit time.
90 |
91 | 8. Submit a pull request through the GitHub website or using the GitHub CLI (if you have it installed):
92 |
93 | ```shell
94 | $ gh pr create --fill
95 | ```
96 |
97 | ## Pull Request Guidelines
98 |
99 | We like to have the pull request open as soon as possible, that's a great place to discuss any piece of work, even unfinished. You can use draft pull request if it's still a work in progress. Here are a few guidelines to follow:
100 |
101 | 1. Include tests for feature or bug fixes.
102 | 2. Update the documentation for significant features.
103 | 3. Ensure tests are passing on CI.
104 |
105 | ## Tips
106 |
107 | To run a subset of tests:
108 |
109 | ```shell
110 | $ pytest tests
111 | ```
112 |
113 | ## Making a new release
114 |
115 | The deployment should be automated and can be triggered from the Semantic Release workflow in GitHub. The next version will be based on [the commit logs](https://python-semantic-release.readthedocs.io/en/latest/commit-log-parsing.html#commit-log-parsing). This is done by [python-semantic-release](https://python-semantic-release.readthedocs.io/en/latest/index.html) via a GitHub action.
116 |
117 | [gh-issues]: https://github.com/bluetooth-devices/govee-ble/issues
118 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright 2022 J. Nick Koston
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/src/govee_ble/parser.py:
--------------------------------------------------------------------------------
1 | """
2 | Parser for Govee BLE advertisements.
3 |
4 | This file is shamelessly copied from the following repository:
5 | https://github.com/Ernst79/bleparser/blob/c42ae922e1abed2720c7fac993777e1bd59c0c93/package/bleparser/govee.py
6 |
7 | MIT License applies.
8 | """
9 |
10 | from __future__ import annotations
11 |
12 | import logging
13 | import struct
14 | from dataclasses import dataclass
15 | from enum import Enum
16 |
17 | from bluetooth_data_tools import short_address
18 | from bluetooth_sensor_state_data import BluetoothData
19 | from home_assistant_bluetooth import BluetoothServiceInfo
20 | from sensor_state_data import BinarySensorDeviceClass, SensorLibrary
21 |
22 | from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
23 |
24 | _LOGGER = logging.getLogger(__name__)
25 |
26 |
27 | PACKED_hHB_LITTLE = struct.Struct("hHB")
29 | PACKED_hh = struct.Struct(">hh")
30 | PACKED_hhhchhh_LITTLE = struct.Struct("hhhh")
33 | PACKED_hhbhh = struct.Struct(">hhbhh")
34 | PACKED_hhhhh = struct.Struct(">hhhhh")
35 | PACKED_hhhhhh = struct.Struct(">hhhhhh")
36 |
37 |
38 | ERROR = "error"
39 |
40 | MIN_TEMP = -40
41 | MAX_TEMP = 100
42 |
43 | NOT_GOVEE_MANUFACTURER = {76}
44 |
45 | PROBE_MAPPING_1_2 = [1, 2]
46 | PROBE_MAPPING_3_4 = [3, 4]
47 |
48 | FOUR_PROBES_MAPPING = dict.fromkeys(
49 | (1, 65, 129, 193), PROBE_MAPPING_1_2
50 | ) | dict.fromkeys((2, 66, 130, 194), PROBE_MAPPING_3_4)
51 |
52 | SIX_PROBES_MAPPING = {
53 | 0: [[1, 0x01], [2, 0x02]],
54 | 64: [[3, 0x04], [4, 0x08]],
55 | 128: [[5, 0x10], [6, 0x20]],
56 | }
57 |
58 |
59 | def decode_temp_humid_battery_error(data: bytes) -> tuple[float, float, int, bool]:
60 | temp, humi = decode_temp_humid(data[0:3])
61 | batt = int(data[-1] & 0x7F)
62 | err = bool(data[-1] & 0x80)
63 | return temp, humi, batt, err
64 |
65 |
66 | def decode_temp_humid(temp_humid_bytes: bytes) -> tuple[float, float]:
67 | """Decode potential negative temperatures."""
68 | base_num = (
69 | (temp_humid_bytes[0] << 16) + (temp_humid_bytes[1] << 8) + temp_humid_bytes[2]
70 | )
71 | is_negative = base_num & 0x800000
72 | temp_as_int = base_num & 0x7FFFFF
73 | temp_as_float = int(temp_as_int / 1000) / 10.0
74 | if is_negative:
75 | temp_as_float = -temp_as_float
76 | humid = (temp_as_int % 1000) / 10.0
77 | return temp_as_float, humid
78 |
79 |
80 | def decode_temps_probes(packet_value: int) -> float:
81 | """Filter potential negative temperatures."""
82 | if packet_value < 0:
83 | return 0.0
84 | return float(packet_value / 100)
85 |
86 |
87 | def decode_temps_probes_none(packet_value: int) -> float | None:
88 | """Filter potential negative temperatures."""
89 | if packet_value < 0:
90 | return None
91 | return float(packet_value)
92 |
93 |
94 | def hex(data: bytes) -> str:
95 | """Return a string object containing two hexadecimal digits for each byte in the instance."""
96 | return "b'{}'".format("".join(f"\\x{b:02x}" for b in data))
97 |
98 |
99 | def decode_temps_from_4_bytes(packet_value: int) -> float:
100 | """Decode temperature values (to one decimal place)."""
101 | if packet_value & 0x80000000:
102 | # Handle freezing temperatures
103 | packet_value &= 0x7FFFFFFF
104 | return float(int(packet_value / -10000000) / -10)
105 | return float(int(packet_value / 1000000) / 10)
106 |
107 |
108 | def decode_humi_from_4_bytes(packet_value: int) -> float:
109 | """Decode humidity values (to one decimal place)"""
110 | packet_value &= 0x7FFFFFFF
111 | return float(int((packet_value % 1000000) / 1000) / 10)
112 |
113 |
114 | def decode_pm25_from_4_bytes(packet_value: int) -> int:
115 | """Decode humidity values"""
116 | packet_value &= 0x7FFFFFFF
117 | return int(packet_value % 1000)
118 |
119 |
120 | def calculate_crc(data: bytes) -> int:
121 | crc = 0x1D0F
122 | for b in data:
123 | for s in range(7, -1, -1):
124 | mask = 0
125 | if (crc >> 15) ^ (b >> s) & 1:
126 | mask = 0x1021
127 | crc = ((crc << 1) ^ mask) & 0xFFFF
128 | return crc
129 |
130 |
131 | def decrypt_data(key: bytes, data: bytes) -> bytes:
132 | cipher = Cipher(algorithms.AES(key[::-1]), modes.ECB())
133 | decryptor = cipher.decryptor()
134 | return (decryptor.update(data[::-1]) + decryptor.finalize())[::-1]
135 |
136 |
137 | class SensorType(Enum):
138 | THERMOMETER = "thermometer"
139 | BUTTON = "button"
140 | MOTION = "motion"
141 | WINDOW = "window"
142 | VIBRATION = "vibration"
143 | PRESENCE = "presence"
144 | PRESSURE = "pressure"
145 |
146 |
147 | @dataclass
148 | class ModelInfo:
149 | """Model information for Govee sensors."""
150 |
151 | model_id: str
152 | sensor_type: SensorType
153 | button_count: int
154 | sleepy: bool
155 |
156 |
157 | _MODEL_DB = {
158 | "H5121": ModelInfo("H5121", SensorType.MOTION, 0, True),
159 | "H5122": ModelInfo("H5122", SensorType.BUTTON, 1, True),
160 | "H5123": ModelInfo("H5123", SensorType.WINDOW, 0, True),
161 | "H5124": ModelInfo("H5124", SensorType.VIBRATION, 0, True),
162 | "H5125": ModelInfo("H5125", SensorType.BUTTON, 6, True),
163 | "H5126": ModelInfo("H5126", SensorType.BUTTON, 2, True),
164 | "H5127": ModelInfo("H5127", SensorType.PRESENCE, 0, True),
165 | "H5130": ModelInfo("H5130", SensorType.PRESSURE, 1, True),
166 | }
167 |
168 |
169 | def get_model_info(model_id: str) -> ModelInfo:
170 | """Get model information for a Govee sensor."""
171 | return _MODEL_DB.get(
172 | model_id, ModelInfo(model_id, SensorType.THERMOMETER, 0, False)
173 | )
174 |
175 |
176 | class GoveeBluetoothDeviceData(BluetoothData):
177 | """Data for Govee BLE sensors."""
178 |
179 | def _start_update(self, service_info: BluetoothServiceInfo) -> None:
180 | """Update from BLE advertisement data."""
181 | _LOGGER.debug("Parsing Govee BLE advertisement data: %s", service_info)
182 | manufacturer_data = service_info.manufacturer_data
183 | service_uuids = service_info.service_uuids
184 | local_name = service_info.name
185 | address = service_info.address
186 | self.set_device_manufacturer("Govee")
187 |
188 | if local_name.startswith("Govee_"):
189 | self.set_device_name(service_info.name[6:].replace("_", " "))
190 |
191 | if local_name.startswith("GV"):
192 | self.set_device_name(service_info.name[2:].replace("_", " "))
193 | self.set_precision(2)
194 |
195 | for mfr_id, mfr_data in manufacturer_data.items():
196 | if mfr_id in NOT_GOVEE_MANUFACTURER:
197 | continue
198 | self._process_mfr_data(address, local_name, mfr_id, mfr_data, service_uuids)
199 |
200 | @property
201 | def device_type(self) -> str | None:
202 | """Return the device type."""
203 | primary_device_id = self.primary_device_id
204 | if device_type := self._device_id_to_type.get(primary_device_id):
205 | return device_type.partition("-")[0]
206 | return None
207 |
208 | @property
209 | def button_count(self) -> int:
210 | """Return the number of buttons on the device."""
211 | device_type = self.device_type
212 | assert device_type is not None
213 | return get_model_info(device_type).button_count
214 |
215 | @property
216 | def sensor_type(self) -> SensorType:
217 | """Return the sensor type."""
218 | device_type = self.device_type
219 | assert device_type is not None
220 | return get_model_info(device_type).sensor_type
221 |
222 | @property
223 | def sleepy(self) -> bool:
224 | """Return if the device is sleep."""
225 | device_type = self.device_type
226 | assert device_type is not None
227 | return get_model_info(device_type).sleepy
228 |
229 | def _process_mfr_data(
230 | self,
231 | address: str,
232 | local_name: str,
233 | mgr_id: int,
234 | data: bytes,
235 | service_uuids: list[str],
236 | ) -> None:
237 | """Parser for Govee sensors."""
238 | if debug_logging := _LOGGER.isEnabledFor(logging.DEBUG):
239 | _LOGGER.debug("Parsing Govee sensor: %s %s", mgr_id, hex(data))
240 | msg_length = len(data)
241 | if msg_length > 25 and b"INTELLI_ROCKS" in data:
242 | # INTELLI_ROCKS sometimes ends up glued on to the end of the message
243 | data = data[:-25]
244 | msg_length = len(data)
245 | if debug_logging:
246 | _LOGGER.debug("Cleaned up packet: %s %s", mgr_id, data.hex())
247 |
248 | if msg_length == 24:
249 | time_ms = data[2:6]
250 | enc_data = data[6:22]
251 | enc_crc = data[22:24]
252 | if not calculate_crc(enc_data) == int.from_bytes(enc_crc, "big"):
253 | _LOGGER.debug("CRC check failed for H512/3x: %s", hex(data))
254 | return
255 |
256 | key = time_ms + bytes(12)
257 | try:
258 | decrypted = decrypt_data(key, enc_data)
259 | except ValueError:
260 | _LOGGER.warning("Failed to decrypt H512/3x: %s", hex(data))
261 | return
262 | _LOGGER.debug("Decrypted H512/3x: %s - %s", decrypted, decrypted.hex())
263 | model_id = decrypted[2]
264 | # GV5121
265 | # 01040302640100000000000000000000
266 |
267 | # GV5122
268 | # 01050802640000000000000000000000
269 | # 01050802640000000000000000000000
270 |
271 | # GV5123
272 | # 01050202640200000000000000000000
273 |
274 | # GV5124
275 | # 01030902640100000000000000000000
276 |
277 | # GV5125
278 | # 01010a02640000000000000000000000
279 |
280 | # GV5126
281 | # 01010b02640100000000000000000000
282 |
283 | # GV5130
284 | # 010e0d02640000000000000000000000
285 | sensor_type = SensorType.BUTTON
286 | if "GV5121" in local_name or model_id == 3:
287 | self.set_device_type("H5121")
288 | self.set_device_name(f"5121{short_address(address)}")
289 | sensor_type = SensorType.MOTION
290 | elif "GV5122" in local_name or model_id == 8:
291 | self.set_device_type("H5122")
292 | self.set_device_name(f"5122{short_address(address)}")
293 | elif "GV5123" in local_name or model_id == 2:
294 | self.set_device_type("H5123")
295 | self.set_device_name(f"5123{short_address(address)}")
296 | sensor_type = SensorType.WINDOW
297 | elif "GV5124" in local_name or model_id == 9:
298 | self.set_device_type("H5124")
299 | self.set_device_name(f"5124{short_address(address)}")
300 | sensor_type = SensorType.VIBRATION
301 | elif "GV5125" in local_name or model_id == 10:
302 | self.set_device_type("H5125")
303 | self.set_device_name(f"5125{short_address(address)}")
304 | elif "GV5126" in local_name or model_id == 11:
305 | self.set_device_type("H5126")
306 | self.set_device_name(f"5126{short_address(address)}")
307 | elif "GV5130" in local_name or model_id == 13:
308 | self.set_device_type("H5130")
309 | self.set_device_name(f"5130{short_address(address)}")
310 | sensor_type = SensorType.PRESSURE
311 | else:
312 | return
313 |
314 | battery_percentage = decrypted[4]
315 | button_number_pressed = decrypted[5]
316 | self.update_predefined_sensor(
317 | SensorLibrary.BATTERY__PERCENTAGE, battery_percentage
318 | )
319 | if sensor_type is SensorType.WINDOW:
320 | # H5123 is a door/window sensor
321 | self.update_predefined_binary_sensor(
322 | BinarySensorDeviceClass.WINDOW, button_number_pressed == 2
323 | )
324 | elif sensor_type is SensorType.VIBRATION:
325 | # H5124 is a vibration sensor
326 | if button_number_pressed == 1:
327 | self.fire_event("vibration", "vibration")
328 | elif sensor_type is SensorType.MOTION:
329 | if button_number_pressed == 1:
330 | self.fire_event("motion", "motion")
331 | elif sensor_type is SensorType.PRESSURE:
332 | # H5130 is a pressure sensor
333 | if button_number_pressed == 16:
334 | self.fire_event("button_0", "press")
335 | else:
336 | self.update_predefined_binary_sensor(
337 | BinarySensorDeviceClass.PRESENCE, button_number_pressed == 1
338 | )
339 | else:
340 | self.fire_event(f"button_{button_number_pressed}", "press")
341 | return
342 |
343 | if msg_length == 6 and (
344 | (data.startswith(b"\xec\x00\x01\x01") and "H5127" in local_name)
345 | or mgr_id == 0x8803
346 | ):
347 | self.set_device_type("H5127")
348 | self.set_device_name(f"H5127{short_address(address)}")
349 | present = data[4] == 1
350 | motion = data[5] == 17
351 | self.update_predefined_binary_sensor(
352 | BinarySensorDeviceClass.OCCUPANCY, present
353 | )
354 | self.update_predefined_binary_sensor(BinarySensorDeviceClass.MOTION, motion)
355 |
356 | if msg_length == 6 and (
357 | (is_5072 := "H5072" in local_name)
358 | or (is_5075 := "H5075" in local_name)
359 | or mgr_id == 0xEC88
360 | ):
361 | if is_5072:
362 | self.set_device_type("H5072")
363 | elif is_5075:
364 | self.set_device_type("H5075")
365 | else:
366 | self.set_device_type("H5072/H5075")
367 | temp, humi, batt, err = decode_temp_humid_battery_error(data[1:5])
368 | if temp >= MIN_TEMP and temp <= MAX_TEMP and not err:
369 | self.update_predefined_sensor(SensorLibrary.TEMPERATURE__CELSIUS, temp)
370 | self.update_predefined_sensor(SensorLibrary.HUMIDITY__PERCENTAGE, humi)
371 | else:
372 | _LOGGER.debug(
373 | "Ignoring invalid sensor values, temperature: %.1f, humidity: %.1f, error: %s",
374 | temp,
375 | humi,
376 | err,
377 | )
378 | self.update_predefined_sensor(SensorLibrary.TEMPERATURE__CELSIUS, ERROR)
379 | self.update_predefined_sensor(SensorLibrary.HUMIDITY__PERCENTAGE, ERROR)
380 | self.update_predefined_sensor(SensorLibrary.BATTERY__PERCENTAGE, batt)
381 | return
382 |
383 | if msg_length in (6, 8) and (
384 | (is_5108 := "H5108" in local_name)
385 | or (is_5100 := "H5100" in local_name)
386 | or (is_5101 := "H5101" in local_name)
387 | or (is_5102 := "H5102" in local_name)
388 | or (is_5103 := "H5103" in local_name)
389 | or (is_5104 := "H5104" in local_name)
390 | or (is_5105 := "H5105" in local_name)
391 | or (is_5174 := "H5174" in local_name)
392 | or (is_5177 := "H5177" in local_name)
393 | or (is_5110 := "H5110" in local_name)
394 | or (is_5179 := "GV5179" in local_name)
395 | or (mgr_id == 0x0001 and msg_length == 8)
396 | ):
397 | if is_5108 or msg_length == 8:
398 | self.set_device_type("H5108")
399 | elif is_5100:
400 | self.set_device_type("H5100")
401 | elif is_5101:
402 | self.set_device_type("H5101")
403 | elif is_5102:
404 | self.set_device_type("H5102")
405 | elif is_5103:
406 | self.set_device_type("H5103")
407 | elif is_5104:
408 | self.set_device_type("H5104")
409 | elif is_5105:
410 | self.set_device_type("H5105")
411 | elif is_5174:
412 | self.set_device_type("H5174")
413 | elif is_5177:
414 | self.set_device_type("H5177")
415 | elif is_5110:
416 | self.set_device_type("H5110")
417 | elif is_5179:
418 | self.set_device_type("GV5179")
419 | else:
420 | self.set_device_type("H5101/H5102/H5104/H5108/H5174/H5177/GV5179")
421 | temp, humi, batt, err = decode_temp_humid_battery_error(data[2:6])
422 | if temp >= MIN_TEMP and temp <= MAX_TEMP and not err:
423 | self.update_predefined_sensor(SensorLibrary.TEMPERATURE__CELSIUS, temp)
424 | self.update_predefined_sensor(SensorLibrary.HUMIDITY__PERCENTAGE, humi)
425 | else:
426 | _LOGGER.debug(
427 | "Ignoring invalid sensor values, temperature: %.1f, humidity: %.1f, error: %s",
428 | temp,
429 | humi,
430 | err,
431 | )
432 | self.update_predefined_sensor(SensorLibrary.TEMPERATURE__CELSIUS, ERROR)
433 | self.update_predefined_sensor(SensorLibrary.HUMIDITY__PERCENTAGE, ERROR)
434 | self.update_predefined_sensor(SensorLibrary.BATTERY__PERCENTAGE, batt)
435 | return
436 |
437 | if msg_length == 7 and ("H5074" in local_name or mgr_id == 0xEC88):
438 | self.set_device_type("H5074")
439 | (temp, humi, batt) = PACKED_hHB_LITTLE.unpack(data[1:6])
440 | self.update_predefined_sensor(
441 | SensorLibrary.TEMPERATURE__CELSIUS, temp / 100
442 | )
443 | self.update_predefined_sensor(
444 | SensorLibrary.HUMIDITY__PERCENTAGE, humi / 100
445 | )
446 | self.update_predefined_sensor(SensorLibrary.BATTERY__PERCENTAGE, batt)
447 | return
448 |
449 | if msg_length == 9 and (
450 | mgr_id == 0xEC88
451 | or "H5051" in local_name
452 | or "H5052" in local_name
453 | or "H5071" in local_name
454 | ):
455 | if "H5071" in local_name:
456 | self.set_device_type("H5071")
457 | elif "H5052" in local_name:
458 | self.set_device_type("H5052")
459 | else:
460 | self.set_device_type("H5051")
461 | self.set_device_name(f"H5051 {short_address(address)}")
462 | (temp, humi, batt) = PACKED_hHB_LITTLE.unpack(data[1:6])
463 | self.update_predefined_sensor(
464 | SensorLibrary.TEMPERATURE__CELSIUS, temp / 100
465 | )
466 | self.update_predefined_sensor(
467 | SensorLibrary.HUMIDITY__PERCENTAGE, humi / 100
468 | )
469 | self.update_predefined_sensor(SensorLibrary.BATTERY__PERCENTAGE, batt)
470 | return
471 |
472 | if msg_length == 9 and (
473 | "H5178" in local_name or "B5178" in local_name or mgr_id == 0x0001
474 | ):
475 | temp, humi, batt, err = decode_temp_humid_battery_error(data[3:7])
476 | sensor_id = data[2]
477 | device_id = "primary"
478 | if local_name.startswith("H5178") or local_name.startswith("B5178"):
479 | self.set_title(local_name)
480 | else:
481 | self.set_title("H5178")
482 | if sensor_id == 0:
483 | self.set_device_name(
484 | f"{local_name} Primary".replace("_", " "), device_id
485 | )
486 | self.set_device_type("H5178", device_id)
487 | self.set_device_manufacturer("Govee", device_id)
488 | elif sensor_id == 1:
489 | device_id = "remote"
490 | self.set_device_name(
491 | f"{local_name} Remote".replace("_", " "), device_id
492 | )
493 | self.set_device_type("H5178-REMOTE", device_id)
494 | self.set_device_manufacturer("Govee", device_id)
495 | elif debug_logging:
496 | _LOGGER.debug(
497 | "Unknown sensor id for Govee H5178,"
498 | " please report to the developers, data: %s",
499 | hex(data),
500 | )
501 | if temp >= MIN_TEMP and temp <= MAX_TEMP and not err:
502 | self.update_predefined_sensor(
503 | SensorLibrary.TEMPERATURE__CELSIUS, temp, device_id=device_id
504 | )
505 | self.update_predefined_sensor(
506 | SensorLibrary.HUMIDITY__PERCENTAGE, humi, device_id=device_id
507 | )
508 | else:
509 | _LOGGER.debug(
510 | "Ignoring invalid sensor values, temperature: %.1f, humidity: %.1f, error: %s",
511 | temp,
512 | humi,
513 | err,
514 | )
515 | self.update_predefined_sensor(
516 | SensorLibrary.TEMPERATURE__CELSIUS, ERROR, device_id=device_id
517 | )
518 | self.update_predefined_sensor(
519 | SensorLibrary.HUMIDITY__PERCENTAGE, ERROR, device_id=device_id
520 | )
521 | self.update_predefined_sensor(
522 | SensorLibrary.BATTERY__PERCENTAGE, batt, device_id=device_id
523 | )
524 | return
525 |
526 | if msg_length == 9 and ("H5179" in local_name or mgr_id == 0x8801):
527 | self.set_device_type("H5179")
528 | temp, humi, batt = PACKED_hHB_LITTLE.unpack(data[4:9])
529 | self.update_predefined_sensor(
530 | SensorLibrary.TEMPERATURE__CELSIUS, temp / 100
531 | )
532 | self.update_predefined_sensor(
533 | SensorLibrary.HUMIDITY__PERCENTAGE, humi / 100
534 | )
535 | self.update_predefined_sensor(SensorLibrary.BATTERY__PERCENTAGE, batt)
536 | return
537 |
538 | if msg_length == 14 and (
539 | "H5181" in local_name
540 | or mgr_id in {0xF861, 0x388A, 0xEA42, 0xAAA2, 0xD14B}
541 | or "00008151-0000-1000-8000-00805f9b34fb" in service_uuids
542 | ):
543 | self.set_device_type("H5181")
544 | self.set_device_name(f"H5181 {short_address(address)}")
545 | (temp_probe_1, temp_alarm_1) = PACKED_hh.unpack(data[8:12])
546 | self.update_temp_probe_with_alarm(
547 | decode_temps_probes(temp_probe_1), decode_temps_probes(temp_alarm_1), 1
548 | )
549 | return
550 |
551 | if msg_length == 17 and (
552 | "H5182" in local_name
553 | or mgr_id == 0x2730
554 | or "00008251-0000-1000-8000-00805f9b34fb" in service_uuids
555 | ):
556 | self.set_device_type("H5182")
557 | self.set_device_name(f"H5182 {short_address(address)}")
558 | (
559 | temp_probe_1,
560 | temp_alarm_1,
561 | _,
562 | temp_probe_2,
563 | temp_alarm_2,
564 | ) = PACKED_hhbhh.unpack(data[8:17])
565 | self.update_temp_probe_with_alarm(
566 | decode_temps_probes(temp_probe_1), decode_temps_probes(temp_alarm_1), 1
567 | )
568 | self.update_temp_probe_with_alarm(
569 | decode_temps_probes(temp_probe_2), decode_temps_probes(temp_alarm_2), 2
570 | )
571 | return
572 |
573 | if msg_length == 14 and (
574 | "H5183" in local_name
575 | or mgr_id in {0x67DD, 0xE02F, 0xF79F}
576 | or "00008351-0000-1000-8000-00805f9b34fb" in service_uuids
577 | ):
578 | self.set_device_type("H5183")
579 | self.set_device_name(f"H5183 {short_address(address)}")
580 | (temp_probe_1, temp_alarm_1) = PACKED_hh.unpack(data[8:12])
581 | self.update_temp_probe_with_alarm(
582 | decode_temps_probes(temp_probe_1), decode_temps_probes(temp_alarm_1), 1
583 | )
584 | return
585 |
586 | if msg_length == 17 and (
587 | "H5184" in local_name
588 | or mgr_id == 0x1B36
589 | or "00008451-0000-1000-8000-00805f9b34fb" in service_uuids
590 | ):
591 | sensor_id = data[6]
592 | self.set_device_type("H5184")
593 | self.set_device_name(f"H5184 {short_address(address)}")
594 | (
595 | temp_probe_first,
596 | temp_alarm_first,
597 | _,
598 | temp_probe_second,
599 | temp_alarm_second,
600 | ) = PACKED_hhbhh.unpack(data[8:17])
601 | if not (ids := FOUR_PROBES_MAPPING.get(sensor_id)):
602 | if debug_logging:
603 | _LOGGER.debug(
604 | "Unknown sensor id: %s for a H5184, data: %s",
605 | sensor_id,
606 | hex(data),
607 | )
608 | return
609 | self.update_temp_probe_with_alarm(
610 | decode_temps_probes(temp_probe_first),
611 | decode_temps_probes(temp_alarm_first),
612 | ids[0],
613 | )
614 | self.update_temp_probe_with_alarm(
615 | decode_temps_probes(temp_probe_second),
616 | decode_temps_probes(temp_alarm_second),
617 | ids[1],
618 | )
619 | return
620 |
621 | if msg_length == 20 and (
622 | "H5185" in local_name
623 | or mgr_id in (0x4A32, 0x332, 0x4C32)
624 | or "00008551-0000-1000-8000-00805f9b34fb" in service_uuids
625 | ):
626 | self.set_device_type("H5185")
627 | self.set_device_name(f"H5185 {short_address(address)}")
628 | (
629 | temp_probe_1,
630 | temp_alarm_1,
631 | _,
632 | temp_probe_2,
633 | temp_alarm_2,
634 | ) = PACKED_hhhhh.unpack(data[8:18])
635 | self.update_temp_probe_with_alarm(
636 | decode_temps_probes(temp_probe_1), decode_temps_probes(temp_alarm_1), 1
637 | )
638 | self.update_temp_probe_with_alarm(
639 | decode_temps_probes(temp_probe_2), decode_temps_probes(temp_alarm_2), 2
640 | )
641 | return
642 |
643 | if msg_length == 20 and (
644 | "H5191" in local_name
645 | or mgr_id == 0xAC63
646 | or "00009151-0000-1000-8000-00805f9b34fb" in service_uuids
647 | ):
648 | self.set_device_type("H5191")
649 | self.set_device_name(f"H5191 {short_address(address)}")
650 | (
651 | temp_probe_1,
652 | temp_alarm_1,
653 | _,
654 | temp,
655 | ) = PACKED_hhhh.unpack(data[8:16])
656 | self.update_temp_probe_with_alarm(
657 | decode_temps_probes(temp_probe_1), decode_temps_probes(temp_alarm_1), 1
658 | )
659 | self.update_predefined_sensor(
660 | SensorLibrary.TEMPERATURE__CELSIUS, temp / 100
661 | )
662 | return
663 |
664 | if msg_length == 20 and (
665 | "H5198" in local_name
666 | or mgr_id == 0x3022
667 | or "00009851-0000-1000-8000-00805f9b34fb" in service_uuids
668 | ):
669 | sensor_id = data[6]
670 | self.set_device_type("H5198")
671 | self.set_device_name(f"H5198 {short_address(address)}")
672 | (
673 | temp_probe_first,
674 | temp_alarm_first,
675 | low_temp_alarm_first,
676 | temp_probe_second,
677 | temp_alarm_second,
678 | low_temp_alarm_second,
679 | ) = PACKED_hhhhhh.unpack(data[8:20])
680 | if not (ids := FOUR_PROBES_MAPPING.get(sensor_id)):
681 | if debug_logging:
682 | _LOGGER.debug(
683 | "Unknown sensor id: %s for a H5198, data: %s",
684 | sensor_id,
685 | hex(data),
686 | )
687 | return
688 | self.update_temp_probe_with_alarm(
689 | decode_temps_probes(temp_probe_first),
690 | decode_temps_probes(temp_alarm_first),
691 | ids[0],
692 | decode_temps_probes(low_temp_alarm_first),
693 | )
694 | self.update_temp_probe_with_alarm(
695 | decode_temps_probes(temp_probe_second),
696 | decode_temps_probes(temp_alarm_second),
697 | ids[1],
698 | decode_temps_probes(low_temp_alarm_second),
699 | )
700 | return
701 |
702 | if msg_length == 20 and "00005550-0000-1000-8000-00805f9b34fb" in service_uuids:
703 | self.set_device_type("H5055")
704 | self.set_device_name(f"H5055 {short_address(address)}")
705 | (
706 | temp_probe_first,
707 | temp_min_first,
708 | temp_max_first,
709 | _,
710 | temp_probe_second,
711 | temp_min_second,
712 | temp_max_second,
713 | ) = PACKED_hhhchhh_LITTLE.unpack(data[5:18])
714 | sensor_ids = data[3]
715 | if not (pids := SIX_PROBES_MAPPING.get(sensor_ids & 0xC0)):
716 | if debug_logging:
717 | _LOGGER.debug(
718 | "Unknown sensor id: %s for a H5055, data: %s",
719 | sensor_ids,
720 | hex(data),
721 | )
722 | return
723 | if sensor_ids & pids[0][1]:
724 | self.update_temp_probe_with_alarm(
725 | temp_probe_first,
726 | decode_temps_probes_none(temp_max_first),
727 | pids[0][0],
728 | decode_temps_probes_none(temp_min_first),
729 | )
730 | if sensor_ids & pids[1][1]:
731 | self.update_temp_probe_with_alarm(
732 | temp_probe_second,
733 | decode_temps_probes_none(temp_max_second),
734 | pids[1][0],
735 | decode_temps_probes_none(temp_min_second),
736 | )
737 | batt = int(data[2] & 0x7F)
738 | self.update_predefined_sensor(SensorLibrary.BATTERY__PERCENTAGE, batt)
739 | return
740 |
741 | if msg_length == 6 and "H5106" in local_name:
742 | self.set_device_type("H5106")
743 | self.set_device_name(f"H5106 {short_address(address)}")
744 | packet_5106 = data[2:6].hex()
745 | four_bytes = int(packet_5106, 16)
746 | temp = decode_temps_from_4_bytes(four_bytes)
747 | humi = decode_humi_from_4_bytes(four_bytes)
748 | pm25 = decode_pm25_from_4_bytes(four_bytes)
749 | self.update_predefined_sensor(SensorLibrary.TEMPERATURE__CELSIUS, temp)
750 | self.update_predefined_sensor(SensorLibrary.HUMIDITY__PERCENTAGE, humi)
751 | self.update_predefined_sensor(
752 | SensorLibrary.PM25__CONCENTRATION_MICROGRAMS_PER_CUBIC_METER, pm25
753 | )
754 | return
755 |
756 | def update_temp_probe(self, temp: float, probe_id: int) -> None:
757 | """Update the temperature probe with the alarm temperature."""
758 | self.update_predefined_sensor(
759 | SensorLibrary.TEMPERATURE__CELSIUS,
760 | temp,
761 | key=f"temperature_probe_{probe_id}",
762 | name=f"Temperature Probe {probe_id}",
763 | )
764 |
765 | def update_temp_probe_with_alarm(
766 | self,
767 | temp: float,
768 | alarm_temp: float | None,
769 | probe_id: int,
770 | low_alarm_temp: float | None = None,
771 | ) -> None:
772 | """Update the temperature probe with the alarm temperature."""
773 | self.update_temp_probe(temp, probe_id)
774 | if alarm_temp is not None:
775 | self.update_predefined_sensor(
776 | SensorLibrary.TEMPERATURE__CELSIUS,
777 | alarm_temp,
778 | key=f"temperature_alarm_probe_{probe_id}",
779 | name=f"Temperature Alarm Probe {probe_id}",
780 | )
781 | if low_alarm_temp is not None:
782 | self.update_predefined_sensor(
783 | SensorLibrary.TEMPERATURE__CELSIUS,
784 | low_alarm_temp,
785 | key=f"low_temperature_alarm_probe_{probe_id}",
786 | name=f"Low Temperature Alarm Probe {probe_id}",
787 | )
788 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # CHANGELOG
2 |
3 |
4 | ## v0.45.0 (2025-08-14)
5 |
6 | ### Chores
7 |
8 | - Add more coverage for GVH5110 ([#170](https://github.com/Bluetooth-Devices/govee-ble/pull/170),
9 | [`44071f8`](https://github.com/Bluetooth-Devices/govee-ble/commit/44071f8b280319e0b69c3c51595c9d2ef8934a8c))
10 |
11 | - **deps**: Bump bluetooth-data-tools from 1.23.3 to 1.28.1
12 | ([#162](https://github.com/Bluetooth-Devices/govee-ble/pull/162),
13 | [`0489c2a`](https://github.com/Bluetooth-Devices/govee-ble/commit/0489c2a1db9da807db735c221c97df651a871d6c))
14 |
15 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
16 |
17 | - **deps**: Bump bluetooth-data-tools from 1.28.1 to 1.28.2
18 | ([#179](https://github.com/Bluetooth-Devices/govee-ble/pull/179),
19 | [`57e45a5`](https://github.com/Bluetooth-Devices/govee-ble/commit/57e45a5dde203a0285c32a5096eb2ed6c0c08944))
20 |
21 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
22 |
23 | - **deps**: Bump bluetooth-sensor-state-data from 1.7.1 to 1.7.5
24 | ([#156](https://github.com/Bluetooth-Devices/govee-ble/pull/156),
25 | [`620b44f`](https://github.com/Bluetooth-Devices/govee-ble/commit/620b44fcf1ee8bfced833da0555a34e30b8c023f))
26 |
27 | - **deps**: Bump cryptography from 44.0.0 to 44.0.1
28 | ([#155](https://github.com/Bluetooth-Devices/govee-ble/pull/155),
29 | [`18d0edf`](https://github.com/Bluetooth-Devices/govee-ble/commit/18d0edf47baa593765ec3fb59ec2d88737581be7))
30 |
31 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
32 |
33 | - **deps**: Bump cryptography from 44.0.1 to 44.0.2
34 | ([#159](https://github.com/Bluetooth-Devices/govee-ble/pull/159),
35 | [`cc525de`](https://github.com/Bluetooth-Devices/govee-ble/commit/cc525decab60271826bcd36226b662f96d5bc032))
36 |
37 | - **deps**: Bump cryptography from 44.0.2 to 44.0.3
38 | ([#164](https://github.com/Bluetooth-Devices/govee-ble/pull/164),
39 | [`4ed69e1`](https://github.com/Bluetooth-Devices/govee-ble/commit/4ed69e16c410832a45c28d52caefc2c2f4e655c2))
40 |
41 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
42 |
43 | - **deps**: Bump cryptography from 44.0.3 to 45.0.2
44 | ([#167](https://github.com/Bluetooth-Devices/govee-ble/pull/167),
45 | [`a94ccce`](https://github.com/Bluetooth-Devices/govee-ble/commit/a94ccce1618eccd44334d3af499b262a5accdcee))
46 |
47 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
48 |
49 | - **deps**: Bump cryptography from 45.0.2 to 45.0.3
50 | ([#168](https://github.com/Bluetooth-Devices/govee-ble/pull/168),
51 | [`ef97655`](https://github.com/Bluetooth-Devices/govee-ble/commit/ef9765529ec403f688cb40e3d797dec151d2ccf0))
52 |
53 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
54 |
55 | - **deps**: Bump cryptography from 45.0.3 to 45.0.5
56 | ([#177](https://github.com/Bluetooth-Devices/govee-ble/pull/177),
57 | [`190e57c`](https://github.com/Bluetooth-Devices/govee-ble/commit/190e57cadb1beb4759c83ded460495e2bc9956c9))
58 |
59 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
60 |
61 | - **deps**: Bump cryptography from 45.0.5 to 45.0.6
62 | ([#182](https://github.com/Bluetooth-Devices/govee-ble/pull/182),
63 | [`ddbce27`](https://github.com/Bluetooth-Devices/govee-ble/commit/ddbce27ee6d6d553a2747f63ae8064b048a57c2c))
64 |
65 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
66 |
67 | - **deps**: Bump jinja2 from 3.1.5 to 3.1.6
68 | ([#154](https://github.com/Bluetooth-Devices/govee-ble/pull/154),
69 | [`a2fd9d1`](https://github.com/Bluetooth-Devices/govee-ble/commit/a2fd9d1afd2f4c3f1a5df7b35c2cf3e98c0e829d))
70 |
71 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
72 |
73 | - **deps**: Bump myst-parser from 3.0.1 to 4.0.1
74 | ([#158](https://github.com/Bluetooth-Devices/govee-ble/pull/158),
75 | [`9324b62`](https://github.com/Bluetooth-Devices/govee-ble/commit/9324b6295d3bbe3ba7cdce102254e30a6f2b8108))
76 |
77 | Bumps [myst-parser](https://github.com/executablebooks/MyST-Parser) from 3.0.1 to 4.0.1. - [Release
78 | notes](https://github.com/executablebooks/MyST-Parser/releases) -
79 | [Changelog](https://github.com/executablebooks/MyST-Parser/blob/master/CHANGELOG.md) -
80 | [Commits](https://github.com/executablebooks/MyST-Parser/compare/v3.0.1...v4.0.1)
81 |
82 | --- updated-dependencies: - dependency-name: myst-parser dependency-version: 4.0.1
83 |
84 | dependency-type: direct:production
85 |
86 | update-type: version-update:semver-major ...
87 |
88 | Signed-off-by: dependabot[bot]
89 |
90 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
91 |
92 | - **deps**: Bump requests from 2.32.3 to 2.32.4
93 | ([#172](https://github.com/Bluetooth-Devices/govee-ble/pull/172),
94 | [`1ef32dd`](https://github.com/Bluetooth-Devices/govee-ble/commit/1ef32dd4a9e617f04c277c734442e06e8727a369))
95 |
96 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
97 |
98 | - **deps**: Bump sensor-state-data from 2.18.1 to 2.19.0
99 | ([#180](https://github.com/Bluetooth-Devices/govee-ble/pull/180),
100 | [`42e09f6`](https://github.com/Bluetooth-Devices/govee-ble/commit/42e09f6fe6d404557db59420a504d6b438f3d737))
101 |
102 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
103 |
104 | - **deps**: Bump sphinx from 7.4.7 to 8.1.3
105 | ([#163](https://github.com/Bluetooth-Devices/govee-ble/pull/163),
106 | [`4c9d9c4`](https://github.com/Bluetooth-Devices/govee-ble/commit/4c9d9c48f80cc8cf71ceeb4ba8ee15ef55b90d31))
107 |
108 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
109 |
110 | - **deps**: Bump urllib3 from 2.3.0 to 2.5.0
111 | ([#175](https://github.com/Bluetooth-Devices/govee-ble/pull/175),
112 | [`4053e68`](https://github.com/Bluetooth-Devices/govee-ble/commit/4053e6812a7e5759f70d4095f58a1f68935d16a4))
113 |
114 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
115 |
116 | - **deps-dev**: Bump pytest from 8.3.4 to 8.3.5
117 | ([#157](https://github.com/Bluetooth-Devices/govee-ble/pull/157),
118 | [`ec2a87f`](https://github.com/Bluetooth-Devices/govee-ble/commit/ec2a87f8d071ce05db5f7b562309ee36aea54f06))
119 |
120 | - **deps-dev**: Bump pytest from 8.3.5 to 8.4.1
121 | ([#176](https://github.com/Bluetooth-Devices/govee-ble/pull/176),
122 | [`24bc49d`](https://github.com/Bluetooth-Devices/govee-ble/commit/24bc49d5f4e18c2f52993b27209952296692dd5f))
123 |
124 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
125 |
126 | - **deps-dev**: Bump pytest-cov from 6.0.0 to 6.1.1
127 | ([#160](https://github.com/Bluetooth-Devices/govee-ble/pull/160),
128 | [`3a38e71`](https://github.com/Bluetooth-Devices/govee-ble/commit/3a38e71ec342bf677abab7b546dc3ca2c00140ca))
129 |
130 | - **deps-dev**: Bump pytest-cov from 6.1.1 to 6.2.1
131 | ([#173](https://github.com/Bluetooth-Devices/govee-ble/pull/173),
132 | [`8c993c1`](https://github.com/Bluetooth-Devices/govee-ble/commit/8c993c1df8307e874b3c53ee3a5c74fe98c97d24))
133 |
134 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
135 |
136 | - **pre-commit.ci**: Pre-commit autoupdate
137 | ([#161](https://github.com/Bluetooth-Devices/govee-ble/pull/161),
138 | [`a0f7c41`](https://github.com/Bluetooth-Devices/govee-ble/commit/a0f7c4148449fb3815144dde71c73f7f4eb9a3c8))
139 |
140 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
141 |
142 | - **pre-commit.ci**: Pre-commit autoupdate
143 | ([#165](https://github.com/Bluetooth-Devices/govee-ble/pull/165),
144 | [`0a19fdf`](https://github.com/Bluetooth-Devices/govee-ble/commit/0a19fdf8bd6414144ed1c1cad539a226a9a8a843))
145 |
146 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
147 |
148 | - **pre-commit.ci**: Pre-commit autoupdate
149 | ([#166](https://github.com/Bluetooth-Devices/govee-ble/pull/166),
150 | [`3289ead`](https://github.com/Bluetooth-Devices/govee-ble/commit/3289ead82c96546fdab26e44349fed196360152c))
151 |
152 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
153 |
154 | - **pre-commit.ci**: Pre-commit autoupdate
155 | ([#178](https://github.com/Bluetooth-Devices/govee-ble/pull/178),
156 | [`a6d4ede`](https://github.com/Bluetooth-Devices/govee-ble/commit/a6d4ede722ec1e82d7f8fa68a0e51d0cb3c5f4d9))
157 |
158 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
159 |
160 | ### Features
161 |
162 | - Add support for H5191 ([#181](https://github.com/Bluetooth-Devices/govee-ble/pull/181),
163 | [`363f8e2`](https://github.com/Bluetooth-Devices/govee-ble/commit/363f8e286e208869bbcc41db7ff9ee5e99a87e65))
164 |
165 |
166 | ## v0.44.0 (2025-04-28)
167 |
168 | ### Chores
169 |
170 | - **ci**: Bump the github-actions group with 2 updates
171 | ([#144](https://github.com/Bluetooth-Devices/govee-ble/pull/144),
172 | [`29cab59`](https://github.com/Bluetooth-Devices/govee-ble/commit/29cab597fb7ae1790e698afe9188ef729de08bdc))
173 |
174 | Bumps the github-actions group with 2 updates:
175 | [python-semantic-release/python-semantic-release](https://github.com/python-semantic-release/python-semantic-release)
176 | and
177 | [python-semantic-release/publish-action](https://github.com/python-semantic-release/publish-action).
178 |
179 | Updates `python-semantic-release/python-semantic-release` from 9.17.0 to 9.21.0 - [Release
180 | notes](https://github.com/python-semantic-release/python-semantic-release/releases) -
181 | [Changelog](https://github.com/python-semantic-release/python-semantic-release/blob/master/CHANGELOG.rst)
182 | -
183 | [Commits](https://github.com/python-semantic-release/python-semantic-release/compare/v9.17.0...v9.21.0)
184 |
185 | Updates `python-semantic-release/publish-action` from 9.17.0 to 9.21.0 - [Release
186 | notes](https://github.com/python-semantic-release/publish-action/releases) -
187 | [Changelog](https://github.com/python-semantic-release/publish-action/blob/main/releaserc.toml) -
188 | [Commits](https://github.com/python-semantic-release/publish-action/compare/v9.17.0...v9.21.0)
189 |
190 | --- updated-dependencies: - dependency-name: python-semantic-release/python-semantic-release
191 | dependency-type: direct:production
192 |
193 | update-type: version-update:semver-minor
194 |
195 | dependency-group: github-actions
196 |
197 | - dependency-name: python-semantic-release/publish-action dependency-type: direct:production
198 |
199 | dependency-group: github-actions ...
200 |
201 | Signed-off-by: dependabot[bot]
202 |
203 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
204 |
205 | - **pre-commit.ci**: Pre-commit autoupdate
206 | ([#143](https://github.com/Bluetooth-Devices/govee-ble/pull/143),
207 | [`8758806`](https://github.com/Bluetooth-Devices/govee-ble/commit/87588061637edba85ef17ca90eb92df2544d0801))
208 |
209 | - **pre-commit.ci**: Pre-commit autoupdate
210 | ([#146](https://github.com/Bluetooth-Devices/govee-ble/pull/146),
211 | [`f224903`](https://github.com/Bluetooth-Devices/govee-ble/commit/f224903ad94662ecd68229ec7001db26e4bf0188))
212 |
213 | - **pre-commit.ci**: Pre-commit autoupdate
214 | ([#147](https://github.com/Bluetooth-Devices/govee-ble/pull/147),
215 | [`b434381`](https://github.com/Bluetooth-Devices/govee-ble/commit/b434381b21b477c40a7b0752fd0097b8f3f84490))
216 |
217 | updates: - [github.com/astral-sh/ruff-pre-commit: v0.11.0 →
218 | v0.11.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.11.0...v0.11.2)
219 |
220 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
221 |
222 | - **pre-commit.ci**: Pre-commit autoupdate
223 | ([#148](https://github.com/Bluetooth-Devices/govee-ble/pull/148),
224 | [`3d01fa8`](https://github.com/Bluetooth-Devices/govee-ble/commit/3d01fa8b868e508449131f80cb252323982aa367))
225 |
226 | updates: - [github.com/PyCQA/flake8: 7.1.2 →
227 | 7.2.0](https://github.com/PyCQA/flake8/compare/7.1.2...7.2.0)
228 |
229 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
230 |
231 | - **pre-commit.ci**: Pre-commit autoupdate
232 | ([#149](https://github.com/Bluetooth-Devices/govee-ble/pull/149),
233 | [`bde11e7`](https://github.com/Bluetooth-Devices/govee-ble/commit/bde11e75948b23b802ee66b9fa1fc217d17208d8))
234 |
235 | updates: - [github.com/commitizen-tools/commitizen: v4.4.1 →
236 | v4.5.0](https://github.com/commitizen-tools/commitizen/compare/v4.4.1...v4.5.0) -
237 | [github.com/astral-sh/ruff-pre-commit: v0.11.2 →
238 | v0.11.4](https://github.com/astral-sh/ruff-pre-commit/compare/v0.11.2...v0.11.4)
239 |
240 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
241 |
242 | - **pre-commit.ci**: Pre-commit autoupdate
243 | ([#150](https://github.com/Bluetooth-Devices/govee-ble/pull/150),
244 | [`d1fdcd3`](https://github.com/Bluetooth-Devices/govee-ble/commit/d1fdcd3e0b15645ee7228139e096b0767ba3c881))
245 |
246 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
247 |
248 | - **pre-commit.ci**: Pre-commit autoupdate
249 | ([#152](https://github.com/Bluetooth-Devices/govee-ble/pull/152),
250 | [`e6ffe35`](https://github.com/Bluetooth-Devices/govee-ble/commit/e6ffe35bb907fe6654fddd67eab95df097ff1566))
251 |
252 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
253 |
254 | ### Features
255 |
256 | - Add support for H5110 ([#153](https://github.com/Bluetooth-Devices/govee-ble/pull/153),
257 | [`9fd67ef`](https://github.com/Bluetooth-Devices/govee-ble/commit/9fd67ef312af0b602e7b94ef1594dc0fa772c9b8))
258 |
259 |
260 | ## v0.43.1 (2025-03-05)
261 |
262 | ### Bug Fixes
263 |
264 | - Change minimum temp to -40 ([#145](https://github.com/Bluetooth-Devices/govee-ble/pull/145),
265 | [`2f7360d`](https://github.com/Bluetooth-Devices/govee-ble/commit/2f7360de826527a2befb4a1942a9176776b6874c))
266 |
267 | ### Chores
268 |
269 | - **ci**: Bump the github-actions group with 8 updates
270 | ([#139](https://github.com/Bluetooth-Devices/govee-ble/pull/139),
271 | [`0bfccb1`](https://github.com/Bluetooth-Devices/govee-ble/commit/0bfccb1384eced110c498a3bcade7ea273ebd8d7))
272 |
273 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
274 |
275 | Co-authored-by: J. Nick Koston
276 |
277 | - **pre-commit.ci**: Pre-commit autoupdate
278 | ([#141](https://github.com/Bluetooth-Devices/govee-ble/pull/141),
279 | [`0cf81b4`](https://github.com/Bluetooth-Devices/govee-ble/commit/0cf81b46d0dc4b3a384d4928627fada6bea81fe8))
280 |
281 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
282 |
283 | - **pre-commit.ci**: Pre-commit autoupdate
284 | ([#142](https://github.com/Bluetooth-Devices/govee-ble/pull/142),
285 | [`48e5f0a`](https://github.com/Bluetooth-Devices/govee-ble/commit/48e5f0a0fcac604022bb2748b54b42941bf4cfdc))
286 |
287 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
288 |
289 |
290 | ## v0.43.0 (2025-02-06)
291 |
292 | ### Chores
293 |
294 | - Update dependabot.yml to include GHA
295 | ([#138](https://github.com/Bluetooth-Devices/govee-ble/pull/138),
296 | [`e83b35d`](https://github.com/Bluetooth-Devices/govee-ble/commit/e83b35dc52dda4b38f0e53f3ef235b358ac47260))
297 |
298 | ### Features
299 |
300 | - Add support for newer 5179 firmware
301 | ([#140](https://github.com/Bluetooth-Devices/govee-ble/pull/140),
302 | [`3d0f853`](https://github.com/Bluetooth-Devices/govee-ble/commit/3d0f8535a0ca1b7cf3fa4ed0b7d12c58c776dffb))
303 |
304 |
305 | ## v0.42.1 (2025-02-04)
306 |
307 | ### Bug Fixes
308 |
309 | - Update poetry to v2 + add license to metadata
310 | ([#137](https://github.com/Bluetooth-Devices/govee-ble/pull/137),
311 | [`e61a9cb`](https://github.com/Bluetooth-Devices/govee-ble/commit/e61a9cb4903215bfce3dca7efec140b3a21d6d0b))
312 |
313 | ### Chores
314 |
315 | - Add test data from ha issue 110528
316 | ([#128](https://github.com/Bluetooth-Devices/govee-ble/pull/128),
317 | [`c5baa25`](https://github.com/Bluetooth-Devices/govee-ble/commit/c5baa253d04f7080de0546779a9abc915eecb8c8))
318 |
319 | - Create dependabot.yml
320 | ([`3e55779`](https://github.com/Bluetooth-Devices/govee-ble/commit/3e55779b101a24d561544be654c79179a8d8a5ef))
321 |
322 | - Update CI for Python 3.13 ([#124](https://github.com/Bluetooth-Devices/govee-ble/pull/124),
323 | [`ddb0195`](https://github.com/Bluetooth-Devices/govee-ble/commit/ddb01959470f98c90c215998ff896e79c07199be))
324 |
325 | - Update deps for Python 3.13 ([#125](https://github.com/Bluetooth-Devices/govee-ble/pull/125),
326 | [`0b2ecbb`](https://github.com/Bluetooth-Devices/govee-ble/commit/0b2ecbbb36edc4aa54e4b9aeacb815450953400a))
327 |
328 | - **deps**: Bump bluetooth-data-tools from 1.22.0 to 1.23.3
329 | ([#135](https://github.com/Bluetooth-Devices/govee-ble/pull/135),
330 | [`fe74840`](https://github.com/Bluetooth-Devices/govee-ble/commit/fe74840c732046f143c825f04ffaa967c6f9af71))
331 |
332 | - **deps**: Bump cryptography from 42.0.8 to 44.0.0
333 | ([#122](https://github.com/Bluetooth-Devices/govee-ble/pull/122),
334 | [`9ec1fcf`](https://github.com/Bluetooth-Devices/govee-ble/commit/9ec1fcf5d992482cae297cf1f0671e51273c59f4))
335 |
336 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
337 |
338 | - **deps**: Bump jinja2 from 3.1.4 to 3.1.5
339 | ([#123](https://github.com/Bluetooth-Devices/govee-ble/pull/123),
340 | [`9cd5c5c`](https://github.com/Bluetooth-Devices/govee-ble/commit/9cd5c5c6642e4c29f21743222f11f4fef3e5fd83))
341 |
342 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
343 |
344 | - **deps**: Bump myst-parser from 0.18.1 to 1.0.0
345 | ([#119](https://github.com/Bluetooth-Devices/govee-ble/pull/119),
346 | [`9201df8`](https://github.com/Bluetooth-Devices/govee-ble/commit/9201df85046b4b4213ced94ffa5fd5f912efd8b8))
347 |
348 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
349 |
350 | - **deps**: Bump myst-parser from 1.0.0 to 3.0.1
351 | ([#131](https://github.com/Bluetooth-Devices/govee-ble/pull/131),
352 | [`4e70715`](https://github.com/Bluetooth-Devices/govee-ble/commit/4e7071563aa1e9d2f0c18cc85449f80e3dc02bc2))
353 |
354 | - **deps**: Bump sphinx from 5.3.0 to 6.2.1
355 | ([#126](https://github.com/Bluetooth-Devices/govee-ble/pull/126),
356 | [`4d9a98b`](https://github.com/Bluetooth-Devices/govee-ble/commit/4d9a98b1633dd237f82e5b455098433ec5034845))
357 |
358 | - **deps**: Bump sphinx from 6.2.1 to 7.4.7
359 | ([#134](https://github.com/Bluetooth-Devices/govee-ble/pull/134),
360 | [`8b32dd7`](https://github.com/Bluetooth-Devices/govee-ble/commit/8b32dd7d69031ffc356f86dbc502a274920ffbf4))
361 |
362 | - **deps**: Bump sphinx-rtd-theme from 1.3.0 to 2.0.0
363 | ([#120](https://github.com/Bluetooth-Devices/govee-ble/pull/120),
364 | [`ba94d1e`](https://github.com/Bluetooth-Devices/govee-ble/commit/ba94d1eafe9a7cd4eed4440cb9afd39f7996d108))
365 |
366 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
367 |
368 | - **deps**: Bump sphinx-rtd-theme from 2.0.0 to 3.0.2
369 | ([#132](https://github.com/Bluetooth-Devices/govee-ble/pull/132),
370 | [`2288823`](https://github.com/Bluetooth-Devices/govee-ble/commit/22888233d51b777a65195642907de30709dc942f))
371 |
372 | Bumps [sphinx-rtd-theme](https://github.com/readthedocs/sphinx_rtd_theme) from 2.0.0 to 3.0.2. -
373 | [Changelog](https://github.com/readthedocs/sphinx_rtd_theme/blob/master/docs/changelog.rst) -
374 | [Commits](https://github.com/readthedocs/sphinx_rtd_theme/compare/2.0.0...3.0.2)
375 |
376 | --- updated-dependencies: - dependency-name: sphinx-rtd-theme dependency-type: direct:production
377 |
378 | update-type: version-update:semver-major ...
379 |
380 | Signed-off-by: dependabot[bot]
381 |
382 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
383 |
384 | - **deps-dev**: Bump pytest from 7.4.4 to 8.3.4
385 | ([#118](https://github.com/Bluetooth-Devices/govee-ble/pull/118),
386 | [`e94e1fc`](https://github.com/Bluetooth-Devices/govee-ble/commit/e94e1fc854c5b22c0fe9d2ea85aa5c5afb72933d))
387 |
388 | Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
389 |
390 | - **deps-dev**: Bump pytest-cov from 3.0.0 to 6.0.0
391 | ([#121](https://github.com/Bluetooth-Devices/govee-ble/pull/121),
392 | [`ecbeb28`](https://github.com/Bluetooth-Devices/govee-ble/commit/ecbeb28e3f31f0395cdf24b9c6d908a269663817))
393 |
394 | - **pre-commit.ci**: Pre-commit autoupdate
395 | ([#127](https://github.com/Bluetooth-Devices/govee-ble/pull/127),
396 | [`90f701c`](https://github.com/Bluetooth-Devices/govee-ble/commit/90f701c6fdeb523a144f174fff8bd5361d1f9adf))
397 |
398 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
399 |
400 | - **pre-commit.ci**: Pre-commit autoupdate
401 | ([#133](https://github.com/Bluetooth-Devices/govee-ble/pull/133),
402 | [`882ad48`](https://github.com/Bluetooth-Devices/govee-ble/commit/882ad48343050d113bfc8f8d02009bdeaf57337a))
403 |
404 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
405 |
406 | - **pre-commit.ci**: Pre-commit autoupdate
407 | ([#136](https://github.com/Bluetooth-Devices/govee-ble/pull/136),
408 | [`8b0568f`](https://github.com/Bluetooth-Devices/govee-ble/commit/8b0568fe21e115e8a001771767c6a1f81b89252d))
409 |
410 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
411 |
412 | ### Refactoring
413 |
414 | - Reduce duplicate code ([#129](https://github.com/Bluetooth-Devices/govee-ble/pull/129),
415 | [`f265edd`](https://github.com/Bluetooth-Devices/govee-ble/commit/f265edd415371063720e1d027f912b9d16e6fd24))
416 |
417 | - Reduce duplicate code ([#130](https://github.com/Bluetooth-Devices/govee-ble/pull/130),
418 | [`e359472`](https://github.com/Bluetooth-Devices/govee-ble/commit/e35947253a35f51603fafbad1f155ab75b936d34))
419 |
420 |
421 | ## v0.42.0 (2025-01-16)
422 |
423 | ### Features
424 |
425 | - Add support for gvh5130 button ([#117](https://github.com/Bluetooth-Devices/govee-ble/pull/117),
426 | [`0d499db`](https://github.com/Bluetooth-Devices/govee-ble/commit/0d499db328c19b2403c5d0089224a3fc46300e56))
427 |
428 |
429 | ## v0.41.0 (2025-01-16)
430 |
431 | ### Chores
432 |
433 | - **pre-commit.ci**: Pre-commit autoupdate
434 | ([#103](https://github.com/Bluetooth-Devices/govee-ble/pull/103),
435 | [`c4f1937`](https://github.com/Bluetooth-Devices/govee-ble/commit/c4f19377053fd1213a0e0eaaa675f3850d9faf7b))
436 |
437 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
438 |
439 | - **pre-commit.ci**: Pre-commit autoupdate
440 | ([#104](https://github.com/Bluetooth-Devices/govee-ble/pull/104),
441 | [`a3e80b5`](https://github.com/Bluetooth-Devices/govee-ble/commit/a3e80b57dc896a7251c64d7e164ce90207fc3951))
442 |
443 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
444 |
445 | - **pre-commit.ci**: Pre-commit autoupdate
446 | ([#105](https://github.com/Bluetooth-Devices/govee-ble/pull/105),
447 | [`b31d39e`](https://github.com/Bluetooth-Devices/govee-ble/commit/b31d39ece0bb991b1ef92e8fb46ed32ea22e2202))
448 |
449 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
450 |
451 | - **pre-commit.ci**: Pre-commit autoupdate
452 | ([#106](https://github.com/Bluetooth-Devices/govee-ble/pull/106),
453 | [`be92194`](https://github.com/Bluetooth-Devices/govee-ble/commit/be921949f7162c6ed77421d690ec709f2c511024))
454 |
455 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
456 |
457 | - **pre-commit.ci**: Pre-commit autoupdate
458 | ([#107](https://github.com/Bluetooth-Devices/govee-ble/pull/107),
459 | [`2b0cb41`](https://github.com/Bluetooth-Devices/govee-ble/commit/2b0cb4162f4419045bfbec9b95f30a8cc4ce70c2))
460 |
461 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
462 |
463 | - **pre-commit.ci**: Pre-commit autoupdate
464 | ([#108](https://github.com/Bluetooth-Devices/govee-ble/pull/108),
465 | [`1d7da8c`](https://github.com/Bluetooth-Devices/govee-ble/commit/1d7da8c1fc19ad0dd2ed151492a2027780823b6f))
466 |
467 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
468 |
469 | - **pre-commit.ci**: Pre-commit autoupdate
470 | ([#109](https://github.com/Bluetooth-Devices/govee-ble/pull/109),
471 | [`7c0ccda`](https://github.com/Bluetooth-Devices/govee-ble/commit/7c0ccda3c9c8d661cc3c6cb3b7fca56b3c5fcc99))
472 |
473 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
474 |
475 | - **pre-commit.ci**: Pre-commit autoupdate
476 | ([#110](https://github.com/Bluetooth-Devices/govee-ble/pull/110),
477 | [`41d2374`](https://github.com/Bluetooth-Devices/govee-ble/commit/41d2374dd29d93dbf3a30ea0158503cf95cc34c2))
478 |
479 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
480 |
481 | - **pre-commit.ci**: Pre-commit autoupdate
482 | ([#112](https://github.com/Bluetooth-Devices/govee-ble/pull/112),
483 | [`5c0f0c1`](https://github.com/Bluetooth-Devices/govee-ble/commit/5c0f0c1ea3cb49a689a0e9c9c9288d815b0d6a3f))
484 |
485 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
486 |
487 | - **pre-commit.ci**: Pre-commit autoupdate
488 | ([#113](https://github.com/Bluetooth-Devices/govee-ble/pull/113),
489 | [`4b7d53d`](https://github.com/Bluetooth-Devices/govee-ble/commit/4b7d53dfc674495bbf4126faa3d1f704c69b040f))
490 |
491 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
492 |
493 | - **pre-commit.ci**: Pre-commit autoupdate
494 | ([#114](https://github.com/Bluetooth-Devices/govee-ble/pull/114),
495 | [`281c20b`](https://github.com/Bluetooth-Devices/govee-ble/commit/281c20b5fc56018aec1d30353794edf1553447d8))
496 |
497 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
498 |
499 | - **pre-commit.ci**: Pre-commit autoupdate
500 | ([#115](https://github.com/Bluetooth-Devices/govee-ble/pull/115),
501 | [`1d2dcaf`](https://github.com/Bluetooth-Devices/govee-ble/commit/1d2dcaf28ed11faa6455aded30b5eaae43e5b0ea))
502 |
503 | ### Features
504 |
505 | - Add support for H5130 Pressure sensor
506 | ([#116](https://github.com/Bluetooth-Devices/govee-ble/pull/116),
507 | [`5336114`](https://github.com/Bluetooth-Devices/govee-ble/commit/5336114250175ea92217e73d3b5c674e76ffbb2b))
508 |
509 |
510 | ## v0.40.0 (2024-07-24)
511 |
512 | ### Features
513 |
514 | - Add support for h5127 ([#101](https://github.com/Bluetooth-Devices/govee-ble/pull/101),
515 | [`5e84208`](https://github.com/Bluetooth-Devices/govee-ble/commit/5e8420811b07540999bdb8580f13653f2e413a21))
516 |
517 |
518 | ## v0.39.1 (2024-07-24)
519 |
520 | ### Bug Fixes
521 |
522 | - Vibration sensor is on only and should have been an event
523 | ([#100](https://github.com/Bluetooth-Devices/govee-ble/pull/100),
524 | [`142e7c5`](https://github.com/Bluetooth-Devices/govee-ble/commit/142e7c50bb6db8cdf3f9818c85645280b0bb25fc))
525 |
526 |
527 | ## v0.39.0 (2024-07-24)
528 |
529 | ### Chores
530 |
531 | - **pre-commit.ci**: Pre-commit autoupdate
532 | ([#98](https://github.com/Bluetooth-Devices/govee-ble/pull/98),
533 | [`69daf5f`](https://github.com/Bluetooth-Devices/govee-ble/commit/69daf5f24e6f30469eb020f43866f49394a2ba50))
534 |
535 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
536 |
537 | ### Features
538 |
539 | - Add support for h5124 vibration sensors
540 | ([#99](https://github.com/Bluetooth-Devices/govee-ble/pull/99),
541 | [`d88ffd6`](https://github.com/Bluetooth-Devices/govee-ble/commit/d88ffd62e0089b87831ed10b00782a642eca253e))
542 |
543 |
544 | ## v0.38.0 (2024-07-17)
545 |
546 | ### Features
547 |
548 | - Add support for binary sensors ([#97](https://github.com/Bluetooth-Devices/govee-ble/pull/97),
549 | [`ab22cdb`](https://github.com/Bluetooth-Devices/govee-ble/commit/ab22cdbc291ee95ad107003dad1d7ec001e1f63b))
550 |
551 |
552 | ## v0.37.0 (2024-07-16)
553 |
554 | ### Features
555 |
556 | - Add support for sleepy devices ([#96](https://github.com/Bluetooth-Devices/govee-ble/pull/96),
557 | [`bbe36fa`](https://github.com/Bluetooth-Devices/govee-ble/commit/bbe36fa862f022c5f0f47f42cbfddb3fe92f19a3))
558 |
559 |
560 | ## v0.36.1 (2024-07-16)
561 |
562 | ### Bug Fixes
563 |
564 | - Handle model not yet set ([#95](https://github.com/Bluetooth-Devices/govee-ble/pull/95),
565 | [`2083a01`](https://github.com/Bluetooth-Devices/govee-ble/commit/2083a01ecb102e1c9dd2292b898c22da8695b1d3))
566 |
567 |
568 | ## v0.36.0 (2024-07-16)
569 |
570 | ### Features
571 |
572 | - Expose ModelInfo ([#94](https://github.com/Bluetooth-Devices/govee-ble/pull/94),
573 | [`9111e16`](https://github.com/Bluetooth-Devices/govee-ble/commit/9111e16a6385258dd11b9756c2ed4d2cbdd7c50a))
574 |
575 |
576 | ## v0.35.1 (2024-07-16)
577 |
578 | ### Bug Fixes
579 |
580 | - Handle remote discovered first ([#93](https://github.com/Bluetooth-Devices/govee-ble/pull/93),
581 | [`ae375f6`](https://github.com/Bluetooth-Devices/govee-ble/commit/ae375f627d66fa505727f6da9388fd94b138b2be))
582 |
583 |
584 | ## v0.35.0 (2024-07-16)
585 |
586 | ### Features
587 |
588 | - Refactor to support get_model_info for offline devices
589 | ([#92](https://github.com/Bluetooth-Devices/govee-ble/pull/92),
590 | [`a12d139`](https://github.com/Bluetooth-Devices/govee-ble/commit/a12d139cd29b73bd17225958f13b534425f4f7e1))
591 |
592 |
593 | ## v0.34.0 (2024-07-16)
594 |
595 | ### Features
596 |
597 | - Add sensor type and button count ([#91](https://github.com/Bluetooth-Devices/govee-ble/pull/91),
598 | [`747dcb0`](https://github.com/Bluetooth-Devices/govee-ble/commit/747dcb091c2ff2234d2d3eccc39f551a09d5a878))
599 |
600 |
601 | ## v0.33.1 (2024-07-16)
602 |
603 | ### Bug Fixes
604 |
605 | - Remove unused device id code ([#90](https://github.com/Bluetooth-Devices/govee-ble/pull/90),
606 | [`a071f2e`](https://github.com/Bluetooth-Devices/govee-ble/commit/a071f2ecfd7b14d504cfdaee46e289e530383008))
607 |
608 |
609 | ## v0.33.0 (2024-07-16)
610 |
611 | ### Features
612 |
613 | - Add passive support for GV5121/GV5122/GV5123/GV5125/GV5126
614 | ([#89](https://github.com/Bluetooth-Devices/govee-ble/pull/89),
615 | [`83ac0d5`](https://github.com/Bluetooth-Devices/govee-ble/commit/83ac0d5950d420e35113c38a58553b413b27c1f8))
616 |
617 |
618 | ## v0.32.0 (2024-07-15)
619 |
620 | ### Chores
621 |
622 | - **pre-commit.ci**: Pre-commit autoupdate
623 | ([#87](https://github.com/Bluetooth-Devices/govee-ble/pull/87),
624 | [`d6e3cc4`](https://github.com/Bluetooth-Devices/govee-ble/commit/d6e3cc448e41d031544dbca0ba91f18fc6e76b6c))
625 |
626 | * chore(pre-commit.ci): pre-commit autoupdate
627 |
628 | updates: - [github.com/commitizen-tools/commitizen: v2.28.0 →
629 | v3.27.0](https://github.com/commitizen-tools/commitizen/compare/v2.28.0...v3.27.0) -
630 | [github.com/pre-commit/pre-commit-hooks: v4.3.0 →
631 | v4.6.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.3.0...v4.6.0) -
632 | [github.com/pre-commit/mirrors-prettier: v2.7.1 →
633 | v4.0.0-alpha.8](https://github.com/pre-commit/mirrors-prettier/compare/v2.7.1...v4.0.0-alpha.8) -
634 | [github.com/asottile/pyupgrade: v2.37.1 →
635 | v3.16.0](https://github.com/asottile/pyupgrade/compare/v2.37.1...v3.16.0) -
636 | [github.com/PyCQA/isort: 5.12.0 → 5.13.2](https://github.com/PyCQA/isort/compare/5.12.0...5.13.2)
637 | - [github.com/psf/black: 22.6.0 → 24.4.2](https://github.com/psf/black/compare/22.6.0...24.4.2) -
638 | [github.com/codespell-project/codespell: v2.1.0 →
639 | v2.3.0](https://github.com/codespell-project/codespell/compare/v2.1.0...v2.3.0) -
640 | [github.com/PyCQA/flake8: 4.0.1 → 7.1.0](https://github.com/PyCQA/flake8/compare/4.0.1...7.1.0) -
641 | [github.com/pre-commit/mirrors-mypy: v0.931 →
642 | v1.10.1](https://github.com/pre-commit/mirrors-mypy/compare/v0.931...v1.10.1) -
643 | [github.com/PyCQA/bandit: 1.7.4 → 1.7.9](https://github.com/PyCQA/bandit/compare/1.7.4...1.7.9)
644 |
645 | * chore(pre-commit.ci): auto fixes
646 |
647 | ---------
648 |
649 | Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
650 |
651 | ### Features
652 |
653 | - Add support for GV5121/GV5122/GV5123/GV5125/GV5126
654 | ([#88](https://github.com/Bluetooth-Devices/govee-ble/pull/88),
655 | [`e71ca98`](https://github.com/Bluetooth-Devices/govee-ble/commit/e71ca9897fc2de04adeb3c70a5777e52a3588c04))
656 |
657 |
658 | ## v0.31.3 (2024-06-24)
659 |
660 | ### Bug Fixes
661 |
662 | - Fix license classifier ([#86](https://github.com/Bluetooth-Devices/govee-ble/pull/86),
663 | [`88408cf`](https://github.com/Bluetooth-Devices/govee-ble/commit/88408cfe3c6d075718e0fdddbf7fed38c27e59f1))
664 |
665 |
666 | ## v0.31.2 (2024-04-25)
667 |
668 | ### Bug Fixes
669 |
670 | - Ryse smart shades where being detected as an h5106
671 | ([#85](https://github.com/Bluetooth-Devices/govee-ble/pull/85),
672 | [`509977f`](https://github.com/Bluetooth-Devices/govee-ble/commit/509977f0c1e309b496ebbae2f2f930b38548f2b0))
673 |
674 | ### Testing
675 |
676 | - Add more 5105 tests ([#84](https://github.com/Bluetooth-Devices/govee-ble/pull/84),
677 | [`94bfe57`](https://github.com/Bluetooth-Devices/govee-ble/commit/94bfe57af1d134805aede008459b7dfeb78e0597))
678 |
679 |
680 | ## v0.31.1 (2024-04-25)
681 |
682 | ### Bug Fixes
683 |
684 | - Show h5075 as h5075 instead of h5075/h5072
685 | ([#83](https://github.com/Bluetooth-Devices/govee-ble/pull/83),
686 | [`8fc22f7`](https://github.com/Bluetooth-Devices/govee-ble/commit/8fc22f7e4183341e02c38667ab830c9edeb27cd3))
687 |
688 |
689 | ## v0.31.0 (2024-01-31)
690 |
691 | ### Features
692 |
693 | - Add support for H5108 with external probe
694 | ([#82](https://github.com/Bluetooth-Devices/govee-ble/pull/82),
695 | [`46bccd8`](https://github.com/Bluetooth-Devices/govee-ble/commit/46bccd8a487dc736f4e75b6b584d8610e008c306))
696 |
697 |
698 | ## v0.30.0 (2024-01-31)
699 |
700 | ### Features
701 |
702 | - Add support for h5100 ([#81](https://github.com/Bluetooth-Devices/govee-ble/pull/81),
703 | [`00d9581`](https://github.com/Bluetooth-Devices/govee-ble/commit/00d9581bfb766f9ab95d3034afc45e4f9dcaf58f))
704 |
705 |
706 | ## v0.29.0 (2024-01-31)
707 |
708 | ### Features
709 |
710 | - Add support for h5105 ([#80](https://github.com/Bluetooth-Devices/govee-ble/pull/80),
711 | [`d1ab246`](https://github.com/Bluetooth-Devices/govee-ble/commit/d1ab246b766df4775ae1c3534b52b66f8f88e39f))
712 |
713 |
714 | ## v0.28.0 (2024-01-31)
715 |
716 | ### Features
717 |
718 | - Add support for h5103 ([#79](https://github.com/Bluetooth-Devices/govee-ble/pull/79),
719 | [`0c698bb`](https://github.com/Bluetooth-Devices/govee-ble/commit/0c698bbfd3d30233c60fdec0722d41f86904c120))
720 |
721 |
722 | ## v0.27.3 (2024-01-12)
723 |
724 | ### Bug Fixes
725 |
726 | - Ensure H5106 is not detected as a H5101
727 | ([#77](https://github.com/Bluetooth-Devices/govee-ble/pull/77),
728 | [`0f847ea`](https://github.com/Bluetooth-Devices/govee-ble/commit/0f847ea83473d5c385664e62ebd4771aa4a8ba82))
729 |
730 |
731 | ## v0.27.2 (2024-01-11)
732 |
733 | ### Bug Fixes
734 |
735 | - Ensure H5106 has a name in passive mode
736 | ([#76](https://github.com/Bluetooth-Devices/govee-ble/pull/76),
737 | [`491977e`](https://github.com/Bluetooth-Devices/govee-ble/commit/491977e12363f25fd543e4663e419c9e0c891bcb))
738 |
739 |
740 | ## v0.27.1 (2024-01-11)
741 |
742 | ### Bug Fixes
743 |
744 | - Update sensor state data to fix pm25 in library
745 | ([#75](https://github.com/Bluetooth-Devices/govee-ble/pull/75),
746 | [`425d322`](https://github.com/Bluetooth-Devices/govee-ble/commit/425d32230af45990bb5383ee64c8d03a815d64d6))
747 |
748 |
749 | ## v0.27.0 (2024-01-11)
750 |
751 | ### Features
752 |
753 | - Add support for H5106 ([#74](https://github.com/Bluetooth-Devices/govee-ble/pull/74),
754 | [`1466f9d`](https://github.com/Bluetooth-Devices/govee-ble/commit/1466f9d680d6bca900677eda9fcef2c02150c374))
755 |
756 |
757 | ## v0.26.0 (2024-01-10)
758 |
759 | ### Features
760 |
761 | - Add support for 5104 and 5174 ([#73](https://github.com/Bluetooth-Devices/govee-ble/pull/73),
762 | [`ce7e266`](https://github.com/Bluetooth-Devices/govee-ble/commit/ce7e266e27afddc46e607ce8cd08f2a941749f69))
763 |
764 |
765 | ## v0.25.0 (2024-01-10)
766 |
767 | ### Features
768 |
769 | - Add support for H5108 ([#72](https://github.com/Bluetooth-Devices/govee-ble/pull/72),
770 | [`0f52384`](https://github.com/Bluetooth-Devices/govee-ble/commit/0f5238472177402361f3d1a39861c2a9db29307d))
771 |
772 |
773 | ## v0.24.0 (2023-08-11)
774 |
775 | ### Chores
776 |
777 | - Update python-semantic-release ([#67](https://github.com/Bluetooth-Devices/govee-ble/pull/67),
778 | [`082e358`](https://github.com/Bluetooth-Devices/govee-ble/commit/082e35861194395b9539726e466cc7abee529ba1))
779 |
780 | ### Features
781 |
782 | - Add support for govee h5055 ([#66](https://github.com/Bluetooth-Devices/govee-ble/pull/66),
783 | [`badd966`](https://github.com/Bluetooth-Devices/govee-ble/commit/badd966b529225f7ce55e97362e0b3c15be5191a))
784 |
785 |
786 | ## v0.23.0 (2023-02-10)
787 |
788 | ### Bug Fixes
789 |
790 | - Update isort to fix ci ([#62](https://github.com/Bluetooth-Devices/govee-ble/pull/62),
791 | [`9147504`](https://github.com/Bluetooth-Devices/govee-ble/commit/914750424c33fcaa1268d7d36dac1cccd7441ae6))
792 |
793 | ### Features
794 |
795 | - Add low temperature alarm to h5198 ([#61](https://github.com/Bluetooth-Devices/govee-ble/pull/61),
796 | [`d2b8e0f`](https://github.com/Bluetooth-Devices/govee-ble/commit/d2b8e0f5ddc0faa1bd2699439605601c0ca58f08))
797 |
798 |
799 | ## v0.22.0 (2023-01-27)
800 |
801 | ### Features
802 |
803 | - Add govee h5198 ([#60](https://github.com/Bluetooth-Devices/govee-ble/pull/60),
804 | [`821a55d`](https://github.com/Bluetooth-Devices/govee-ble/commit/821a55d1162b9d87e2a7745e9e015b925f7bf816))
805 |
806 |
807 | ## v0.21.1 (2023-01-12)
808 |
809 | ### Bug Fixes
810 |
811 | - Decrease minimum temperature to -30C
812 | ([#57](https://github.com/Bluetooth-Devices/govee-ble/pull/57),
813 | [`c41c9b5`](https://github.com/Bluetooth-Devices/govee-ble/commit/c41c9b5858a469e07cbb6b6666f2bdd4f5eee2c8))
814 |
815 | Fixes https://github.com/home-assistant/core/issues/85580
816 |
817 |
818 | ## v0.21.0 (2022-12-27)
819 |
820 | ### Features
821 |
822 | - Implement error bit ([#55](https://github.com/Bluetooth-Devices/govee-ble/pull/55),
823 | [`b4b2f82`](https://github.com/Bluetooth-Devices/govee-ble/commit/b4b2f821e8d1dc6e1517ca76d29d124add369eb7))
824 |
825 | Fixes https://github.com/Bluetooth-Devices/govee-ble/issues/51
826 |
827 |
828 | ## v0.20.0 (2022-12-19)
829 |
830 | ### Features
831 |
832 | - Log data as hex ([#53](https://github.com/Bluetooth-Devices/govee-ble/pull/53),
833 | [`d014bfc`](https://github.com/Bluetooth-Devices/govee-ble/commit/d014bfc9e1ed278c8fe2f25b469941748bac19cb))
834 |
835 |
836 | ## v0.19.4 (2022-12-18)
837 |
838 | ### Bug Fixes
839 |
840 | - Round temp values ([#52](https://github.com/Bluetooth-Devices/govee-ble/pull/52),
841 | [`e7ec133`](https://github.com/Bluetooth-Devices/govee-ble/commit/e7ec133fa7a884f67b841a5f1f42c7d98946657e))
842 |
843 |
844 | ## v0.19.3 (2022-12-15)
845 |
846 | ### Bug Fixes
847 |
848 | - Reject impossible temp values take 2
849 | ([#50](https://github.com/Bluetooth-Devices/govee-ble/pull/50),
850 | [`c0a54eb`](https://github.com/Bluetooth-Devices/govee-ble/commit/c0a54eb3e00afe20bacbb930ea8ce251d760d8bc))
851 |
852 |
853 | ## v0.19.2 (2022-12-15)
854 |
855 | ### Bug Fixes
856 |
857 | - Reject impossible temp values ([#47](https://github.com/Bluetooth-Devices/govee-ble/pull/47),
858 | [`bb8b6e0`](https://github.com/Bluetooth-Devices/govee-ble/commit/bb8b6e00b8c0a2a8779806e6b25330ef50cb41f8))
859 |
860 |
861 | ## v0.19.1 (2022-09-30)
862 |
863 | ### Bug Fixes
864 |
865 | - Handle another H5181 ([#45](https://github.com/Bluetooth-Devices/govee-ble/pull/45),
866 | [`af2da30`](https://github.com/Bluetooth-Devices/govee-ble/commit/af2da30574db19674ec5e76bfaa5c84adcbbe9f0))
867 |
868 |
869 | ## v0.19.0 (2022-09-24)
870 |
871 | ### Features
872 |
873 | - Add support for yet another H5183 variant
874 | ([#44](https://github.com/Bluetooth-Devices/govee-ble/pull/44),
875 | [`d699552`](https://github.com/Bluetooth-Devices/govee-ble/commit/d699552bef2c3be13b34899f34e355a54914ffdb))
876 |
877 |
878 | ## v0.18.0 (2022-09-24)
879 |
880 | ### Features
881 |
882 | - Add support for another H5181 variant
883 | ([#43](https://github.com/Bluetooth-Devices/govee-ble/pull/43),
884 | [`7738d25`](https://github.com/Bluetooth-Devices/govee-ble/commit/7738d25fe6737a2c41d4d1f7af6e3fa41861ba0e))
885 |
886 |
887 | ## v0.17.3 (2022-09-13)
888 |
889 | ### Bug Fixes
890 |
891 | - Publish ([#41](https://github.com/Bluetooth-Devices/govee-ble/pull/41),
892 | [`40ce706`](https://github.com/Bluetooth-Devices/govee-ble/commit/40ce70653f9cd52eb584253f6893d0f20677d2c7))
893 |
894 |
895 | ## v0.17.2 (2022-09-05)
896 |
897 | ### Bug Fixes
898 |
899 | - Names are now human readable ([#39](https://github.com/Bluetooth-Devices/govee-ble/pull/39),
900 | [`fefc6b4`](https://github.com/Bluetooth-Devices/govee-ble/commit/fefc6b405e62a063234d12c8d812f9581b24369c))
901 |
902 |
903 | ## v0.17.1 (2022-08-31)
904 |
905 | ### Bug Fixes
906 |
907 | - Model H5181 var fixes ([#38](https://github.com/Bluetooth-Devices/govee-ble/pull/38),
908 | [`42012bc`](https://github.com/Bluetooth-Devices/govee-ble/commit/42012bc8be9028c62054a7b143ea990ffeb67deb))
909 |
910 |
911 | ## v0.17.0 (2022-08-30)
912 |
913 | ### Features
914 |
915 | - Add support for additional H5185 firmware
916 | ([#37](https://github.com/Bluetooth-Devices/govee-ble/pull/37),
917 | [`0a5dfa5`](https://github.com/Bluetooth-Devices/govee-ble/commit/0a5dfa5e4e95d79f3f9a5e076355963ba75d34be))
918 |
919 |
920 | ## v0.16.1 (2022-08-25)
921 |
922 | ### Bug Fixes
923 |
924 | - Use bluetooth-data-tools short_address
925 | ([#36](https://github.com/Bluetooth-Devices/govee-ble/pull/36),
926 | [`e137d93`](https://github.com/Bluetooth-Devices/govee-ble/commit/e137d930d7605a41f7112fd342cfc4bd269dc7da))
927 |
928 |
929 | ## v0.16.0 (2022-08-16)
930 |
931 | ### Features
932 |
933 | - Add support for H5071 ([#34](https://github.com/Bluetooth-Devices/govee-ble/pull/34),
934 | [`cf7e809`](https://github.com/Bluetooth-Devices/govee-ble/commit/cf7e8095c3f15a5d2ccde2cd14cf294edb4ba379))
935 |
936 |
937 | ## v0.15.0 (2022-08-16)
938 |
939 | ### Features
940 |
941 | - Implement rounding ([#33](https://github.com/Bluetooth-Devices/govee-ble/pull/33),
942 | [`eeed1aa`](https://github.com/Bluetooth-Devices/govee-ble/commit/eeed1aa231be0df9f3193511124ca2dfeeeaee51))
943 |
944 |
945 | ## v0.14.1 (2022-08-11)
946 |
947 | ### Bug Fixes
948 |
949 | - Older 5181 firmwares ([#31](https://github.com/Bluetooth-Devices/govee-ble/pull/31),
950 | [`61eac60`](https://github.com/Bluetooth-Devices/govee-ble/commit/61eac6038177b58c07a80882d3cebe9debc25430))
951 |
952 |
953 | ## v0.14.0 (2022-08-08)
954 |
955 | ### Features
956 |
957 | - Add support for the h5052 ([#30](https://github.com/Bluetooth-Devices/govee-ble/pull/30),
958 | [`625594c`](https://github.com/Bluetooth-Devices/govee-ble/commit/625594c16ad67801cf2a57fa2534900e6ef28310))
959 |
960 |
961 | ## v0.13.0 (2022-08-08)
962 |
963 | ### Features
964 |
965 | - Add support for the 5184 devices ([#29](https://github.com/Bluetooth-Devices/govee-ble/pull/29),
966 | [`d9d6d6a`](https://github.com/Bluetooth-Devices/govee-ble/commit/d9d6d6a84e7b7647c829be8471915e15fa61ca0d))
967 |
968 |
969 | ## v0.12.7 (2022-08-07)
970 |
971 | ### Bug Fixes
972 |
973 | - Add 818 to the manufacturer_ids for the gvh5185
974 | ([#28](https://github.com/Bluetooth-Devices/govee-ble/pull/28),
975 | [`f3cfb61`](https://github.com/Bluetooth-Devices/govee-ble/commit/f3cfb61c2d562b801570956901f669c27b0d77fb))
976 |
977 |
978 | ## v0.12.6 (2022-08-02)
979 |
980 | ### Bug Fixes
981 |
982 | - The GVH5074 is little endian ([#27](https://github.com/Bluetooth-Devices/govee-ble/pull/27),
983 | [`28e626c`](https://github.com/Bluetooth-Devices/govee-ble/commit/28e626c2527c395c507fbe00e7f18a184a3484f0))
984 |
985 |
986 | ## v0.12.5 (2022-07-30)
987 |
988 | ### Bug Fixes
989 |
990 | - H5179 is little endian and not big endian like the rest
991 | ([#26](https://github.com/Bluetooth-Devices/govee-ble/pull/26),
992 | [`24a0e92`](https://github.com/Bluetooth-Devices/govee-ble/commit/24a0e922f32ef476d51d0b13e90a737dfdc83676))
993 |
994 |
995 | ## v0.12.4 (2022-07-29)
996 |
997 | ### Bug Fixes
998 |
999 | - Parser for h5182 had the wrong mfgr_id
1000 | ([#25](https://github.com/Bluetooth-Devices/govee-ble/pull/25),
1001 | [`57abb96`](https://github.com/Bluetooth-Devices/govee-ble/commit/57abb962b32994fe4ec8cb938ad89947838b8294))
1002 |
1003 |
1004 | ## v0.12.3 (2022-07-22)
1005 |
1006 | ### Bug Fixes
1007 |
1008 | - Names for bbq devices ([#24](https://github.com/Bluetooth-Devices/govee-ble/pull/24),
1009 | [`4407ed4`](https://github.com/Bluetooth-Devices/govee-ble/commit/4407ed431f4280ca77b7a31cd4fa930f878aee77))
1010 |
1011 |
1012 | ## v0.12.2 (2022-07-22)
1013 |
1014 | ### Bug Fixes
1015 |
1016 | - Fixs for bbq sensors ([#23](https://github.com/Bluetooth-Devices/govee-ble/pull/23),
1017 | [`132d04d`](https://github.com/Bluetooth-Devices/govee-ble/commit/132d04d91fc9161ff1a67a34c9b00c46afb2f708))
1018 |
1019 |
1020 | ## v0.12.1 (2022-07-21)
1021 |
1022 | ### Bug Fixes
1023 |
1024 | - Bump sensor-state-data to fix typing
1025 | ([#22](https://github.com/Bluetooth-Devices/govee-ble/pull/22),
1026 | [`d5cdfc5`](https://github.com/Bluetooth-Devices/govee-ble/commit/d5cdfc506abeb4c81bbb0c2d0c7515f7c81266c5))
1027 |
1028 |
1029 | ## v0.12.0 (2022-07-21)
1030 |
1031 | ### Features
1032 |
1033 | - Refactor for sensor-state-data 2 ([#21](https://github.com/Bluetooth-Devices/govee-ble/pull/21),
1034 | [`b7fb4dc`](https://github.com/Bluetooth-Devices/govee-ble/commit/b7fb4dcef279e1eeb4b53e47e8f684c3a785e3c2))
1035 |
1036 |
1037 | ## v0.11.0 (2022-07-20)
1038 |
1039 | ### Features
1040 |
1041 | - Export SensorDescription and SensorValue
1042 | ([#20](https://github.com/Bluetooth-Devices/govee-ble/pull/20),
1043 | [`b61e938`](https://github.com/Bluetooth-Devices/govee-ble/commit/b61e938ce974bf892b2060bc95d6ee808191d1bf))
1044 |
1045 |
1046 | ## v0.10.2 (2022-07-20)
1047 |
1048 | ### Bug Fixes
1049 |
1050 | - Bump deps ([#19](https://github.com/Bluetooth-Devices/govee-ble/pull/19),
1051 | [`5fc9ece`](https://github.com/Bluetooth-Devices/govee-ble/commit/5fc9ece3d7502bfab84f9f287912f6375549cf49))
1052 |
1053 |
1054 | ## v0.10.1 (2022-07-19)
1055 |
1056 | ### Bug Fixes
1057 |
1058 | - Bump libs ([#18](https://github.com/Bluetooth-Devices/govee-ble/pull/18),
1059 | [`e818e7c`](https://github.com/Bluetooth-Devices/govee-ble/commit/e818e7c4dc797a571e1d78426f62b940ec60c585))
1060 |
1061 |
1062 | ## v0.10.0 (2022-07-19)
1063 |
1064 | ### Features
1065 |
1066 | - Export all needed objects ([#17](https://github.com/Bluetooth-Devices/govee-ble/pull/17),
1067 | [`3c5ca7b`](https://github.com/Bluetooth-Devices/govee-ble/commit/3c5ca7b42d20c36bcca650ba15b4b32280751a88))
1068 |
1069 |
1070 | ## v0.9.1 (2022-07-19)
1071 |
1072 | ### Bug Fixes
1073 |
1074 | - Add missing device classes to bbq probes
1075 | ([#16](https://github.com/Bluetooth-Devices/govee-ble/pull/16),
1076 | [`f2cafd7`](https://github.com/Bluetooth-Devices/govee-ble/commit/f2cafd71dba9894cb7dc9ab6706bd23b77c61366))
1077 |
1078 |
1079 | ## v0.9.0 (2022-07-19)
1080 |
1081 | ### Features
1082 |
1083 | - Set manu for secondary sensor ([#15](https://github.com/Bluetooth-Devices/govee-ble/pull/15),
1084 | [`ec54d57`](https://github.com/Bluetooth-Devices/govee-ble/commit/ec54d57f25bdff968d9430421b64a751f1b2ce13))
1085 |
1086 |
1087 | ## v0.8.0 (2022-07-19)
1088 |
1089 | ### Features
1090 |
1091 | - Add set_device_manufacturer ([#14](https://github.com/Bluetooth-Devices/govee-ble/pull/14),
1092 | [`f0203b7`](https://github.com/Bluetooth-Devices/govee-ble/commit/f0203b7c50753127f298e7d7c6977580dccb8cd4))
1093 |
1094 |
1095 | ## v0.7.0 (2022-07-19)
1096 |
1097 | ### Features
1098 |
1099 | - Add support for B5178 local name variation
1100 | ([#13](https://github.com/Bluetooth-Devices/govee-ble/pull/13),
1101 | [`324b3cd`](https://github.com/Bluetooth-Devices/govee-ble/commit/324b3cd99c833496af7427333e591f23d249ec70))
1102 |
1103 |
1104 | ## v0.6.0 (2022-07-19)
1105 |
1106 | ### Features
1107 |
1108 | - Do not drop mac from title ([#12](https://github.com/Bluetooth-Devices/govee-ble/pull/12),
1109 | [`cd187ed`](https://github.com/Bluetooth-Devices/govee-ble/commit/cd187ed19b0acf5b7b0c3a91dbc0e13fb321cce5))
1110 |
1111 |
1112 | ## v0.5.0 (2022-07-19)
1113 |
1114 | ### Features
1115 |
1116 | - Set title for outdoor sensors ([#11](https://github.com/Bluetooth-Devices/govee-ble/pull/11),
1117 | [`1031c78`](https://github.com/Bluetooth-Devices/govee-ble/commit/1031c782865e9b6ec74e38df5f3b4a5345d871ce))
1118 |
1119 |
1120 | ## v0.4.1 (2022-07-19)
1121 |
1122 | ### Bug Fixes
1123 |
1124 | - Fix device_id for remote sensors ([#10](https://github.com/Bluetooth-Devices/govee-ble/pull/10),
1125 | [`198caf2`](https://github.com/Bluetooth-Devices/govee-ble/commit/198caf26a535f070921ee3e24cc66070d64282d2))
1126 |
1127 |
1128 | ## v0.4.0 (2022-07-19)
1129 |
1130 | ### Features
1131 |
1132 | - Improve support for remote sensors ([#9](https://github.com/Bluetooth-Devices/govee-ble/pull/9),
1133 | [`bf6eca1`](https://github.com/Bluetooth-Devices/govee-ble/commit/bf6eca1d1f64770fd010475afaeeb642c5e175ff))
1134 |
1135 |
1136 | ## v0.3.0 (2022-07-19)
1137 |
1138 | ### Features
1139 |
1140 | - Change model ([#8](https://github.com/Bluetooth-Devices/govee-ble/pull/8),
1141 | [`9456bb3`](https://github.com/Bluetooth-Devices/govee-ble/commit/9456bb3ec459e9f2e7d7be4e1bfd670e5cb4fed6))
1142 |
1143 |
1144 | ## v0.2.1 (2022-07-19)
1145 |
1146 | ### Bug Fixes
1147 |
1148 | - Update sensor-state-data ([#7](https://github.com/Bluetooth-Devices/govee-ble/pull/7),
1149 | [`02b04a9`](https://github.com/Bluetooth-Devices/govee-ble/commit/02b04a91d47337dbdd925cc2c7e037500cd934f2))
1150 |
1151 |
1152 | ## v0.2.0 (2022-07-19)
1153 |
1154 | ### Features
1155 |
1156 | - Switch to using bluetooth-sensor-state-data
1157 | ([#6](https://github.com/Bluetooth-Devices/govee-ble/pull/6),
1158 | [`8ad3ec5`](https://github.com/Bluetooth-Devices/govee-ble/commit/8ad3ec5f8e7117cf1847be79641b1f706eb9478f))
1159 |
1160 |
1161 | ## v0.1.1 (2022-07-18)
1162 |
1163 | ### Bug Fixes
1164 |
1165 | - Fix links ([#5](https://github.com/Bluetooth-Devices/govee-ble/pull/5),
1166 | [`455f2d2`](https://github.com/Bluetooth-Devices/govee-ble/commit/455f2d202e80c03bb0e15d1f0385316e3d9dfded))
1167 |
1168 |
1169 | ## v0.1.0 (2022-07-18)
1170 |
1171 | ### Bug Fixes
1172 |
1173 | - Fix publish process ([#4](https://github.com/Bluetooth-Devices/govee-ble/pull/4),
1174 | [`9c3f892`](https://github.com/Bluetooth-Devices/govee-ble/commit/9c3f89271d1226f05dbe6ec972096c2e822bd2bb))
1175 |
1176 | ### Features
1177 |
1178 | - Init repo ([#2](https://github.com/Bluetooth-Devices/govee-ble/pull/2),
1179 | [`58fe30c`](https://github.com/Bluetooth-Devices/govee-ble/commit/58fe30ca51b74e3c822bb03e3876eced657915a8))
1180 |
1181 |
1182 | ## v0.0.2 (2022-07-18)
1183 |
1184 | ### Bug Fixes
1185 |
1186 | - Bump python min to 3.9
1187 | ([`5913902`](https://github.com/Bluetooth-Devices/govee-ble/commit/5913902dd854a5e3fc86e290e76fcb8eef9d1804))
1188 |
1189 | ### Chores
1190 |
1191 | - Initial commit
1192 | ([`4b17198`](https://github.com/Bluetooth-Devices/govee-ble/commit/4b171988c2acc563cb05f48c98837be78a1dd656))
1193 |
--------------------------------------------------------------------------------