pax_global_header 0000666 0000000 0000000 00000000064 14366747107 0014531 g ustar 00root root 0000000 0000000 52 comment=7a37db351cb887b2259c654410dad2c093336003
930913-ld2410-ble-6c24cfb/ 0000775 0000000 0000000 00000000000 14366747107 0014440 5 ustar 00root root 0000000 0000000 930913-ld2410-ble-6c24cfb/.all-contributorsrc 0000664 0000000 0000000 00000000446 14366747107 0020275 0 ustar 00root root 0000000 0000000 {
"projectName": "ld2410-ble",
"projectOwner": "930913",
"repoType": "github",
"repoHost": "https://github.com",
"files": [
"README.md"
],
"imageSize": 80,
"commit": true,
"commitConvention": "angular",
"contributors": [],
"contributorsPerLine": 7,
"skipCi": true
}
930913-ld2410-ble-6c24cfb/.editorconfig 0000664 0000000 0000000 00000000444 14366747107 0017117 0 ustar 00root root 0000000 0000000 # http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
insert_final_newline = true
charset = utf-8
end_of_line = lf
[*.bat]
indent_style = tab
end_of_line = crlf
[LICENSE]
insert_final_newline = false
[Makefile]
indent_style = tab
930913-ld2410-ble-6c24cfb/.flake8 0000664 0000000 0000000 00000000056 14366747107 0015614 0 ustar 00root root 0000000 0000000 [flake8]
exclude = docs
max-line-length = 120
930913-ld2410-ble-6c24cfb/.github/ 0000775 0000000 0000000 00000000000 14366747107 0016000 5 ustar 00root root 0000000 0000000 930913-ld2410-ble-6c24cfb/.github/FUNDING.yml 0000664 0000000 0000000 00000000023 14366747107 0017610 0 ustar 00root root 0000000 0000000 github: ["930913"]
930913-ld2410-ble-6c24cfb/.github/ISSUE_TEMPLATE/ 0000775 0000000 0000000 00000000000 14366747107 0020163 5 ustar 00root root 0000000 0000000 930913-ld2410-ble-6c24cfb/.github/ISSUE_TEMPLATE/1-bug_report.md 0000664 0000000 0000000 00000000422 14366747107 0023011 0 ustar 00root root 0000000 0000000 ---
name: Bug report
about: Create a report to help us improve
labels: bug
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
**Additional context**
Add any other context about the problem here.
930913-ld2410-ble-6c24cfb/.github/ISSUE_TEMPLATE/2-feature-request.md 0000664 0000000 0000000 00000000672 14366747107 0023772 0 ustar 00root root 0000000 0000000 ---
name: Feature request
about: Suggest an idea for this project
labels: enhancement
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Additional context**
Add any other context or screenshots about the feature request here.
930913-ld2410-ble-6c24cfb/.github/labels.toml 0000664 0000000 0000000 00000003515 14366747107 0020143 0 ustar 00root root 0000000 0000000 [breaking]
color = "ffcc00"
name = "breaking"
description = "Breaking change."
[bug]
color = "d73a4a"
name = "bug"
description = "Something isn't working"
[dependencies]
color = "0366d6"
name = "dependencies"
description = "Pull requests that update a dependency file"
[github_actions]
color = "000000"
name = "github_actions"
description = "Update of github actions"
[documentation]
color = "1bc4a5"
name = "documentation"
description = "Improvements or additions to documentation"
[duplicate]
color = "cfd3d7"
name = "duplicate"
description = "This issue or pull request already exists"
[enhancement]
color = "a2eeef"
name = "enhancement"
description = "New feature or request"
["good first issue"]
color = "7057ff"
name = "good first issue"
description = "Good for newcomers"
["help wanted"]
color = "008672"
name = "help wanted"
description = "Extra attention is needed"
[invalid]
color = "e4e669"
name = "invalid"
description = "This doesn't seem right"
[nochangelog]
color = "555555"
name = "nochangelog"
description = "Exclude pull requests from changelog"
[question]
color = "d876e3"
name = "question"
description = "Further information is requested"
[removed]
color = "e99695"
name = "removed"
description = "Removed piece of functionalities."
[tests]
color = "bfd4f2"
name = "tests"
description = "CI, CD and testing related changes"
[wontfix]
color = "ffffff"
name = "wontfix"
description = "This will not be worked on"
[discussion]
color = "c2e0c6"
name = "discussion"
description = "Some discussion around the project"
[hacktoberfest]
color = "ffa663"
name = "hacktoberfest"
description = "Good issues for Hacktoberfest"
[answered]
color = "0ee2b6"
name = "answered"
description = "Automatically closes as answered after a delay"
[waiting]
color = "5f7972"
name = "waiting"
description = "Automatically closes if no answer after a delay"
930913-ld2410-ble-6c24cfb/.github/workflows/ 0000775 0000000 0000000 00000000000 14366747107 0020035 5 ustar 00root root 0000000 0000000 930913-ld2410-ble-6c24cfb/.github/workflows/ci.yml 0000664 0000000 0000000 00000003730 14366747107 0021156 0 ustar 00root root 0000000 0000000 name: CI
on:
push:
branches:
- main
pull_request:
concurrency:
group: ${{ github.head_ref || github.run_id }}
cancel-in-progress: true
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
with:
python-version: "3.9"
- uses: pre-commit/action@v2.0.3
# Make sure commit messages follow the conventional commits convention:
# https://www.conventionalcommits.org
commitlint:
name: Lint Commit Messages
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- uses: wagoid/commitlint-github-action@v4.1.11
test:
strategy:
fail-fast: false
matrix:
python-version:
- "3.9"
- "3.10"
os:
- ubuntu-latest
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}
- uses: snok/install-poetry@v1
- name: Install Dependencies
run: poetry install
- name: Test with Pytest
run: poetry run pytest --cov-report=xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
release:
runs-on: ubuntu-latest
environment: release
if: github.ref == 'refs/heads/main'
needs:
- test
- lint
- commitlint
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
# Run semantic release:
# - Update CHANGELOG.md
# - Update version in code
# - Create git tag
# - Create GitHub release
# - Publish to PyPI
- name: Python Semantic Release
uses: relekang/python-semantic-release@v7.31.4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
pypi_token: ${{ secrets.PYPI_TOKEN }}
930913-ld2410-ble-6c24cfb/.github/workflows/hacktoberfest.yml 0000664 0000000 0000000 00000000534 14366747107 0023406 0 ustar 00root root 0000000 0000000 name: Hacktoberfest
on:
schedule:
# Run every day in October
- cron: "0 0 * 10 *"
# Run on the 1st of November to revert
- cron: "0 13 1 11 *"
jobs:
hacktoberfest:
runs-on: ubuntu-latest
steps:
- uses: browniebroke/hacktoberfest-labeler-action@v2.2.0
with:
github_token: ${{ secrets.GH_PAT }}
930913-ld2410-ble-6c24cfb/.github/workflows/issue-manager.yml 0000664 0000000 0000000 00000001340 14366747107 0023316 0 ustar 00root root 0000000 0000000 name: Issue Manager
on:
schedule:
- cron: "0 0 * * *"
issue_comment:
types:
- created
issues:
types:
- labeled
pull_request_target:
types:
- labeled
workflow_dispatch:
jobs:
issue-manager:
runs-on: ubuntu-latest
steps:
- uses: tiangolo/issue-manager@0.4.0
with:
token: ${{ secrets.GITHUB_TOKEN }}
config: >
{
"answered": {
"message": "Assuming the original issue was solved, it will be automatically closed now."
},
"waiting": {
"message": "Automatically closing. To re-open, please provide the additional information requested."
}
}
930913-ld2410-ble-6c24cfb/.github/workflows/labels.yml 0000664 0000000 0000000 00000000774 14366747107 0022032 0 ustar 00root root 0000000 0000000 name: Sync Github labels
on:
push:
branches:
- main
paths:
- ".github/**"
jobs:
labels:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
with:
python-version: 3.8
- name: Install labels
run: pip install labels
- name: Sync config with Github
run: labels -u ${{ github.repository_owner }} -t ${{ secrets.GITHUB_TOKEN }} sync -f .github/labels.toml
930913-ld2410-ble-6c24cfb/.gitignore 0000664 0000000 0000000 00000004066 14366747107 0016436 0 ustar 00root root 0000000 0000000 # Created by .ignore support plugin (hsz.mobi)
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
930913-ld2410-ble-6c24cfb/.gitpod.yml 0000664 0000000 0000000 00000000306 14366747107 0016526 0 ustar 00root root 0000000 0000000 tasks:
- command: |
pip install poetry
PIP_USER=false poetry install
- command: |
pip install pre-commit
pre-commit install
PIP_USER=false pre-commit install-hooks
930913-ld2410-ble-6c24cfb/.idea/ 0000775 0000000 0000000 00000000000 14366747107 0015420 5 ustar 00root root 0000000 0000000 930913-ld2410-ble-6c24cfb/.idea/led-ble.iml 0000664 0000000 0000000 00000000515 14366747107 0017430 0 ustar 00root root 0000000 0000000
930913-ld2410-ble-6c24cfb/.idea/watcherTasks.xml 0000664 0000000 0000000 00000005253 14366747107 0020612 0 ustar 00root root 0000000 0000000
930913-ld2410-ble-6c24cfb/.idea/workspace.xml 0000664 0000000 0000000 00000002726 14366747107 0020147 0 ustar 00root root 0000000 0000000
930913-ld2410-ble-6c24cfb/.pre-commit-config.yaml 0000664 0000000 0000000 00000003306 14366747107 0020723 0 ustar 00root root 0000000 0000000 # See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
exclude: "CHANGELOG.md"
default_stages: [commit]
ci:
autofix_commit_msg: "chore(pre-commit.ci): auto fixes"
autoupdate_commit_msg: "chore(pre-commit.ci): pre-commit autoupdate"
repos:
- repo: https://github.com/commitizen-tools/commitizen
rev: v2.29.1
hooks:
- id: commitizen
stages: [commit-msg]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
hooks:
- id: debug-statements
- id: check-builtin-literals
- id: check-case-conflict
- id: check-docstring-first
- id: check-json
- id: check-toml
- id: check-xml
- id: check-yaml
- id: detect-private-key
- id: end-of-file-fixer
- id: trailing-whitespace
- id: debug-statements
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v2.7.1
hooks:
- id: prettier
args: ["--tab-width", "2"]
- repo: https://github.com/asottile/pyupgrade
rev: v2.37.3
hooks:
- id: pyupgrade
args: [--py37-plus]
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 22.6.0
hooks:
- id: black
- repo: https://github.com/codespell-project/codespell
rev: v2.1.0
hooks:
- id: codespell
- repo: https://github.com/PyCQA/flake8
rev: 4.0.1
hooks:
- id: flake8
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.931
hooks:
- id: mypy
additional_dependencies: []
- repo: https://github.com/PyCQA/bandit
rev: 1.7.4
hooks:
- id: bandit
args: [-x, tests]
930913-ld2410-ble-6c24cfb/.readthedocs.yml 0000664 0000000 0000000 00000001004 14366747107 0017521 0 ustar 00root root 0000000 0000000 # Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/source/conf.py
# Set the version of Python and other tools you might need
build:
os: ubuntu-20.04
tools:
python: "3.9"
# Optionally declare the Python requirements required to build your docs
python:
install:
- method: pip
path: .
extra_requirements:
- docs
930913-ld2410-ble-6c24cfb/CHANGELOG.md 0000664 0000000 0000000 00000002113 14366747107 0016246 0 ustar 00root root 0000000 0000000 # Changelog
## v0.2.0 (2023-02-02)
### Feature
* Add configurable password ([`15ef013`](https://github.com/930913/ld2410-ble/commit/15ef013468befc5d74e8cda4f27b2cbee9c1fc76))
### Fix
* Bump isort build dependency ([`068d0a9`](https://github.com/930913/ld2410-ble/commit/068d0a93b01d89d9eb95df34b7ed8248921f8197))
## v0.1.1 (2022-12-12)
### Fix
* Replace namespace ([`f7ebc79`](https://github.com/930913/ld2410-ble/commit/f7ebc7938df71d4d06aae2a6de02da29a9e45b45))
## v0.1.0 (2022-12-12)
### Feature
* Handle disconnects ([`4ce126f`](https://github.com/930913/ld2410-ble/commit/4ce126f87d8b6029991d9faeef85b84c979a855e))
## v0.0.1 (2022-12-07)
### Fix
* Try change version ([`bd38389`](https://github.com/930913/ld2410-ble/commit/bd38389ffbe23ce3fbff09187a429db7e4b9f496))
* Wtf is this format ([`ec1fac6`](https://github.com/930913/ld2410-ble/commit/ec1fac63ed3541e14e07b7373eb9ccc9ff376e1b))
* Commit message ([`610be33`](https://github.com/930913/ld2410-ble/commit/610be33a12ebc791af0ce069dcc98686cf73087e))
## v0.0.0 (2022-12-07)
### Feature
Initial commit
930913-ld2410-ble-6c24cfb/CONTRIBUTING.md 0000664 0000000 0000000 00000007414 14366747107 0016677 0 ustar 00root root 0000000 0000000 # Contributing
Contributions are welcome, and they are greatly appreciated! Every little helps, and credit will always be given.
You can contribute in many ways:
## Types of Contributions
### Report Bugs
Report bugs to [our issue page][gh-issues]. If you are reporting a bug, please include:
- Your operating system name and version.
- Any details about your local setup that might be helpful in troubleshooting.
- Detailed steps to reproduce the bug.
### Fix Bugs
Look through the GitHub issues for bugs. Anything tagged with "bug" and "help wanted" is open to whoever wants to implement it.
### Implement Features
Look through the GitHub issues for features. Anything tagged with "enhancement" and "help wanted" is open to whoever wants to implement it.
### Write Documentation
LD2410 BLE could always use more documentation, whether as part of the official LD2410 BLE docs, in docstrings, or even on the web in blog posts, articles, and such.
### Submit Feedback
The best way to send feedback [our issue page][gh-issues] on GitHub. If you are proposing a feature:
- Explain in detail how it would work.
- Keep the scope as narrow as possible, to make it easier to implement.
- Remember that this is a volunteer-driven project, and that contributions are welcome 😊
## Get Started!
Ready to contribute? Here's how to set yourself up for local development.
1. Fork the repo on GitHub.
2. Clone your fork locally:
```shell
$ git clone git@github.com:/ld2410-ble.git
```
3. Install the project dependencies with [Poetry](https://python-poetry.org):
```shell
$ poetry install
```
4. Create a branch for local development:
```shell
$ git checkout -b name-of-your-bugfix-or-feature
```
Now you can make your changes locally.
5. When you're done making changes, check that your changes pass our tests:
```shell
$ poetry run pytest
```
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:
```shell
$ pre-commit run -a
```
Or better, install the hooks once and have them run automatically each time you commit:
```shell
$ pre-commit install
```
7. Commit your changes and push your branch to GitHub:
```shell
$ git add .
$ git commit -m "feat(something): your detailed description of your changes"
$ git push origin name-of-your-bugfix-or-feature
```
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.
8. Submit a pull request through the GitHub website or using the GitHub CLI (if you have it installed):
```shell
$ gh pr create --fill
```
## Pull Request Guidelines
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:
1. Include tests for feature or bug fixes.
2. Update the documentation for significant features.
3. Ensure tests are passing on CI.
## Tips
To run a subset of tests:
```shell
$ pytest tests
```
## Making a new release
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.
[gh-issues]: https://github.com/930913/ld2410-ble/issues
930913-ld2410-ble-6c24cfb/LICENSE 0000664 0000000 0000000 00000026111 14366747107 0015446 0 ustar 00root root 0000000 0000000
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2022 930913
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
930913-ld2410-ble-6c24cfb/README.md 0000664 0000000 0000000 00000006621 14366747107 0015724 0 ustar 00root root 0000000 0000000 # LD2410 BLE
Interface with LD2410B modules from HiLink
## Installation
Install this via pip (or your favourite package manager):
`pip install ld2410-ble`
## Contributors ✨
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
## Credits
This package was created with
[Cookiecutter](https://github.com/audreyr/cookiecutter) and the
[browniebroke/cookiecutter-pypackage](https://github.com/browniebroke/cookiecutter-pypackage)
project template.
930913-ld2410-ble-6c24cfb/commitlint.config.js 0000664 0000000 0000000 00000000364 14366747107 0020424 0 ustar 00root root 0000000 0000000 module.exports = {
extends: ["@commitlint/config-conventional"],
rules: {
"header-max-length": [0, "always", Infinity],
"body-max-line-length": [0, "always", Infinity],
"footer-max-line-length": [0, "always", Infinity],
},
};
930913-ld2410-ble-6c24cfb/docs/ 0000775 0000000 0000000 00000000000 14366747107 0015370 5 ustar 00root root 0000000 0000000 930913-ld2410-ble-6c24cfb/docs/Makefile 0000664 0000000 0000000 00000001175 14366747107 0017034 0 ustar 00root root 0000000 0000000 # Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
930913-ld2410-ble-6c24cfb/docs/make.bat 0000664 0000000 0000000 00000001374 14366747107 0017002 0 ustar 00root root 0000000 0000000 @ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=source
set BUILDDIR=build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd
930913-ld2410-ble-6c24cfb/docs/source/ 0000775 0000000 0000000 00000000000 14366747107 0016670 5 ustar 00root root 0000000 0000000 930913-ld2410-ble-6c24cfb/docs/source/_static/ 0000775 0000000 0000000 00000000000 14366747107 0020316 5 ustar 00root root 0000000 0000000 930913-ld2410-ble-6c24cfb/docs/source/_static/.gitkeep 0000664 0000000 0000000 00000000000 14366747107 0021735 0 ustar 00root root 0000000 0000000 930913-ld2410-ble-6c24cfb/docs/source/changelog.md 0000664 0000000 0000000 00000000045 14366747107 0021140 0 ustar 00root root 0000000 0000000 ```{include} ../../CHANGELOG.md
```
930913-ld2410-ble-6c24cfb/docs/source/conf.py 0000664 0000000 0000000 00000003632 14366747107 0020173 0 ustar 00root root 0000000 0000000 # Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
from typing import Any, List
# -- Project information -----------------------------------------------------
project = "LD2410 BLE"
copyright = "2023, 930913"
author = "930913"
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"myst_parser",
]
# The suffix of source filenames.
source_suffix = [".rst", ".md"]
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns: List[Any] = []
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "sphinx_rtd_theme"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
930913-ld2410-ble-6c24cfb/docs/source/contributing.md 0000664 0000000 0000000 00000000050 14366747107 0021714 0 ustar 00root root 0000000 0000000 ```{include} ../../CONTRIBUTING.md
```
930913-ld2410-ble-6c24cfb/docs/source/index.md 0000664 0000000 0000000 00000000352 14366747107 0020321 0 ustar 00root root 0000000 0000000 # Welcome to LD2410 BLE documentation!
```{toctree}
:caption: Installation & Usage
:maxdepth: 2
installation
usage
```
```{toctree}
:caption: Project Info
:maxdepth: 2
changelog
contributing
```
```{include} ../../README.md
```
930913-ld2410-ble-6c24cfb/docs/source/installation.md 0000664 0000000 0000000 00000000265 14366747107 0021716 0 ustar 00root root 0000000 0000000 # Installation
The package is published on [PyPI](https://pypi.org/project/deezer-python/) and can be installed with `pip` (or any equivalent):
```bash
pip install ld2410-ble
```
930913-ld2410-ble-6c24cfb/docs/source/usage.md 0000664 0000000 0000000 00000000140 14366747107 0020311 0 ustar 00root root 0000000 0000000 # Usage
To use this package, import it:
```python
import ld2410_ble
```
TODO: Document usage
930913-ld2410-ble-6c24cfb/examples/ 0000775 0000000 0000000 00000000000 14366747107 0016256 5 ustar 00root root 0000000 0000000 930913-ld2410-ble-6c24cfb/examples/run.py 0000664 0000000 0000000 00000002437 14366747107 0017442 0 ustar 00root root 0000000 0000000 import asyncio
import logging
from bleak import BleakScanner
from bleak.backends.device import BLEDevice
from bleak.backends.scanner import AdvertisementData
from ld2410_ble import LD2410BLE, LD2410BLEState
_LOGGER = logging.getLogger(__name__)
ADDRESS = "D0291B39-3A1B-7FF2-787B-4E743FED5B25"
ADDRESS = "D0291B39-3A1B-7FF2-787B-4E743FED5B25"
async def run() -> None:
scanner = BleakScanner()
future: asyncio.Future[BLEDevice] = asyncio.Future()
def on_detected(device: BLEDevice, adv: AdvertisementData) -> None:
if future.done():
return
_LOGGER.info("Detected: %s", device)
if device.address.lower() == ADDRESS.lower():
_LOGGER.info("Found device: %s", device.address)
future.set_result(device)
scanner.register_detection_callback(on_detected)
await scanner.start()
def on_state_changed(state: LD2410BLEState) -> None:
_LOGGER.info("State changed: %s", state)
device = await future
ld2410b = LD2410BLE(device)
cancel_callback = ld2410b.register_callback(on_state_changed)
await ld2410b.initialise()
await asyncio.sleep(10)
cancel_callback()
await scanner.stop()
logging.basicConfig(level=logging.INFO)
logging.getLogger("ld2410_ble").setLevel(logging.DEBUG)
asyncio.run(run())
930913-ld2410-ble-6c24cfb/poetry.lock 0000664 0000000 0000000 00000166463 14366747107 0016654 0 ustar 00root root 0000000 0000000 [[package]]
name = "alabaster"
version = "0.7.12"
description = "A configurable sidebar-enabled Sphinx theme"
category = "main"
optional = true
python-versions = "*"
[[package]]
name = "async-timeout"
version = "4.0.2"
description = "Timeout context manager for asyncio programs"
category = "main"
optional = false
python-versions = ">=3.6"
[[package]]
name = "atomicwrites"
version = "1.4.1"
description = "Atomic file writes."
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]]
name = "attrs"
version = "21.4.0"
description = "Classes Without Boilerplate"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[package.extras]
dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "sphinx", "sphinx-notfound-page", "zope.interface"]
docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"]
tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six", "zope.interface"]
tests_no_zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "six"]
[[package]]
name = "babel"
version = "2.10.3"
description = "Internationalization utilities"
category = "main"
optional = true
python-versions = ">=3.6"
[package.dependencies]
pytz = ">=2015.7"
[[package]]
name = "bleak"
version = "0.19.0"
description = "Bluetooth Low Energy platform Agnostic Klient"
category = "main"
optional = false
python-versions = ">=3.7,<4.0"
[package.dependencies]
async-timeout = ">=3.0.0,<5"
bleak-winrt = {version = ">=1.2.0,<2.0.0", markers = "platform_system == \"Windows\""}
dbus-fast = {version = ">=1.22.0,<2.0.0", markers = "platform_system == \"Linux\""}
pyobjc-core = {version = ">=8.5.1,<9.0.0", markers = "platform_system == \"Darwin\""}
pyobjc-framework-CoreBluetooth = {version = ">=8.5.1,<9.0.0", markers = "platform_system == \"Darwin\""}
pyobjc-framework-libdispatch = {version = ">=8.5.1,<9.0.0", markers = "platform_system == \"Darwin\""}
[[package]]
name = "bleak-retry-connector"
version = "2.3.0"
description = "A connector for Bleak Clients that handles transient connection failures"
category = "main"
optional = false
python-versions = ">=3.9,<4.0"
[package.dependencies]
async-timeout = ">=4.0.1"
bleak = ">=0.19.0"
dbus-fast = {version = ">=1.14.0", markers = "platform_system == \"Linux\""}
[package.extras]
docs = ["Sphinx (>=5.0,<6.0)", "myst-parser (>=0.18,<0.19)", "sphinx-rtd-theme (>=1.0,<2.0)"]
[[package]]
name = "bleak-winrt"
version = "1.2.0"
description = "Python WinRT bindings for Bleak"
category = "main"
optional = false
python-versions = "*"
[[package]]
name = "certifi"
version = "2022.6.15"
description = "Python package for providing Mozilla's CA Bundle."
category = "main"
optional = true
python-versions = ">=3.6"
[[package]]
name = "charset-normalizer"
version = "2.1.0"
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
category = "main"
optional = true
python-versions = ">=3.6.0"
[package.extras]
unicode_backport = ["unicodedata2"]
[[package]]
name = "colorama"
version = "0.4.5"
description = "Cross-platform colored terminal text."
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "coverage"
version = "6.4.4"
description = "Code coverage measurement for Python"
category = "dev"
optional = false
python-versions = ">=3.7"
[package.dependencies]
tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""}
[package.extras]
toml = ["tomli"]
[[package]]
name = "dbus-fast"
version = "1.45.0"
description = "A faster version of dbus-next"
category = "main"
optional = false
python-versions = ">=3.7,<4.0"
[package.dependencies]
async-timeout = ">=3.0.0"
[package.extras]
docs = ["Sphinx (>=5.1.1,<6.0.0)", "myst-parser (>=0.18.0,<0.19.0)", "sphinx-rtd-theme (>=1.0.0,<2.0.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)", "sphinxcontrib-fulltoc (>=1.2.0,<2.0.0)"]
[[package]]
name = "docutils"
version = "0.17.1"
description = "Docutils -- Python Documentation Utilities"
category = "main"
optional = true
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "flux-led"
version = "0.28.32"
description = "A Python library to communicate with the flux_led smart bulbs"
category = "main"
optional = false
python-versions = ">=3.7"
[package.dependencies]
webcolors = "*"
[package.extras]
all = ["Sphinx (>=3.4.3)", "black (>=19.10b0)", "bump2version (>=1.0.1)", "codecov (>=2.1.4)", "coverage (>=5.1)", "flake8 (>=3.8.3)", "flake8-debugger (>=3.2.1)", "ipython (>=7.15.0)", "m2r2 (>=0.2.7)", "pytest (>=5.4.3)", "pytest-asyncio", "pytest-cov (>=2.9.0)", "pytest-raises (>=0.11)", "pytest-runner (>=5.2)", "sphinx-rtd-theme (>=0.5.1)", "tox (>=3.15.2)", "twine (>=3.1.1)", "typing-extensions", "webcolors", "wheel (>=0.34.2)"]
dev = ["Sphinx (>=3.4.3)", "black (>=19.10b0)", "bump2version (>=1.0.1)", "codecov (>=2.1.4)", "coverage (>=5.1)", "flake8 (>=3.8.3)", "flake8-debugger (>=3.2.1)", "ipython (>=7.15.0)", "m2r2 (>=0.2.7)", "pytest (>=5.4.3)", "pytest-asyncio", "pytest-cov (>=2.9.0)", "pytest-raises (>=0.11)", "pytest-runner (>=5.2)", "sphinx-rtd-theme (>=0.5.1)", "tox (>=3.15.2)", "twine (>=3.1.1)", "wheel (>=0.34.2)"]
setup = ["pytest-runner (>=5.2)"]
test = ["black (>=19.10b0)", "codecov (>=2.1.4)", "flake8 (>=3.8.3)", "flake8-debugger (>=3.2.1)", "pytest (>=5.4.3)", "pytest-asyncio", "pytest-cov (>=2.9.0)", "pytest-raises (>=0.11)"]
[[package]]
name = "idna"
version = "3.3"
description = "Internationalized Domain Names in Applications (IDNA)"
category = "main"
optional = true
python-versions = ">=3.5"
[[package]]
name = "imagesize"
version = "1.4.1"
description = "Getting image size from png/jpeg/jpeg2000/gif file"
category = "main"
optional = true
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]]
name = "importlib-metadata"
version = "4.12.0"
description = "Read metadata from Python packages"
category = "main"
optional = true
python-versions = ">=3.7"
[package.dependencies]
zipp = ">=0.5"
[package.extras]
docs = ["jaraco.packaging (>=9)", "rst.linker (>=1.9)", "sphinx"]
perf = ["ipython"]
testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"]
[[package]]
name = "iniconfig"
version = "1.1.1"
description = "iniconfig: brain-dead simple config-ini parsing"
category = "dev"
optional = false
python-versions = "*"
[[package]]
name = "jinja2"
version = "3.1.2"
description = "A very fast and expressive template engine."
category = "main"
optional = true
python-versions = ">=3.7"
[package.dependencies]
MarkupSafe = ">=2.0"
[package.extras]
i18n = ["Babel (>=2.7)"]
[[package]]
name = "markdown-it-py"
version = "2.1.0"
description = "Python port of markdown-it. Markdown parsing, done right!"
category = "main"
optional = true
python-versions = ">=3.7"
[package.dependencies]
mdurl = ">=0.1,<1.0"
[package.extras]
benchmarking = ["psutil", "pytest", "pytest-benchmark (>=3.2,<4.0)"]
code_style = ["pre-commit (==2.6)"]
compare = ["commonmark (>=0.9.1,<0.10.0)", "markdown (>=3.3.6,<3.4.0)", "mistletoe (>=0.8.1,<0.9.0)", "mistune (>=2.0.2,<2.1.0)", "panflute (>=2.1.3,<2.2.0)"]
linkify = ["linkify-it-py (>=1.0,<2.0)"]
plugins = ["mdit-py-plugins"]
profiling = ["gprof2dot"]
rtd = ["attrs", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"]
testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
[[package]]
name = "markupsafe"
version = "2.1.1"
description = "Safely add untrusted strings to HTML/XML markup."
category = "main"
optional = true
python-versions = ">=3.7"
[[package]]
name = "mdit-py-plugins"
version = "0.3.0"
description = "Collection of plugins for markdown-it-py"
category = "main"
optional = true
python-versions = "~=3.6"
[package.dependencies]
markdown-it-py = ">=1.0.0,<3.0.0"
[package.extras]
code_style = ["pre-commit (==2.6)"]
rtd = ["myst-parser (>=0.14.0,<0.15.0)", "sphinx-book-theme (>=0.1.0,<0.2.0)"]
testing = ["coverage", "pytest (>=3.6,<4)", "pytest-cov", "pytest-regressions"]
[[package]]
name = "mdurl"
version = "0.1.1"
description = "Markdown URL utilities"
category = "main"
optional = true
python-versions = ">=3.7"
[[package]]
name = "myst-parser"
version = "0.18.0"
description = "An extended commonmark compliant parser, with bridges to docutils & sphinx."
category = "main"
optional = true
python-versions = ">=3.7"
[package.dependencies]
docutils = ">=0.15,<0.19"
jinja2 = "*"
markdown-it-py = ">=1.0.0,<3.0.0"
mdit-py-plugins = ">=0.3.0,<0.4.0"
pyyaml = "*"
sphinx = ">=4,<6"
typing-extensions = "*"
[package.extras]
code_style = ["pre-commit (>=2.12,<3.0)"]
linkify = ["linkify-it-py (>=1.0,<2.0)"]
rtd = ["ipython", "sphinx-book-theme", "sphinx-design", "sphinxcontrib.mermaid (>=0.7.1,<0.8.0)", "sphinxext-opengraph (>=0.6.3,<0.7.0)", "sphinxext-rediraffe (>=0.2.7,<0.3.0)"]
testing = ["beautifulsoup4", "coverage[toml]", "pytest (>=6,<7)", "pytest-cov", "pytest-param-files (>=0.3.4,<0.4.0)", "pytest-regressions", "sphinx-pytest"]
[[package]]
name = "packaging"
version = "21.3"
description = "Core utilities for Python packages"
category = "main"
optional = false
python-versions = ">=3.6"
[package.dependencies]
pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
[[package]]
name = "pluggy"
version = "1.0.0"
description = "plugin and hook calling mechanisms for python"
category = "dev"
optional = false
python-versions = ">=3.6"
[package.extras]
dev = ["pre-commit", "tox"]
testing = ["pytest", "pytest-benchmark"]
[[package]]
name = "py"
version = "1.11.0"
description = "library with cross-python path, ini-parsing, io, code, log facilities"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]]
name = "pygments"
version = "2.12.0"
description = "Pygments is a syntax highlighting package written in Python."
category = "main"
optional = true
python-versions = ">=3.6"
[[package]]
name = "pyobjc-core"
version = "8.5.1"
description = "Python<->ObjC Interoperability Module"
category = "main"
optional = false
python-versions = ">=3.6"
[[package]]
name = "pyobjc-framework-Cocoa"
version = "8.5.1"
description = "Wrappers for the Cocoa frameworks on macOS"
category = "main"
optional = false
python-versions = ">=3.6"
[package.dependencies]
pyobjc-core = ">=8.5.1"
[[package]]
name = "pyobjc-framework-CoreBluetooth"
version = "8.5.1"
description = "Wrappers for the framework CoreBluetooth on macOS"
category = "main"
optional = false
python-versions = ">=3.6"
[package.dependencies]
pyobjc-core = ">=8.5.1"
pyobjc-framework-Cocoa = ">=8.5.1"
[[package]]
name = "pyobjc-framework-libdispatch"
version = "8.5.1"
description = "Wrappers for libdispatch on macOS"
category = "main"
optional = false
python-versions = ">=3.6"
[package.dependencies]
pyobjc-core = ">=8.5.1"
[[package]]
name = "pyparsing"
version = "3.0.9"
description = "pyparsing module - Classes and methods to define and execute parsing grammars"
category = "main"
optional = false
python-versions = ">=3.6.8"
[package.extras]
diagrams = ["jinja2", "railroad-diagrams"]
[[package]]
name = "pytest"
version = "7.1.2"
description = "pytest: simple powerful testing with Python"
category = "dev"
optional = false
python-versions = ">=3.7"
[package.dependencies]
atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
attrs = ">=19.2.0"
colorama = {version = "*", markers = "sys_platform == \"win32\""}
iniconfig = "*"
packaging = "*"
pluggy = ">=0.12,<2.0"
py = ">=1.8.2"
tomli = ">=1.0.0"
[package.extras]
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"]
[[package]]
name = "pytest-cov"
version = "3.0.0"
description = "Pytest plugin for measuring coverage."
category = "dev"
optional = false
python-versions = ">=3.6"
[package.dependencies]
coverage = {version = ">=5.2.1", extras = ["toml"]}
pytest = ">=4.6"
[package.extras]
testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"]
[[package]]
name = "pytz"
version = "2022.1"
description = "World timezone definitions, modern and historical"
category = "main"
optional = true
python-versions = "*"
[[package]]
name = "pyyaml"
version = "6.0"
description = "YAML parser and emitter for Python"
category = "main"
optional = true
python-versions = ">=3.6"
[[package]]
name = "requests"
version = "2.28.1"
description = "Python HTTP for Humans."
category = "main"
optional = true
python-versions = ">=3.7, <4"
[package.dependencies]
certifi = ">=2017.4.17"
charset-normalizer = ">=2,<3"
idna = ">=2.5,<4"
urllib3 = ">=1.21.1,<1.27"
[package.extras]
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
name = "snowballstemmer"
version = "2.2.0"
description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
category = "main"
optional = true
python-versions = "*"
[[package]]
name = "sphinx"
version = "5.1.1"
description = "Python documentation generator"
category = "main"
optional = true
python-versions = ">=3.6"
[package.dependencies]
alabaster = ">=0.7,<0.8"
babel = ">=1.3"
colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""}
docutils = ">=0.14,<0.20"
imagesize = "*"
importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""}
Jinja2 = ">=2.3"
packaging = "*"
Pygments = ">=2.0"
requests = ">=2.5.0"
snowballstemmer = ">=1.1"
sphinxcontrib-applehelp = "*"
sphinxcontrib-devhelp = "*"
sphinxcontrib-htmlhelp = ">=2.0.0"
sphinxcontrib-jsmath = "*"
sphinxcontrib-qthelp = "*"
sphinxcontrib-serializinghtml = ">=1.1.5"
[package.extras]
docs = ["sphinxcontrib-websupport"]
lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-bugbear", "flake8-comprehensions", "isort", "mypy (>=0.971)", "sphinx-lint", "types-requests", "types-typed-ast"]
test = ["cython", "html5lib", "pytest (>=4.6)", "typed-ast"]
[[package]]
name = "sphinx-rtd-theme"
version = "1.0.0"
description = "Read the Docs theme for Sphinx"
category = "main"
optional = true
python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*"
[package.dependencies]
docutils = "<0.18"
sphinx = ">=1.6"
[package.extras]
dev = ["bump2version", "sphinxcontrib-httpdomain", "transifex-client"]
[[package]]
name = "sphinxcontrib-applehelp"
version = "1.0.2"
description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books"
category = "main"
optional = true
python-versions = ">=3.5"
[package.extras]
lint = ["docutils-stubs", "flake8", "mypy"]
test = ["pytest"]
[[package]]
name = "sphinxcontrib-devhelp"
version = "1.0.2"
description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document."
category = "main"
optional = true
python-versions = ">=3.5"
[package.extras]
lint = ["docutils-stubs", "flake8", "mypy"]
test = ["pytest"]
[[package]]
name = "sphinxcontrib-htmlhelp"
version = "2.0.0"
description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
category = "main"
optional = true
python-versions = ">=3.6"
[package.extras]
lint = ["docutils-stubs", "flake8", "mypy"]
test = ["html5lib", "pytest"]
[[package]]
name = "sphinxcontrib-jsmath"
version = "1.0.1"
description = "A sphinx extension which renders display math in HTML via JavaScript"
category = "main"
optional = true
python-versions = ">=3.5"
[package.extras]
test = ["flake8", "mypy", "pytest"]
[[package]]
name = "sphinxcontrib-qthelp"
version = "1.0.3"
description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document."
category = "main"
optional = true
python-versions = ">=3.5"
[package.extras]
lint = ["docutils-stubs", "flake8", "mypy"]
test = ["pytest"]
[[package]]
name = "sphinxcontrib-serializinghtml"
version = "1.1.5"
description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)."
category = "main"
optional = true
python-versions = ">=3.5"
[package.extras]
lint = ["docutils-stubs", "flake8", "mypy"]
test = ["pytest"]
[[package]]
name = "tomli"
version = "2.0.1"
description = "A lil' TOML parser"
category = "dev"
optional = false
python-versions = ">=3.7"
[[package]]
name = "typing-extensions"
version = "4.3.0"
description = "Backported and Experimental Type Hints for Python 3.7+"
category = "main"
optional = true
python-versions = ">=3.7"
[[package]]
name = "urllib3"
version = "1.26.11"
description = "HTTP library with thread-safe connection pooling, file post, and more."
category = "main"
optional = true
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4"
[package.extras]
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"]
secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)"]
socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
[[package]]
name = "webcolors"
version = "1.12"
description = "A library for working with color names and color values formats defined by HTML and CSS."
category = "main"
optional = false
python-versions = ">=3.7"
[[package]]
name = "zipp"
version = "3.8.1"
description = "Backport of pathlib-compatible object wrapper for zip files"
category = "main"
optional = true
python-versions = ">=3.7"
[package.extras]
docs = ["jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx"]
testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"]
[extras]
docs = ["myst-parser", "Sphinx", "sphinx-rtd-theme"]
[metadata]
lock-version = "1.1"
python-versions = "^3.9"
content-hash = "cc1b77fa653e3c4a09c36133586dfc1bd6ec69284c6cbfa61235c85db1b3d901"
[metadata.files]
alabaster = [
{file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"},
{file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"},
]
async-timeout = [
{file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"},
{file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"},
]
atomicwrites = [
{file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"},
]
attrs = [
{file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"},
{file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"},
]
babel = [
{file = "Babel-2.10.3-py3-none-any.whl", hash = "sha256:ff56f4892c1c4bf0d814575ea23471c230d544203c7748e8c68f0089478d48eb"},
{file = "Babel-2.10.3.tar.gz", hash = "sha256:7614553711ee97490f732126dc077f8d0ae084ebc6a96e23db1482afabdb2c51"},
]
bleak = [
{file = "bleak-0.19.0-py3-none-any.whl", hash = "sha256:ccdba0d17dcceb1326e4e46600b37e9019cd52ce01948e2a3dbd6c94d1e4de01"},
{file = "bleak-0.19.0.tar.gz", hash = "sha256:cce5200ca9bac7daaa74dd009c867c8c2b161a124e234c74307462e86caf50e6"},
]
bleak-retry-connector = [
{file = "bleak_retry_connector-2.3.0-py3-none-any.whl", hash = "sha256:251bd30720e908ec371c8ad5e4893a14d4e7700897d3a4a4e29f0722b2d2c499"},
{file = "bleak_retry_connector-2.3.0.tar.gz", hash = "sha256:58c159aa3b3ecef9f3d63beb19923279ab3c77c7cca3a0cc82cc6daae3c93637"},
]
bleak-winrt = [
{file = "bleak-winrt-1.2.0.tar.gz", hash = "sha256:0577d070251b9354fc6c45ffac57e39341ebb08ead014b1bdbd43e211d2ce1d6"},
{file = "bleak_winrt-1.2.0-cp310-cp310-win32.whl", hash = "sha256:a2ae3054d6843ae0cfd3b94c83293a1dfd5804393977dd69bde91cb5099fc47c"},
{file = "bleak_winrt-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:677df51dc825c6657b3ae94f00bd09b8ab88422b40d6a7bdbf7972a63bc44e9a"},
{file = "bleak_winrt-1.2.0-cp311-cp311-win32.whl", hash = "sha256:9449cdb942f22c9892bc1ada99e2ccce9bea8a8af1493e81fefb6de2cb3a7b80"},
{file = "bleak_winrt-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:98c1b5a6a6c431ac7f76aa4285b752fe14a1c626bd8a1dfa56f66173ff120bee"},
{file = "bleak_winrt-1.2.0-cp37-cp37m-win32.whl", hash = "sha256:623ac511696e1f58d83cb9c431e32f613395f2199b3db7f125a3d872cab968a4"},
{file = "bleak_winrt-1.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:13ab06dec55469cf51a2c187be7b630a7a2922e1ea9ac1998135974a7239b1e3"},
{file = "bleak_winrt-1.2.0-cp38-cp38-win32.whl", hash = "sha256:5a36ff8cd53068c01a795a75d2c13054ddc5f99ce6de62c1a97cd343fc4d0727"},
{file = "bleak_winrt-1.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:810c00726653a962256b7acd8edf81ab9e4a3c66e936a342ce4aec7dbd3a7263"},
{file = "bleak_winrt-1.2.0-cp39-cp39-win32.whl", hash = "sha256:dd740047a08925bde54bec357391fcee595d7b8ca0c74c87170a5cbc3f97aa0a"},
{file = "bleak_winrt-1.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:63130c11acfe75c504a79c01f9919e87f009f5e742bfc7b7a5c2a9c72bf591a7"},
]
certifi = [
{file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"},
{file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"},
]
charset-normalizer = [
{file = "charset-normalizer-2.1.0.tar.gz", hash = "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413"},
{file = "charset_normalizer-2.1.0-py3-none-any.whl", hash = "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5"},
]
colorama = [
{file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"},
{file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"},
]
coverage = [
{file = "coverage-6.4.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7b4da9bafad21ea45a714d3ea6f3e1679099e420c8741c74905b92ee9bfa7cc"},
{file = "coverage-6.4.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fde17bc42e0716c94bf19d92e4c9f5a00c5feb401f5bc01101fdf2a8b7cacf60"},
{file = "coverage-6.4.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdbb0d89923c80dbd435b9cf8bba0ff55585a3cdb28cbec65f376c041472c60d"},
{file = "coverage-6.4.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:67f9346aeebea54e845d29b487eb38ec95f2ecf3558a3cffb26ee3f0dcc3e760"},
{file = "coverage-6.4.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42c499c14efd858b98c4e03595bf914089b98400d30789511577aa44607a1b74"},
{file = "coverage-6.4.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c35cca192ba700979d20ac43024a82b9b32a60da2f983bec6c0f5b84aead635c"},
{file = "coverage-6.4.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9cc4f107009bca5a81caef2fca843dbec4215c05e917a59dec0c8db5cff1d2aa"},
{file = "coverage-6.4.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5f444627b3664b80d078c05fe6a850dd711beeb90d26731f11d492dcbadb6973"},
{file = "coverage-6.4.4-cp310-cp310-win32.whl", hash = "sha256:66e6df3ac4659a435677d8cd40e8eb1ac7219345d27c41145991ee9bf4b806a0"},
{file = "coverage-6.4.4-cp310-cp310-win_amd64.whl", hash = "sha256:35ef1f8d8a7a275aa7410d2f2c60fa6443f4a64fae9be671ec0696a68525b875"},
{file = "coverage-6.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c1328d0c2f194ffda30a45f11058c02410e679456276bfa0bbe0b0ee87225fac"},
{file = "coverage-6.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61b993f3998ee384935ee423c3d40894e93277f12482f6e777642a0141f55782"},
{file = "coverage-6.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d5dd4b8e9cd0deb60e6fcc7b0647cbc1da6c33b9e786f9c79721fd303994832f"},
{file = "coverage-6.4.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7026f5afe0d1a933685d8f2169d7c2d2e624f6255fb584ca99ccca8c0e966fd7"},
{file = "coverage-6.4.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9c7b9b498eb0c0d48b4c2abc0e10c2d78912203f972e0e63e3c9dc21f15abdaa"},
{file = "coverage-6.4.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ee2b2fb6eb4ace35805f434e0f6409444e1466a47f620d1d5763a22600f0f892"},
{file = "coverage-6.4.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ab066f5ab67059d1f1000b5e1aa8bbd75b6ed1fc0014559aea41a9eb66fc2ce0"},
{file = "coverage-6.4.4-cp311-cp311-win32.whl", hash = "sha256:9d6e1f3185cbfd3d91ac77ea065d85d5215d3dfa45b191d14ddfcd952fa53796"},
{file = "coverage-6.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:e3d3c4cc38b2882f9a15bafd30aec079582b819bec1b8afdbde8f7797008108a"},
{file = "coverage-6.4.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a095aa0a996ea08b10580908e88fbaf81ecf798e923bbe64fb98d1807db3d68a"},
{file = "coverage-6.4.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef6f44409ab02e202b31a05dd6666797f9de2aa2b4b3534e9d450e42dea5e817"},
{file = "coverage-6.4.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b7101938584d67e6f45f0015b60e24a95bf8dea19836b1709a80342e01b472f"},
{file = "coverage-6.4.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14a32ec68d721c3d714d9b105c7acf8e0f8a4f4734c811eda75ff3718570b5e3"},
{file = "coverage-6.4.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6a864733b22d3081749450466ac80698fe39c91cb6849b2ef8752fd7482011f3"},
{file = "coverage-6.4.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:08002f9251f51afdcc5e3adf5d5d66bb490ae893d9e21359b085f0e03390a820"},
{file = "coverage-6.4.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a3b2752de32c455f2521a51bd3ffb53c5b3ae92736afde67ce83477f5c1dd928"},
{file = "coverage-6.4.4-cp37-cp37m-win32.whl", hash = "sha256:f855b39e4f75abd0dfbcf74a82e84ae3fc260d523fcb3532786bcbbcb158322c"},
{file = "coverage-6.4.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ee6ae6bbcac0786807295e9687169fba80cb0617852b2fa118a99667e8e6815d"},
{file = "coverage-6.4.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:564cd0f5b5470094df06fab676c6d77547abfdcb09b6c29c8a97c41ad03b103c"},
{file = "coverage-6.4.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cbbb0e4cd8ddcd5ef47641cfac97d8473ab6b132dd9a46bacb18872828031685"},
{file = "coverage-6.4.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6113e4df2fa73b80f77663445be6d567913fb3b82a86ceb64e44ae0e4b695de1"},
{file = "coverage-6.4.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d032bfc562a52318ae05047a6eb801ff31ccee172dc0d2504614e911d8fa83e"},
{file = "coverage-6.4.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e431e305a1f3126477abe9a184624a85308da8edf8486a863601d58419d26ffa"},
{file = "coverage-6.4.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:cf2afe83a53f77aec067033199797832617890e15bed42f4a1a93ea24794ae3e"},
{file = "coverage-6.4.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:783bc7c4ee524039ca13b6d9b4186a67f8e63d91342c713e88c1865a38d0892a"},
{file = "coverage-6.4.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ff934ced84054b9018665ca3967fc48e1ac99e811f6cc99ea65978e1d384454b"},
{file = "coverage-6.4.4-cp38-cp38-win32.whl", hash = "sha256:e1fabd473566fce2cf18ea41171d92814e4ef1495e04471786cbc943b89a3781"},
{file = "coverage-6.4.4-cp38-cp38-win_amd64.whl", hash = "sha256:4179502f210ebed3ccfe2f78bf8e2d59e50b297b598b100d6c6e3341053066a2"},
{file = "coverage-6.4.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:98c0b9e9b572893cdb0a00e66cf961a238f8d870d4e1dc8e679eb8bdc2eb1b86"},
{file = "coverage-6.4.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc600f6ec19b273da1d85817eda339fb46ce9eef3e89f220055d8696e0a06908"},
{file = "coverage-6.4.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a98d6bf6d4ca5c07a600c7b4e0c5350cd483c85c736c522b786be90ea5bac4f"},
{file = "coverage-6.4.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01778769097dbd705a24e221f42be885c544bb91251747a8a3efdec6eb4788f2"},
{file = "coverage-6.4.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfa0b97eb904255e2ab24166071b27408f1f69c8fbda58e9c0972804851e0558"},
{file = "coverage-6.4.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:fcbe3d9a53e013f8ab88734d7e517eb2cd06b7e689bedf22c0eb68db5e4a0a19"},
{file = "coverage-6.4.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:15e38d853ee224e92ccc9a851457fb1e1f12d7a5df5ae44544ce7863691c7a0d"},
{file = "coverage-6.4.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6913dddee2deff8ab2512639c5168c3e80b3ebb0f818fed22048ee46f735351a"},
{file = "coverage-6.4.4-cp39-cp39-win32.whl", hash = "sha256:354df19fefd03b9a13132fa6643527ef7905712109d9c1c1903f2133d3a4e145"},
{file = "coverage-6.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:1238b08f3576201ebf41f7c20bf59baa0d05da941b123c6656e42cdb668e9827"},
{file = "coverage-6.4.4-pp36.pp37.pp38-none-any.whl", hash = "sha256:f67cf9f406cf0d2f08a3515ce2db5b82625a7257f88aad87904674def6ddaec1"},
{file = "coverage-6.4.4.tar.gz", hash = "sha256:e16c45b726acb780e1e6f88b286d3c10b3914ab03438f32117c4aa52d7f30d58"},
]
dbus-fast = [
{file = "dbus_fast-1.45.0-cp310-cp310-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:a80d284d72ebc9893943e6be705866d72dfa37ce7534cd274e7ab1cd86b0a829"},
{file = "dbus_fast-1.45.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8250cfafb1f875fe0204bbea49419ee8c72ff834c40f22765ac39c54ba1b8fd3"},
{file = "dbus_fast-1.45.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5d092874c16d5f64dd5c164cbf84da151a6565fa21aa518da8cf4178e2b9df0c"},
{file = "dbus_fast-1.45.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:552e145b1fdb98922cc83b24fb8677ee63029628f19bb7b2f1aca075c3208945"},
{file = "dbus_fast-1.45.0-cp311-cp311-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:eb30d3d70deff8145ceedad15b7030fcc0d9b5411b84f0b80ba1f6581f83fec0"},
{file = "dbus_fast-1.45.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40050d56f59be198486fc0ad1a7b4aba16928a31c89f84e98cd58ea332186a9f"},
{file = "dbus_fast-1.45.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:10bc728544b95204abb9717941272146a9ba671ee7e6e93a697e4a17e93840c2"},
{file = "dbus_fast-1.45.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9ca3b008892aff4e0fa5a8046a8492043f5108502f3105a09f676749855d130e"},
{file = "dbus_fast-1.45.0-cp37-cp37m-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:24561a1a31de35fef7d59b285e5e5b5c1c76b7eb4e9047dcaf0a726627204b6c"},
{file = "dbus_fast-1.45.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c6286bd0a9a3ef0a65dfb666df07bd77efa0d6f1798afe5dabc14437cd5ed6a"},
{file = "dbus_fast-1.45.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:48e09ae676c87ca4fbc58881f0c0d6c41a67d87610878c9ed3a6692fc0368b29"},
{file = "dbus_fast-1.45.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a1d81da92f2438164b8ebea566972e0706313e46490f8cc2a2c5480adc50b238"},
{file = "dbus_fast-1.45.0-cp38-cp38-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:9a838a2bb353079ad4a040c697099be6481d908ae063810d28e086c259bd2786"},
{file = "dbus_fast-1.45.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d69a6b90ba45ace831cb6e9b5ad0c0850fed8bec95591d35edafedbeac323135"},
{file = "dbus_fast-1.45.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ed0d2c86fe4c98c8f685adab6b4c18307855b7198fe8cd78971e8e1dac1e3c68"},
{file = "dbus_fast-1.45.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:77ca7d27648a09fc38e54aa6289a1eb32214ac72e64bfa46a12c6161ddd3c984"},
{file = "dbus_fast-1.45.0-cp39-cp39-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:b673c1810010625ef8e9a0df314267b9e7b597828412caa337716efebbdfbf05"},
{file = "dbus_fast-1.45.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3292370b9f07da9bced35915b0e5b3930d24a642d18400462ab3be4af9ef552c"},
{file = "dbus_fast-1.45.0-cp39-cp39-manylinux_2_31_x86_64.whl", hash = "sha256:9323a530b952aa0a6e5cd9cb00b150f74cc2ea2c519fe01e13d5d635f2607d9a"},
{file = "dbus_fast-1.45.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a77dcb8c11e1685ae1d3600b9e8260ca5c9daaa9526664112af2f1bdcbee280d"},
{file = "dbus_fast-1.45.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7ff3c131469b6f90a52c953d853a0a97dced5dc6678496b12657aaa1e014ca78"},
{file = "dbus_fast-1.45.0-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:2685caab65ddb2e7b3aed6dc17a214bb1f7cfd6164f4895bee167ecd5463d71e"},
{file = "dbus_fast-1.45.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5bef4860104bc3580e49a70928d6f05085c9911f842efe12f099539092a4f94"},
{file = "dbus_fast-1.45.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:2cfdabca35a48172d19c56bc149c9ce76f94a747e243a3cfd7c115751988800d"},
{file = "dbus_fast-1.45.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:27eff54c50e752e213d98dbf9dfc2d98a8109dfa9c1314eab5074aef3ea45f51"},
{file = "dbus_fast-1.45.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:2f7ede9ad484d38d63d33b5b54757a885d6a36569d5cfed6d1a7969576396d21"},
{file = "dbus_fast-1.45.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed5e612d0c66fe204030b5c6513cd132203d0a32030e2b6d9ed84b26409959aa"},
{file = "dbus_fast-1.45.0.tar.gz", hash = "sha256:ed5204b265f316f1a5ab52de3d857038532945b4645a0ff73e6dbb9622747117"},
]
docutils = [
{file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"},
{file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"},
]
flux-led = [
{file = "flux_led-0.28.32-py3-none-any.whl", hash = "sha256:0a8a2f52a1e494f5273ba2d5cc5955f39cc948ffe1e81152b1115bcad67c94e0"},
{file = "flux_led-0.28.32.tar.gz", hash = "sha256:931a690b570a93ccb1c71d62786dafd6f5e25358edcabaea41ed5a17a0b2a2ba"},
]
idna = [
{file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
{file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"},
]
imagesize = [
{file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"},
{file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"},
]
importlib-metadata = [
{file = "importlib_metadata-4.12.0-py3-none-any.whl", hash = "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23"},
{file = "importlib_metadata-4.12.0.tar.gz", hash = "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670"},
]
iniconfig = [
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
]
jinja2 = [
{file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
{file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
]
markdown-it-py = [
{file = "markdown-it-py-2.1.0.tar.gz", hash = "sha256:cf7e59fed14b5ae17c0006eff14a2d9a00ed5f3a846148153899a0224e2c07da"},
{file = "markdown_it_py-2.1.0-py3-none-any.whl", hash = "sha256:93de681e5c021a432c63147656fe21790bc01231e0cd2da73626f1aa3ac0fe27"},
]
markupsafe = [
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"},
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"},
{file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"},
{file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"},
{file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"},
{file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"},
{file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"},
{file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"},
{file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"},
{file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"},
{file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"},
{file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"},
{file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"},
{file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"},
{file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"},
{file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"},
{file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"},
{file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"},
{file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"},
{file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"},
{file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"},
{file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"},
{file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"},
{file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"},
{file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"},
{file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"},
{file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"},
{file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"},
{file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"},
{file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"},
{file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"},
{file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"},
{file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"},
{file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"},
{file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"},
{file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"},
{file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"},
{file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"},
{file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"},
{file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"},
]
mdit-py-plugins = [
{file = "mdit-py-plugins-0.3.0.tar.gz", hash = "sha256:ecc24f51eeec6ab7eecc2f9724e8272c2fb191c2e93cf98109120c2cace69750"},
{file = "mdit_py_plugins-0.3.0-py3-none-any.whl", hash = "sha256:b1279701cee2dbf50e188d3da5f51fee8d78d038cdf99be57c6b9d1aa93b4073"},
]
mdurl = [
{file = "mdurl-0.1.1-py3-none-any.whl", hash = "sha256:6a8f6804087b7128040b2fb2ebe242bdc2affaeaa034d5fc9feeed30b443651b"},
{file = "mdurl-0.1.1.tar.gz", hash = "sha256:f79c9709944df218a4cdb0fcc0b0c7ead2f44594e3e84dc566606f04ad749c20"},
]
myst-parser = [
{file = "myst-parser-0.18.0.tar.gz", hash = "sha256:739a4d96773a8e55a2cacd3941ce46a446ee23dcd6b37e06f73f551ad7821d86"},
{file = "myst_parser-0.18.0-py3-none-any.whl", hash = "sha256:4965e51918837c13bf1c6f6fe2c6bddddf193148360fbdaefe743a4981358f6a"},
]
packaging = [
{file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
{file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
]
pluggy = [
{file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
{file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
]
py = [
{file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
{file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
]
pygments = [
{file = "Pygments-2.12.0-py3-none-any.whl", hash = "sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519"},
{file = "Pygments-2.12.0.tar.gz", hash = "sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb"},
]
pyobjc-core = [
{file = "pyobjc-core-8.5.1.tar.gz", hash = "sha256:f8592a12de076c27006700c4a46164478564fa33d7da41e7cbdd0a3bf9ddbccf"},
{file = "pyobjc_core-8.5.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b62dcf987cc511188fc2aa5b4d3b9fd895361ea4984380463497ce4b0752ddf4"},
{file = "pyobjc_core-8.5.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0accc653501a655f66c13f149a1d3d30e6cb65824edf852f7960a00c4f930d5b"},
{file = "pyobjc_core-8.5.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f82b32affc898e9e5af041c1cecde2c99f2ce160b87df77f678c99f1550a4655"},
{file = "pyobjc_core-8.5.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f7b2f6b6f3caeb882c658fe0c7098be2e8b79893d84daa8e636cb3e58a07df00"},
{file = "pyobjc_core-8.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:872c0202c911a5a2f1269261c168e36569f6ddac17e5d854ac19e581726570cc"},
{file = "pyobjc_core-8.5.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:21f92e231a4bae7f2d160d065f5afbf5e859a1e37f29d34ac12592205fc8c108"},
{file = "pyobjc_core-8.5.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:315334dd09781129af6a39641248891c4caa57043901750b0139c6614ce84ec0"},
]
pyobjc-framework-Cocoa = [
{file = "pyobjc-framework-Cocoa-8.5.1.tar.gz", hash = "sha256:9a3de5cdb4644e85daf53f2ed912ef6c16ea5804a9e65552eafe62c2e139eb8c"},
{file = "pyobjc_framework_Cocoa-8.5.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:aa572acc2628488a47be8d19f4701fc96fce7377cc4da18316e1e08c3918521a"},
{file = "pyobjc_framework_Cocoa-8.5.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cb3ae21c8d81b7f02a891088c623cef61bca89bd671eff58c632d2f926b649f3"},
{file = "pyobjc_framework_Cocoa-8.5.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:88f08f5bd94c66d373d8413c1d08218aff4cff0b586e0cc4249b2284023e7577"},
{file = "pyobjc_framework_Cocoa-8.5.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:063683b57e4bd88cb0f9631ae65d25ec4eecf427d2fe8d0c578f88da9c896f3f"},
{file = "pyobjc_framework_Cocoa-8.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8f8806ddfac40620fb27f185d0f8937e69e330617319ecc2eccf6b9c8451bdd1"},
{file = "pyobjc_framework_Cocoa-8.5.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:7733a9a201df9e0cc2a0cf7bf54d76bd7981cba9b599353b243e3e0c9eefec10"},
{file = "pyobjc_framework_Cocoa-8.5.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f0ab227f99d3e25dd3db73f8cde0999914a5f0dd6a08600349d25f95eaa0da63"},
]
pyobjc-framework-CoreBluetooth = [
{file = "pyobjc-framework-CoreBluetooth-8.5.1.tar.gz", hash = "sha256:b4f621fc3b5bf289db58e64fd746773b18297f87a0ffc5502de74f69133301c1"},
{file = "pyobjc_framework_CoreBluetooth-8.5.1-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:bc720f2987a4d28dc73b13146e7c104d717100deb75c244da68f1d0849096661"},
{file = "pyobjc_framework_CoreBluetooth-8.5.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:2167f22886beb5b3ae69e475e055403f28eab065c49a25e2b98b050b483be799"},
{file = "pyobjc_framework_CoreBluetooth-8.5.1-cp36-abi3-macosx_11_0_universal2.whl", hash = "sha256:aa9587a36eca143701731e8bb6c369148f8cc48c28168d41e7323828e5117f2d"},
]
pyobjc-framework-libdispatch = [
{file = "pyobjc-framework-libdispatch-8.5.1.tar.gz", hash = "sha256:066fb34fceb326307559104d45532ec2c7b55426f9910b70dbefd5d1b8fd530f"},
{file = "pyobjc_framework_libdispatch-8.5.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a316646ab30ba2a97bc828f8e27e7bb79efdf993d218a9c5118396b4f81dc762"},
{file = "pyobjc_framework_libdispatch-8.5.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7730a29e4d9c7d8c2e8d9ffb60af0ab6699b2186296d2bff0a2dd54527578bc3"},
{file = "pyobjc_framework_libdispatch-8.5.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:76208d9d2b0071df2950800495ac0300360bb5f25cbe9ab880b65cb809764979"},
{file = "pyobjc_framework_libdispatch-8.5.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:1ad9aa4773ff1d89bf4385c081824c4f8708b50e3ac2fe0a9d590153242c0f67"},
{file = "pyobjc_framework_libdispatch-8.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:81e1833bd26f15930faba678f9efdffafc79ec04e2ea8b6d1b88cafc0883af97"},
{file = "pyobjc_framework_libdispatch-8.5.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:73226e224436eb6383e7a8a811c90ed597995adb155b4f46d727881a383ac550"},
{file = "pyobjc_framework_libdispatch-8.5.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d115355ce446fc073c75cedfd7ab0a13958adda8e3a3b1e421e1f1e5f65640da"},
]
pyparsing = [
{file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
{file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
]
pytest = [
{file = "pytest-7.1.2-py3-none-any.whl", hash = "sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c"},
{file = "pytest-7.1.2.tar.gz", hash = "sha256:a06a0425453864a270bc45e71f783330a7428defb4230fb5e6a731fde06ecd45"},
]
pytest-cov = [
{file = "pytest-cov-3.0.0.tar.gz", hash = "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470"},
{file = "pytest_cov-3.0.0-py3-none-any.whl", hash = "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6"},
]
pytz = [
{file = "pytz-2022.1-py2.py3-none-any.whl", hash = "sha256:e68985985296d9a66a881eb3193b0906246245294a881e7c8afe623866ac6a5c"},
{file = "pytz-2022.1.tar.gz", hash = "sha256:1e760e2fe6a8163bc0b3d9a19c4f84342afa0a2affebfaa84b01b978a02ecaa7"},
]
pyyaml = [
{file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"},
{file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"},
{file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"},
{file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"},
{file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"},
{file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"},
{file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"},
{file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"},
{file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"},
{file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"},
{file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"},
{file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"},
{file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"},
{file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"},
{file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"},
{file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"},
{file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"},
{file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"},
{file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"},
{file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"},
{file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"},
{file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"},
{file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"},
{file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"},
{file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"},
{file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"},
{file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"},
{file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"},
{file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"},
{file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"},
{file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"},
{file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"},
{file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
]
requests = [
{file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"},
{file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"},
]
snowballstemmer = [
{file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
{file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
]
sphinx = [
{file = "Sphinx-5.1.1-py3-none-any.whl", hash = "sha256:309a8da80cb6da9f4713438e5b55861877d5d7976b69d87e336733637ea12693"},
{file = "Sphinx-5.1.1.tar.gz", hash = "sha256:ba3224a4e206e1fbdecf98a4fae4992ef9b24b85ebf7b584bb340156eaf08d89"},
]
sphinx-rtd-theme = [
{file = "sphinx_rtd_theme-1.0.0-py2.py3-none-any.whl", hash = "sha256:4d35a56f4508cfee4c4fb604373ede6feae2a306731d533f409ef5c3496fdbd8"},
{file = "sphinx_rtd_theme-1.0.0.tar.gz", hash = "sha256:eec6d497e4c2195fa0e8b2016b337532b8a699a68bcb22a512870e16925c6a5c"},
]
sphinxcontrib-applehelp = [
{file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"},
{file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"},
]
sphinxcontrib-devhelp = [
{file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"},
{file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"},
]
sphinxcontrib-htmlhelp = [
{file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"},
{file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"},
]
sphinxcontrib-jsmath = [
{file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"},
{file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"},
]
sphinxcontrib-qthelp = [
{file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"},
{file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"},
]
sphinxcontrib-serializinghtml = [
{file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"},
{file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"},
]
tomli = [
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
]
typing-extensions = [
{file = "typing_extensions-4.3.0-py3-none-any.whl", hash = "sha256:25642c956049920a5aa49edcdd6ab1e06d7e5d467fc00e0506c44ac86fbfca02"},
{file = "typing_extensions-4.3.0.tar.gz", hash = "sha256:e6d2677a32f47fc7eb2795db1dd15c1f34eff616bcaf2cfb5e997f854fa1c4a6"},
]
urllib3 = [
{file = "urllib3-1.26.11-py2.py3-none-any.whl", hash = "sha256:c33ccba33c819596124764c23a97d25f32b28433ba0dedeb77d873a38722c9bc"},
{file = "urllib3-1.26.11.tar.gz", hash = "sha256:ea6e8fb210b19d950fab93b60c9009226c63a28808bc8386e05301e25883ac0a"},
]
webcolors = [
{file = "webcolors-1.12-py3-none-any.whl", hash = "sha256:d98743d81d498a2d3eaf165196e65481f0d2ea85281463d856b1e51b09f62dce"},
{file = "webcolors-1.12.tar.gz", hash = "sha256:16d043d3a08fd6a1b1b7e3e9e62640d09790dce80d2bdd4792a175b35fe794a9"},
]
zipp = [
{file = "zipp-3.8.1-py3-none-any.whl", hash = "sha256:47c40d7fe183a6f21403a199b3e4192cca5774656965b0a4988ad2f8feb5f009"},
{file = "zipp-3.8.1.tar.gz", hash = "sha256:05b45f1ee8f807d0cc928485ca40a07cb491cf092ff587c0df9cb1fd154848d2"},
]
930913-ld2410-ble-6c24cfb/pyproject.toml 0000664 0000000 0000000 00000004465 14366747107 0017365 0 ustar 00root root 0000000 0000000 [tool.poetry]
name = "ld2410-ble"
version = "0.2.0"
description = "Interface with LD2410B modules from HiLink"
authors = ["930913 <3722064+930913@users.noreply.github.com>"]
license = "Apache Software License 2.0"
readme = "README.md"
repository = "https://github.com/930913/ld2410-ble"
documentation = "https://ld2410-ble.readthedocs.io"
classifiers = [
"Development Status :: 2 - Pre-Alpha",
"Intended Audience :: Developers",
"Natural Language :: English",
"Operating System :: OS Independent",
"Topic :: Software Development :: Libraries",
]
packages = [
{ include = "ld2410_ble", from = "src" },
]
[tool.poetry.urls]
"Bug Tracker" = "https://github.com/930913/ld2410-ble/issues"
"Changelog" = "https://github.com/930913/ld2410-ble/blob/main/CHANGELOG.md"
[tool.poetry.dependencies]
python = "^3.9"
# Documentation Dependencies
Sphinx = {version = "^5.0", optional = true}
sphinx-rtd-theme = {version = "^1.0", optional = true}
myst-parser = {version = "^0.18", optional = true}
bleak-retry-connector = ">=2.3.0"
bleak = ">=0.19.0"
async-timeout = ">=4.0.1"
[tool.poetry.extras]
docs = [
"myst-parser",
"sphinx",
"sphinx-rtd-theme",
]
[tool.poetry.dev-dependencies]
pytest = "^7.0"
pytest-cov = "^3.0"
[tool.semantic_release]
branch = "main"
version_toml = "pyproject.toml:tool.poetry.version"
version_variable = "src/ld2410_ble/__init__.py:__version__"
build_command = "pip install poetry && poetry build"
[tool.pytest.ini_options]
addopts = "-v -Wdefault --cov=ld2410_ble --cov-report=term-missing:skip-covered"
pythonpath = ["src"]
[tool.coverage.run]
branch = true
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"@overload",
"if TYPE_CHECKING",
"raise NotImplementedError",
]
[tool.isort]
profile = "black"
known_first_party = ["ld2410_ble", "tests"]
[tool.mypy]
check_untyped_defs = true
disallow_any_generics = true
disallow_incomplete_defs = true
disallow_untyped_defs = true
mypy_path = "src/"
no_implicit_optional = true
show_error_codes = true
warn_unreachable = true
warn_unused_ignores = true
exclude = [
'docs/.*',
'setup.py',
]
[[tool.mypy.overrides]]
module = "tests.*"
allow_untyped_defs = true
[[tool.mypy.overrides]]
module = "docs.*"
ignore_errors = true
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
930913-ld2410-ble-6c24cfb/renovate.json 0000664 0000000 0000000 00000000101 14366747107 0017146 0 ustar 00root root 0000000 0000000 {
"extends": ["github>browniebroke/renovate-configs:python"]
}
930913-ld2410-ble-6c24cfb/setup.py 0000664 0000000 0000000 00000000360 14366747107 0016151 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python
# This is a shim to allow GitHub to detect the package, build is done with poetry
# Taken from https://github.com/Textualize/rich
import setuptools
if __name__ == "__main__":
setuptools.setup(name="ld2410-ble")
930913-ld2410-ble-6c24cfb/src/ 0000775 0000000 0000000 00000000000 14366747107 0015227 5 ustar 00root root 0000000 0000000 930913-ld2410-ble-6c24cfb/src/ld2410_ble/ 0000775 0000000 0000000 00000000000 14366747107 0016757 5 ustar 00root root 0000000 0000000 930913-ld2410-ble-6c24cfb/src/ld2410_ble/__init__.py 0000664 0000000 0000000 00000000543 14366747107 0021072 0 ustar 00root root 0000000 0000000 from __future__ import annotations
__version__ = "0.2.0"
from bleak_retry_connector import get_device
from .exceptions import CharacteristicMissingError
from .ld2410_ble import BLEAK_EXCEPTIONS, LD2410BLE, LD2410BLEState
__all__ = [
"BLEAK_EXCEPTIONS",
"CharacteristicMissingError",
"LD2410BLE",
"LD2410BLEState",
"get_device",
]
930913-ld2410-ble-6c24cfb/src/ld2410_ble/const.py 0000664 0000000 0000000 00000003765 14366747107 0020472 0 ustar 00root root 0000000 0000000 CHARACTERISTIC_NOTIFY = "0000fff1-0000-1000-8000-00805f9b34fb"
CHARACTERISTIC_WRITE = "0000fff2-0000-1000-8000-00805f9b34fb"
CMD_BT_PASS_PRE = b"\xfd\xfc\xfb\xfa\x08\x00\xa8\x00"
CMD_BT_PASS_DEFAULT = b"HiLink"
CMD_BT_PASS_POST = b"\x04\x03\x02\x01"
CMD_ENABLE_CONFIG = b"\xfd\xfc\xfb\xfa\x04\x00\xff\x00\x01\x00\x04\x03\x02\x01"
CMD_ENABLE_ENGINEERING_MODE = b"\xfd\xfc\xfb\xfa\x02\x00b\x00\x04\x03\x02\x01"
CMD_DISABLE_CONFIG = b"\xfd\xfc\xfb\xfa\x02\x00\xfe\x00\x04\x03\x02\x01"
MOVING_TARGET = 1
STATIC_TARGET = 2
frame_start = b"\xf4\xf3\xf2\xf1"
frame_length = b"(?P..)"
frame_engineering_mode = b"(?P\x01|\x02)"
frame_head = b"\xaa"
frame_target_state = b"(?P\x00|\x01|\x02|\x03)"
frame_moving_target_distance = b"(?P..)"
frame_moving_target_energy = b"(?P.)"
frame_static_target_distance = b"(?P..)"
frame_static_target_energy = b"(?P.)"
frame_detection_distance = b"(?P..)"
frame_engineering_data = b"(?P.+?)?"
frame_tail = b"\x55"
frame_check = b"\x00"
frame_end = b"\xf8\xf7\xf6\xf5"
frame_maximum_motion_gates = b"(?P.)"
frame_maximum_static_gates = b"(?P.)"
frame_motion_energy_gates = b"(?P.{9})"
frame_static_energy_gates = b"(?P.{9})"
frame_additional_information = b"(?P.*)"
frame_regex = (
frame_start
+ frame_length
+ frame_engineering_mode
+ frame_head
+ frame_target_state
+ frame_moving_target_distance
+ frame_moving_target_energy
+ frame_static_target_distance
+ frame_static_target_energy
+ frame_detection_distance
+ frame_engineering_data
+ frame_tail
+ frame_check
+ frame_end
)
engineering_frame_regex = (
frame_maximum_motion_gates
+ frame_maximum_static_gates
+ frame_motion_energy_gates
+ frame_static_energy_gates
+ frame_additional_information
)
930913-ld2410-ble-6c24cfb/src/ld2410_ble/exceptions.py 0000664 0000000 0000000 00000000140 14366747107 0021505 0 ustar 00root root 0000000 0000000 class CharacteristicMissingError(Exception):
"""Raised when a characteristic is missing."""
930913-ld2410-ble-6c24cfb/src/ld2410_ble/ld2410_ble.py 0000664 0000000 0000000 00000043270 14366747107 0021067 0 ustar 00root root 0000000 0000000 from __future__ import annotations
import asyncio
import logging
import re
import sys
from collections.abc import Callable
from typing import Any, TypeVar
from bleak.backends.device import BLEDevice
from bleak.backends.scanner import AdvertisementData
from bleak.exc import BleakDBusError
from bleak_retry_connector import BLEAK_RETRY_EXCEPTIONS as BLEAK_EXCEPTIONS
from bleak_retry_connector import (
BleakClientWithServiceCache,
BleakError,
BleakNotFoundError,
establish_connection,
retry_bluetooth_connection_error,
)
from .const import (
CHARACTERISTIC_NOTIFY,
CHARACTERISTIC_WRITE,
CMD_BT_PASS_DEFAULT,
CMD_BT_PASS_POST,
CMD_BT_PASS_PRE,
CMD_DISABLE_CONFIG,
CMD_ENABLE_CONFIG,
CMD_ENABLE_ENGINEERING_MODE,
MOVING_TARGET,
STATIC_TARGET,
engineering_frame_regex,
frame_regex,
)
from .exceptions import CharacteristicMissingError
from .models import LD2410BLEState
BLEAK_BACKOFF_TIME = 0.25
__version__ = "0.0.0"
WrapFuncType = TypeVar("WrapFuncType", bound=Callable[..., Any])
RETRY_BACKOFF_EXCEPTIONS = (BleakDBusError,)
_LOGGER = logging.getLogger(__name__)
DEFAULT_ATTEMPTS = sys.maxsize
class LD2410BLE:
def __init__(
self,
ble_device: BLEDevice,
advertisement_data: AdvertisementData | None = None,
password: bytes = CMD_BT_PASS_DEFAULT,
) -> None:
"""Init the LD2410BLE."""
self._ble_device = ble_device
self._advertisement_data = advertisement_data
self._password = password
self._operation_lock = asyncio.Lock()
self._state = LD2410BLEState()
self._connect_lock: asyncio.Lock = asyncio.Lock()
self._client: BleakClientWithServiceCache | None = None
self._expected_disconnect = False
self.loop = asyncio.get_running_loop()
self._callbacks: list[Callable[[LD2410BLEState], None]] = []
self._disconnected_callbacks: list[Callable[[], None]] = []
self._buf = b""
def set_ble_device_and_advertisement_data(
self, ble_device: BLEDevice, advertisement_data: AdvertisementData
) -> None:
"""Set the ble device."""
self._ble_device = ble_device
self._advertisement_data = advertisement_data
@property
def address(self) -> str:
"""Return the address."""
return self._ble_device.address
@property
def _address(self) -> str:
"""Return the address."""
return self._ble_device.address
@property
def name(self) -> str:
"""Get the name of the device."""
return self._ble_device.name or self._ble_device.address
@property
def rssi(self) -> int | None:
"""Get the rssi of the device."""
if self._advertisement_data:
return self._advertisement_data.rssi
return None
@property
def state(self) -> LD2410BLEState:
"""Return the state."""
return self._state
@property
def is_moving(self) -> bool:
return self._state.is_moving
@property
def is_static(self) -> bool:
return self._state.is_static
@property
def moving_target_distance(self) -> int:
return self._state.moving_target_distance
@property
def moving_target_energy(self) -> int:
return self._state.moving_target_energy
@property
def static_target_distance(self) -> int:
return self._state.static_target_distance
@property
def static_target_energy(self) -> int:
return self._state.static_target_energy
@property
def detection_distance(self) -> int:
return self._state.detection_distance
@property
def max_motion_gates(self) -> int:
assert self._state.max_motion_gates is not None # nosec
return self._state.max_motion_gates
@property
def max_static_gates(self) -> int:
assert self._state.max_static_gates is not None # nosec
return self._state.max_static_gates
@property
def motion_energy_gates(self) -> list[int]:
assert self._state.motion_energy_gates is not None # nosec
return self._state.motion_energy_gates
@property
def motion_energy_gate_0(self) -> int:
assert self._state.motion_energy_gates is not None # nosec
return self._state.motion_energy_gates[0]
@property
def motion_energy_gate_1(self) -> int:
assert self._state.motion_energy_gates is not None # nosec
return self._state.motion_energy_gates[1]
@property
def motion_energy_gate_2(self) -> int:
assert self._state.motion_energy_gates is not None # nosec
return self._state.motion_energy_gates[2]
@property
def motion_energy_gate_3(self) -> int:
assert self._state.motion_energy_gates is not None # nosec
return self._state.motion_energy_gates[3]
@property
def motion_energy_gate_4(self) -> int:
assert self._state.motion_energy_gates is not None # nosec
return self._state.motion_energy_gates[4]
@property
def motion_energy_gate_5(self) -> int:
assert self._state.motion_energy_gates is not None # nosec
return self._state.motion_energy_gates[5]
@property
def motion_energy_gate_6(self) -> int:
assert self._state.motion_energy_gates is not None # nosec
return self._state.motion_energy_gates[6]
@property
def motion_energy_gate_7(self) -> int:
assert self._state.motion_energy_gates is not None # nosec
return self._state.motion_energy_gates[7]
@property
def motion_energy_gate_8(self) -> int:
assert self._state.motion_energy_gates is not None # nosec
return self._state.motion_energy_gates[8]
@property
def static_energy_gates(self) -> list[int]:
assert self._state.static_energy_gates is not None # nosec
return self._state.static_energy_gates
@property
def static_energy_gate_0(self) -> int:
assert self._state.static_energy_gates is not None # nosec
return self._state.static_energy_gates[0]
@property
def static_energy_gate_1(self) -> int:
assert self._state.static_energy_gates is not None # nosec
return self._state.static_energy_gates[1]
@property
def static_energy_gate_2(self) -> int:
assert self._state.static_energy_gates is not None # nosec
return self._state.static_energy_gates[2]
@property
def static_energy_gate_3(self) -> int:
assert self._state.static_energy_gates is not None # nosec
return self._state.static_energy_gates[3]
@property
def static_energy_gate_4(self) -> int:
assert self._state.static_energy_gates is not None # nosec
return self._state.static_energy_gates[4]
@property
def static_energy_gate_5(self) -> int:
assert self._state.static_energy_gates is not None # nosec
return self._state.static_energy_gates[5]
@property
def static_energy_gate_6(self) -> int:
assert self._state.static_energy_gates is not None # nosec
return self._state.static_energy_gates[6]
@property
def static_energy_gate_7(self) -> int:
assert self._state.static_energy_gates is not None # nosec
return self._state.static_energy_gates[7]
@property
def static_energy_gate_8(self) -> int:
assert self._state.static_energy_gates is not None # nosec
return self._state.static_energy_gates[8]
async def stop(self) -> None:
"""Stop the LD2410BLE."""
_LOGGER.debug("%s: Stop", self.name)
await self._execute_disconnect()
def _fire_callbacks(self) -> None:
"""Fire the callbacks."""
for callback in self._callbacks:
callback(self._state)
def register_callback(
self, callback: Callable[[LD2410BLEState], None]
) -> Callable[[], None]:
"""Register a callback to be called when the state changes."""
def unregister_callback() -> None:
self._callbacks.remove(callback)
self._callbacks.append(callback)
return unregister_callback
def _fire_disconnected_callbacks(self) -> None:
"""Fire the callbacks."""
for callback in self._disconnected_callbacks:
callback()
def register_disconnected_callback(
self, callback: Callable[[], None]
) -> Callable[[], None]:
"""Register a callback to be called when the state changes."""
def unregister_callback() -> None:
self._disconnected_callbacks.remove(callback)
self._disconnected_callbacks.append(callback)
return unregister_callback
async def initialise(self) -> None:
_LOGGER.debug("%s: Sending configuration commands", self.name)
await self._send_command(CMD_BT_PASS_PRE + self._password + CMD_BT_PASS_POST)
await asyncio.sleep(0.1)
await self._send_command(CMD_ENABLE_CONFIG)
await asyncio.sleep(0.1)
await self._send_command(CMD_ENABLE_ENGINEERING_MODE)
await asyncio.sleep(0.1)
await self._send_command(CMD_DISABLE_CONFIG)
await asyncio.sleep(0.1)
_LOGGER.debug("%s: Subscribe to notifications; RSSI: %s", self.name, self.rssi)
if self._client is not None:
await self._client.start_notify(
CHARACTERISTIC_NOTIFY, self._notification_handler
)
async def _ensure_connected(self) -> None:
"""Ensure connection to device is established."""
if self._connect_lock.locked():
_LOGGER.debug(
"%s: Connection already in progress, waiting for it to complete; RSSI: %s",
self.name,
self.rssi,
)
if self._client and self._client.is_connected:
return
async with self._connect_lock:
# Check again while holding the lock
if self._client and self._client.is_connected:
return
_LOGGER.debug("%s: Connecting; RSSI: %s", self.name, self.rssi)
client = await establish_connection(
BleakClientWithServiceCache,
self._ble_device,
self.name,
self._disconnected,
use_services_cache=True,
ble_device_callback=lambda: self._ble_device,
)
_LOGGER.debug("%s: Connected; RSSI: %s", self.name, self.rssi)
self._client = client
async def _reconnect(self) -> None:
"""Attempt a reconnect"""
_LOGGER.debug("ensuring connection")
try:
await self._ensure_connected()
_LOGGER.debug("ensured connection - initialising")
await self.initialise()
except BleakNotFoundError:
_LOGGER.debug("failed to ensure connection - backing off")
await asyncio.sleep(BLEAK_BACKOFF_TIME)
_LOGGER.debug("reconnecting again")
asyncio.create_task(self._reconnect())
def intify(self, state: bytes) -> int:
return int.from_bytes(state, byteorder="little")
def _notification_handler(self, _sender: int, data: bytearray) -> None:
"""Handle notification responses."""
_LOGGER.debug("%s: Notification received: %s", self.name, data.hex())
self._buf += data
msg = re.search(frame_regex, self._buf)
if msg:
self._buf = self._buf[msg.end() :] # noqa: E203
target_state = msg.group("target_state")
engineering_data = msg.group("engineering_data")
target_state_int = self.intify(target_state)
is_moving = bool(target_state_int & MOVING_TARGET)
is_static = bool(target_state_int & STATIC_TARGET)
moving_target_distance = self.intify(msg.group("moving_target_distance"))
moving_target_energy = self.intify(msg.group("moving_target_energy"))
static_target_distance = self.intify(msg.group("static_target_distance"))
static_target_energy = self.intify(msg.group("static_target_energy"))
detection_distance = self.intify(msg.group("detection_distance"))
max_motion_gates = None
max_static_gates = None
motion_energy_gates = None
static_energy_gates = None
if engineering_data:
em = re.match(engineering_frame_regex, engineering_data)
if em:
max_motion_gates = self.intify(em.group("maximum_motion_gates"))
max_static_gates = self.intify(em.group("maximum_static_gates"))
motion_energy_gates = [x for x in em.group("motion_energy_gates")]
static_energy_gates = [x for x in em.group("static_energy_gates")]
self._state = LD2410BLEState(
is_moving=is_moving,
is_static=is_static,
moving_target_distance=moving_target_distance,
moving_target_energy=moving_target_energy,
static_target_distance=static_target_distance,
static_target_energy=static_target_energy,
detection_distance=detection_distance,
max_motion_gates=max_motion_gates,
max_static_gates=max_static_gates,
motion_energy_gates=motion_energy_gates,
static_energy_gates=static_energy_gates,
)
self._fire_callbacks()
_LOGGER.debug(
"%s: Notification received; RSSI: %s: %s %s",
self.name,
self.rssi,
data.hex(),
self._state,
)
def _disconnected(self, client: BleakClientWithServiceCache) -> None:
"""Disconnected callback."""
self._fire_disconnected_callbacks()
if self._expected_disconnect:
_LOGGER.debug(
"%s: Disconnected from device; RSSI: %s", self.name, self.rssi
)
return
_LOGGER.warning(
"%s: Device unexpectedly disconnected; RSSI: %s",
self.name,
self.rssi,
)
asyncio.create_task(self._reconnect())
def _disconnect(self) -> None:
"""Disconnect from device."""
asyncio.create_task(self._execute_timed_disconnect())
async def _execute_timed_disconnect(self) -> None:
"""Execute timed disconnection."""
_LOGGER.debug(
"%s: Disconnecting",
self.name,
)
await self._execute_disconnect()
async def _execute_disconnect(self) -> None:
"""Execute disconnection."""
async with self._connect_lock:
client = self._client
self._expected_disconnect = True
self._client = None
if client and client.is_connected:
await client.stop_notify(CHARACTERISTIC_NOTIFY)
await client.disconnect()
@retry_bluetooth_connection_error(DEFAULT_ATTEMPTS)
async def _send_command_locked(self, commands: list[bytes]) -> None:
"""Send command to device and read response."""
try:
await self._execute_command_locked(commands)
except BleakDBusError as ex:
# Disconnect so we can reset state and try again
await asyncio.sleep(BLEAK_BACKOFF_TIME)
_LOGGER.debug(
"%s: RSSI: %s; Backing off %ss; Disconnecting due to error: %s",
self.name,
self.rssi,
BLEAK_BACKOFF_TIME,
ex,
)
await self._execute_disconnect()
raise
except BleakError as ex:
# Disconnect so we can reset state and try again
_LOGGER.debug(
"%s: RSSI: %s; Disconnecting due to error: %s", self.name, self.rssi, ex
)
await self._execute_disconnect()
raise
async def _send_command(
self, commands: list[bytes] | bytes, retry: int | None = None
) -> None:
"""Send command to device and read response."""
await self._ensure_connected()
if not isinstance(commands, list):
commands = [commands]
await self._send_command_while_connected(commands, retry)
async def _send_command_while_connected(
self, commands: list[bytes], retry: int | None = None
) -> None:
"""Send command to device and read response."""
_LOGGER.debug(
"%s: Sending commands %s",
self.name,
[command.hex() for command in commands],
)
if self._operation_lock.locked():
_LOGGER.debug(
"%s: Operation already in progress, waiting for it to complete; RSSI: %s",
self.name,
self.rssi,
)
async with self._operation_lock:
try:
await self._send_command_locked(commands)
return
except BleakNotFoundError:
_LOGGER.error(
"%s: device not found, no longer in range, or poor RSSI: %s",
self.name,
self.rssi,
exc_info=True,
)
raise
except CharacteristicMissingError as ex:
_LOGGER.debug(
"%s: characteristic missing: %s; RSSI: %s",
self.name,
ex,
self.rssi,
exc_info=True,
)
raise
except BLEAK_EXCEPTIONS:
_LOGGER.debug("%s: communication failed", self.name, exc_info=True)
raise
raise RuntimeError("Unreachable")
async def _execute_command_locked(self, commands: list[bytes]) -> None:
"""Execute command and read response."""
assert self._client is not None # nosec
for command in commands:
await self._client.write_gatt_char(CHARACTERISTIC_WRITE, command, False)
930913-ld2410-ble-6c24cfb/src/ld2410_ble/models.py 0000664 0000000 0000000 00000001226 14366747107 0020615 0 ustar 00root root 0000000 0000000 from __future__ import annotations
from dataclasses import dataclass, field
@dataclass(frozen=True)
class LD2410BLEState:
is_moving: bool = False
is_static: bool = False
moving_target_distance: int = 0
moving_target_energy: int = 0
static_target_distance: int = 0
static_target_energy: int = 0
detection_distance: int = 0
max_motion_gates: int | None = 8
max_static_gates: int | None = 8
motion_energy_gates: list[int] | None = field(
default_factory=lambda: [0, 0, 0, 0, 0, 0, 0, 0, 0]
)
static_energy_gates: list[int] | None = field(
default_factory=lambda: [0, 0, 0, 0, 0, 0, 0, 0, 0]
)
930913-ld2410-ble-6c24cfb/src/ld2410_ble/py.typed 0000664 0000000 0000000 00000000000 14366747107 0020444 0 ustar 00root root 0000000 0000000 930913-ld2410-ble-6c24cfb/tests/ 0000775 0000000 0000000 00000000000 14366747107 0015602 5 ustar 00root root 0000000 0000000 930913-ld2410-ble-6c24cfb/tests/__init__.py 0000664 0000000 0000000 00000000000 14366747107 0017701 0 ustar 00root root 0000000 0000000 930913-ld2410-ble-6c24cfb/tests/test_init.py 0000664 0000000 0000000 00000000072 14366747107 0020155 0 ustar 00root root 0000000 0000000 import ld2410_ble
def test_add():
assert ld2410_ble