btmesh 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,12 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ .pytest_cache/
5
+ .ruff_cache/
6
+
7
+ # Secrets and vendor artifacts — NEVER commit these.
8
+ # A ThingOS/Häfele ".connect" export holds the mesh NetKey/AppKey/DeviceKeys.
9
+ # (The sanitized tests/fixtures/sample.connect.json is a *.json fixture and is
10
+ # intentionally NOT matched by this pattern.)
11
+ *.connect
12
+ *.apk
@@ -0,0 +1,40 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the project aims
5
+ to follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [0.1.0] — 2026-07-20
8
+
9
+ First public release. A pure-Python Bluetooth SIG Mesh stack (`btmesh`) and a
10
+ Home Assistant custom integration (`bluetooth_mesh`), validated end-to-end on
11
+ real hardware against a Häfele Connect Mesh tunable-white lamp through an
12
+ ESPHome Bluetooth proxy.
13
+
14
+ ### Added
15
+
16
+ - **Mesh stack (`btmesh`)**: k1–k4 derivations, AES-CMAC/AES-CCM, network
17
+ obfuscation; network/transport/access layers; proxy-PDU segmentation and
18
+ reassembly; a provisioner; and a GATT bearer over `bleak` / `habluetooth`
19
+ (works through ESPHome Bluetooth proxies). Validated against the SIG spec
20
+ sample vectors.
21
+ - **Home Assistant integration (`bluetooth_mesh`)**: config flow importing a
22
+ ThingOS/Häfele `.connect` network export; a connection coordinator; and a
23
+ `light` platform exposing on/off, brightness, and colour temperature (Light
24
+ CTL) per node composition.
25
+ - **Coexistence model**: rides on the network the vendor app already
26
+ provisioned (shared NetKey/AppKey), sending standard app-keyed SIG messages.
27
+ - **Kept-alive proxy connection** for instant commands, with a configurable
28
+ keep-alive timeout (options flow) to hand the lamp's single proxy slot back
29
+ to the vendor app when idle. `0` = always connected.
30
+ - **Local brand icon** (`brand/`) for Home Assistant ≥ 2026.3.
31
+
32
+ ### Known limitations
33
+
34
+ - RGB / full-colour lamps (Light HSL / xyL) are not implemented — the reference
35
+ hardware is tunable-white only.
36
+ - Optimistic state: brightness/temperature reflect the last command; changes
37
+ made from the vendor app in parallel are not read back until HA's next
38
+ command.
39
+
40
+ [0.1.0]: https://github.com/dasimon135/ha-bluetooth-mesh/releases/tag/v0.1.0
btmesh-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 David Simon
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
btmesh-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,197 @@
1
+ Metadata-Version: 2.4
2
+ Name: btmesh
3
+ Version: 0.1.0
4
+ Summary: Pure-Python Bluetooth SIG Mesh stack (rides on an existing mesh network)
5
+ Project-URL: Homepage, https://github.com/dasimon135/ha-bluetooth-mesh
6
+ Project-URL: Repository, https://github.com/dasimon135/ha-bluetooth-mesh
7
+ Project-URL: Changelog, https://github.com/dasimon135/ha-bluetooth-mesh/blob/main/CHANGELOG.md
8
+ Project-URL: Issues, https://github.com/dasimon135/ha-bluetooth-mesh/issues
9
+ Author: David Simon
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: ble,bluetooth,bluetooth-mesh,home-assistant,mesh,thingos
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Topic :: Home Automation
17
+ Classifier: Topic :: System :: Networking
18
+ Requires-Python: >=3.12
19
+ Requires-Dist: cryptography>=42
20
+ Provides-Extra: ble
21
+ Requires-Dist: bleak-retry-connector>=3; extra == 'ble'
22
+ Requires-Dist: bleak>=0.22; extra == 'ble'
23
+ Provides-Extra: harness
24
+ Requires-Dist: aioesphomeapi>=24; extra == 'harness'
25
+ Requires-Dist: bleak-esphome>=2.0; extra == 'harness'
26
+ Requires-Dist: bleak-retry-connector>=3; extra == 'harness'
27
+ Requires-Dist: bleak>=0.22; extra == 'harness'
28
+ Requires-Dist: habluetooth>=3; extra == 'harness'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # Bluetooth Mesh for Home Assistant
32
+
33
+ A pure-Python **Bluetooth SIG Mesh** stack and a **Home Assistant** integration
34
+ that lets HA control Bluetooth Mesh lighting — Häfele Connect Mesh (Loox),
35
+ other ThingOS-based luminaires, and standard SIG-Mesh lights — **with no extra
36
+ hardware** beyond what most installs already have: an ESPHome Bluetooth proxy or
37
+ a local Bluetooth adapter.
38
+
39
+ Home Assistant has no native Bluetooth Mesh support, which orphans entire
40
+ product families of "app-only" mesh lights. Existing workarounds need either a
41
+ discontinued vendor gateway or an experimental BlueZ `bluetooth-meshd` setup
42
+ that cannot run on Home Assistant OS. This project removes both requirements.
43
+
44
+ > **Status:** working, validated on real hardware. A Häfele Connect Mesh
45
+ > tunable-white lamp is controlled end-to-end from Home Assistant through an
46
+ > ESPHome Bluetooth proxy — on/off, brightness, and colour temperature — with a
47
+ > kept-alive proxy connection that makes commands feel instant. See
48
+ > [What it controls](#what-it-controls) for the current capability surface.
49
+
50
+ ## What it controls
51
+
52
+ Each provisioned lighting node becomes one Home Assistant `light` entity, with
53
+ capabilities read from its mesh composition:
54
+
55
+ | Node model | HA capability |
56
+ | --- | --- |
57
+ | Generic OnOff (`0x1000`) | on / off |
58
+ | Light Lightness (`0x1300`) | + brightness |
59
+ | Light CTL (`0x1303` / `0x1306`) | + colour temperature (tunable white) |
60
+
61
+ **Not yet supported:** RGB / full-colour lamps (Light HSL / xyL). The author's
62
+ hardware is tunable-white only, so colour is left unimplemented rather than
63
+ shipped untested — contributions with colour hardware to validate against are
64
+ welcome.
65
+
66
+ ## Two deliverables
67
+
68
+ This repository ships two things, mirroring the `pymadoka-ng` / `daikin_madoka`
69
+ split:
70
+
71
+ 1. **`btmesh`** (`src/btmesh/`) — a Home-Assistant-independent Python library
72
+ implementing the mesh stack: crypto (k1–k4 derivations, AES-CMAC, AES-CCM,
73
+ network obfuscation), network/transport/access layers, proxy-PDU
74
+ segmentation/reassembly, a provisioner, and a GATT bearer that runs over
75
+ `bleak` / `habluetooth` (so it works through ESPHome Bluetooth proxies).
76
+ 2. **`bluetooth_mesh`** (`custom_components/bluetooth_mesh/`) — a HACS custom
77
+ integration: config flow, storage, a connection coordinator, and Home
78
+ Assistant entities (starting with `light`).
79
+
80
+ ## How it works
81
+
82
+ ```
83
+ Home Assistant (pure-Python mesh stack: btmesh)
84
+ │ bleak / habluetooth
85
+
86
+ ESPHome BLE proxy (existing fleet) ← or any local BT adapter
87
+ │ GATT: Mesh Proxy Service (proxy protocol tunnel)
88
+
89
+ A mesh node with GATT Proxy enabled (any powered lamp)
90
+ │ advertising bearer (mesh relay)
91
+
92
+ The rest of the mesh network
93
+ ```
94
+
95
+ One GATT connection serves the whole network: the stack maintains a single
96
+ tunnel to one proxy node, and the mesh relays messages to every other node.
97
+ No BlueZ meshd, no dedicated ESP32 firmware — it works on Home Assistant OS in
98
+ a VM with no local radio.
99
+
100
+ ## Coexistence with the vendor app (shared keys)
101
+
102
+ Rather than replicating a vendor's proprietary activation step, this project
103
+ **rides on the mesh network the vendor app already created**. The app exports
104
+ its network as a `.connect` JSON (ThingOS format) containing the NetKey, the
105
+ AppKey, and each node's unicast address. The integration imports that file,
106
+ connects its proxy to the same network, and sends **standard**, app-keyed mesh
107
+ messages (Generic OnOff Set, Light Lightness Set, …) to each node's unicast
108
+ address.
109
+
110
+ Because both sides share the same keys, the vendor app and Home Assistant can
111
+ control the **same lamps** — HA drives the same lights the app provisioned.
112
+
113
+ A mesh node has a **single** GATT-proxy connection slot, so Home Assistant and
114
+ the app cannot both hold it at once. The integration keeps its proxy connection
115
+ open by default (so commands are instant), which means the vendor app cannot
116
+ connect while HA is loaded. If you still want to use the app, set a **keep-alive
117
+ timeout** (Settings → Devices & Services → *Bluetooth Mesh* → **Configure**):
118
+ after that many idle seconds HA releases the lamp so the app can take over, at
119
+ the cost of a few-second reconnect on HA's next command. `0` = always
120
+ connected.
121
+
122
+ ## Installation
123
+
124
+ 1. **Add the repository to HACS** as a custom repository
125
+ (HACS → Integrations → ⋯ → Custom repositories), category **Integration**,
126
+ then install *Bluetooth Mesh* and restart Home Assistant.
127
+ 2. **Export your network** from the vendor app as a `.connect` file.
128
+ 3. **Add the integration** (Settings → Devices & Services → Add Integration →
129
+ *Bluetooth Mesh*) and paste the contents of the `.connect` file when
130
+ prompted. Keep this file private — it contains your mesh network keys and
131
+ should never be committed to a repository.
132
+ 4. *(Optional)* **Configure** the keep-alive timeout if you want to keep using
133
+ the vendor app — see [Coexistence](#coexistence-with-the-vendor-app-shared-keys).
134
+
135
+ A Bluetooth transport is required: an ESPHome Bluetooth proxy on your network,
136
+ or a local Bluetooth adapter usable by Home Assistant. At least one mesh lamp
137
+ must be powered and in range of that proxy for Home Assistant to reach the
138
+ network.
139
+
140
+ ## Development
141
+
142
+ ```bash
143
+ # Library only (fast; no Home Assistant):
144
+ uv sync
145
+ uv run pytest tests # btmesh library test suite
146
+
147
+ # Full suite (library + HA integration) in a HA-equipped environment:
148
+ pip install -e .
149
+ pip install -r requirements-test.txt
150
+ pytest tests # library + tests/ha/ (Home Assistant) together
151
+ ```
152
+
153
+ The `tests/ha/` tree is guarded with `pytest.importorskip` so it stays skipped
154
+ when Home Assistant is not installed, and runs for real when it is. CI installs
155
+ Home Assistant and runs the combined suite on Linux; see
156
+ `.github/workflows/tests.yml` (pytest) and `.github/workflows/validate.yml`
157
+ (hassfest + HACS).
158
+
159
+ ### Vendored library
160
+
161
+ `src/btmesh/` is the canonical library (the source of truth, published to PyPI).
162
+ Because HACS installs `custom_components/bluetooth_mesh/` as-is, the integration
163
+ ships a **vendored copy** of the library at
164
+ `custom_components/bluetooth_mesh/btmesh/`, so it installs with no external
165
+ `btmesh` dependency (only `cryptography`, which Home Assistant already provides).
166
+ After changing anything under `src/btmesh/`, re-sync the vendored copy:
167
+
168
+ ```bash
169
+ python scripts/sync_vendored_btmesh.py
170
+ ```
171
+
172
+ ## Documentation
173
+
174
+ Design and feasibility write-ups live in [`docs/plans/`](docs/plans/):
175
+
176
+ - [`2026-07-18-btmesh-design.md`](docs/plans/2026-07-18-btmesh-design.md) —
177
+ design document (problem, architecture, key decisions).
178
+ - [`2026-07-18-phase0-feasibility.md`](docs/plans/2026-07-18-phase0-feasibility.md) —
179
+ Phase 0 feasibility plan.
180
+ - [`2026-07-19-phase0-report.md`](docs/plans/2026-07-19-phase0-report.md) —
181
+ Phase 0 report (the hardware-validated breakthrough).
182
+ - [`2026-07-19-phase1-library-and-ha-integration.md`](docs/plans/2026-07-19-phase1-library-and-ha-integration.md) —
183
+ Phase 1 plan (library + HA integration).
184
+
185
+ ## Credit and honesty
186
+
187
+ This project grew out of reverse-engineering a Häfele Connect Mesh setup after
188
+ its vendor gateway was discontinued. The mesh crypto and codec layers are
189
+ implemented from the public Bluetooth SIG Mesh specification and validated
190
+ against the specification's official sample vectors; the coexistence approach
191
+ was discovered empirically against real hardware. It is an independent,
192
+ unofficial project and is not affiliated with or endorsed by Häfele, ThingOS,
193
+ or the Bluetooth SIG.
194
+
195
+ ## License
196
+
197
+ [MIT](LICENSE) © 2026 David Simon.
btmesh-0.1.0/README.md ADDED
@@ -0,0 +1,167 @@
1
+ # Bluetooth Mesh for Home Assistant
2
+
3
+ A pure-Python **Bluetooth SIG Mesh** stack and a **Home Assistant** integration
4
+ that lets HA control Bluetooth Mesh lighting — Häfele Connect Mesh (Loox),
5
+ other ThingOS-based luminaires, and standard SIG-Mesh lights — **with no extra
6
+ hardware** beyond what most installs already have: an ESPHome Bluetooth proxy or
7
+ a local Bluetooth adapter.
8
+
9
+ Home Assistant has no native Bluetooth Mesh support, which orphans entire
10
+ product families of "app-only" mesh lights. Existing workarounds need either a
11
+ discontinued vendor gateway or an experimental BlueZ `bluetooth-meshd` setup
12
+ that cannot run on Home Assistant OS. This project removes both requirements.
13
+
14
+ > **Status:** working, validated on real hardware. A Häfele Connect Mesh
15
+ > tunable-white lamp is controlled end-to-end from Home Assistant through an
16
+ > ESPHome Bluetooth proxy — on/off, brightness, and colour temperature — with a
17
+ > kept-alive proxy connection that makes commands feel instant. See
18
+ > [What it controls](#what-it-controls) for the current capability surface.
19
+
20
+ ## What it controls
21
+
22
+ Each provisioned lighting node becomes one Home Assistant `light` entity, with
23
+ capabilities read from its mesh composition:
24
+
25
+ | Node model | HA capability |
26
+ | --- | --- |
27
+ | Generic OnOff (`0x1000`) | on / off |
28
+ | Light Lightness (`0x1300`) | + brightness |
29
+ | Light CTL (`0x1303` / `0x1306`) | + colour temperature (tunable white) |
30
+
31
+ **Not yet supported:** RGB / full-colour lamps (Light HSL / xyL). The author's
32
+ hardware is tunable-white only, so colour is left unimplemented rather than
33
+ shipped untested — contributions with colour hardware to validate against are
34
+ welcome.
35
+
36
+ ## Two deliverables
37
+
38
+ This repository ships two things, mirroring the `pymadoka-ng` / `daikin_madoka`
39
+ split:
40
+
41
+ 1. **`btmesh`** (`src/btmesh/`) — a Home-Assistant-independent Python library
42
+ implementing the mesh stack: crypto (k1–k4 derivations, AES-CMAC, AES-CCM,
43
+ network obfuscation), network/transport/access layers, proxy-PDU
44
+ segmentation/reassembly, a provisioner, and a GATT bearer that runs over
45
+ `bleak` / `habluetooth` (so it works through ESPHome Bluetooth proxies).
46
+ 2. **`bluetooth_mesh`** (`custom_components/bluetooth_mesh/`) — a HACS custom
47
+ integration: config flow, storage, a connection coordinator, and Home
48
+ Assistant entities (starting with `light`).
49
+
50
+ ## How it works
51
+
52
+ ```
53
+ Home Assistant (pure-Python mesh stack: btmesh)
54
+ │ bleak / habluetooth
55
+
56
+ ESPHome BLE proxy (existing fleet) ← or any local BT adapter
57
+ │ GATT: Mesh Proxy Service (proxy protocol tunnel)
58
+
59
+ A mesh node with GATT Proxy enabled (any powered lamp)
60
+ │ advertising bearer (mesh relay)
61
+
62
+ The rest of the mesh network
63
+ ```
64
+
65
+ One GATT connection serves the whole network: the stack maintains a single
66
+ tunnel to one proxy node, and the mesh relays messages to every other node.
67
+ No BlueZ meshd, no dedicated ESP32 firmware — it works on Home Assistant OS in
68
+ a VM with no local radio.
69
+
70
+ ## Coexistence with the vendor app (shared keys)
71
+
72
+ Rather than replicating a vendor's proprietary activation step, this project
73
+ **rides on the mesh network the vendor app already created**. The app exports
74
+ its network as a `.connect` JSON (ThingOS format) containing the NetKey, the
75
+ AppKey, and each node's unicast address. The integration imports that file,
76
+ connects its proxy to the same network, and sends **standard**, app-keyed mesh
77
+ messages (Generic OnOff Set, Light Lightness Set, …) to each node's unicast
78
+ address.
79
+
80
+ Because both sides share the same keys, the vendor app and Home Assistant can
81
+ control the **same lamps** — HA drives the same lights the app provisioned.
82
+
83
+ A mesh node has a **single** GATT-proxy connection slot, so Home Assistant and
84
+ the app cannot both hold it at once. The integration keeps its proxy connection
85
+ open by default (so commands are instant), which means the vendor app cannot
86
+ connect while HA is loaded. If you still want to use the app, set a **keep-alive
87
+ timeout** (Settings → Devices & Services → *Bluetooth Mesh* → **Configure**):
88
+ after that many idle seconds HA releases the lamp so the app can take over, at
89
+ the cost of a few-second reconnect on HA's next command. `0` = always
90
+ connected.
91
+
92
+ ## Installation
93
+
94
+ 1. **Add the repository to HACS** as a custom repository
95
+ (HACS → Integrations → ⋯ → Custom repositories), category **Integration**,
96
+ then install *Bluetooth Mesh* and restart Home Assistant.
97
+ 2. **Export your network** from the vendor app as a `.connect` file.
98
+ 3. **Add the integration** (Settings → Devices & Services → Add Integration →
99
+ *Bluetooth Mesh*) and paste the contents of the `.connect` file when
100
+ prompted. Keep this file private — it contains your mesh network keys and
101
+ should never be committed to a repository.
102
+ 4. *(Optional)* **Configure** the keep-alive timeout if you want to keep using
103
+ the vendor app — see [Coexistence](#coexistence-with-the-vendor-app-shared-keys).
104
+
105
+ A Bluetooth transport is required: an ESPHome Bluetooth proxy on your network,
106
+ or a local Bluetooth adapter usable by Home Assistant. At least one mesh lamp
107
+ must be powered and in range of that proxy for Home Assistant to reach the
108
+ network.
109
+
110
+ ## Development
111
+
112
+ ```bash
113
+ # Library only (fast; no Home Assistant):
114
+ uv sync
115
+ uv run pytest tests # btmesh library test suite
116
+
117
+ # Full suite (library + HA integration) in a HA-equipped environment:
118
+ pip install -e .
119
+ pip install -r requirements-test.txt
120
+ pytest tests # library + tests/ha/ (Home Assistant) together
121
+ ```
122
+
123
+ The `tests/ha/` tree is guarded with `pytest.importorskip` so it stays skipped
124
+ when Home Assistant is not installed, and runs for real when it is. CI installs
125
+ Home Assistant and runs the combined suite on Linux; see
126
+ `.github/workflows/tests.yml` (pytest) and `.github/workflows/validate.yml`
127
+ (hassfest + HACS).
128
+
129
+ ### Vendored library
130
+
131
+ `src/btmesh/` is the canonical library (the source of truth, published to PyPI).
132
+ Because HACS installs `custom_components/bluetooth_mesh/` as-is, the integration
133
+ ships a **vendored copy** of the library at
134
+ `custom_components/bluetooth_mesh/btmesh/`, so it installs with no external
135
+ `btmesh` dependency (only `cryptography`, which Home Assistant already provides).
136
+ After changing anything under `src/btmesh/`, re-sync the vendored copy:
137
+
138
+ ```bash
139
+ python scripts/sync_vendored_btmesh.py
140
+ ```
141
+
142
+ ## Documentation
143
+
144
+ Design and feasibility write-ups live in [`docs/plans/`](docs/plans/):
145
+
146
+ - [`2026-07-18-btmesh-design.md`](docs/plans/2026-07-18-btmesh-design.md) —
147
+ design document (problem, architecture, key decisions).
148
+ - [`2026-07-18-phase0-feasibility.md`](docs/plans/2026-07-18-phase0-feasibility.md) —
149
+ Phase 0 feasibility plan.
150
+ - [`2026-07-19-phase0-report.md`](docs/plans/2026-07-19-phase0-report.md) —
151
+ Phase 0 report (the hardware-validated breakthrough).
152
+ - [`2026-07-19-phase1-library-and-ha-integration.md`](docs/plans/2026-07-19-phase1-library-and-ha-integration.md) —
153
+ Phase 1 plan (library + HA integration).
154
+
155
+ ## Credit and honesty
156
+
157
+ This project grew out of reverse-engineering a Häfele Connect Mesh setup after
158
+ its vendor gateway was discontinued. The mesh crypto and codec layers are
159
+ implemented from the public Bluetooth SIG Mesh specification and validated
160
+ against the specification's official sample vectors; the coexistence approach
161
+ was discovered empirically against real hardware. It is an independent,
162
+ unofficial project and is not affiliated with or endorsed by Häfele, ThingOS,
163
+ or the Bluetooth SIG.
164
+
165
+ ## License
166
+
167
+ [MIT](LICENSE) © 2026 David Simon.
@@ -0,0 +1,59 @@
1
+ [project]
2
+ name = "btmesh"
3
+ version = "0.1.0"
4
+ description = "Pure-Python Bluetooth SIG Mesh stack (rides on an existing mesh network)"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ license = "MIT"
8
+ license-files = ["LICENSE"]
9
+ authors = [{ name = "David Simon" }]
10
+ keywords = ["bluetooth", "bluetooth-mesh", "ble", "mesh", "thingos", "home-assistant"]
11
+ classifiers = [
12
+ "Development Status :: 4 - Beta",
13
+ "Intended Audience :: Developers",
14
+ "Programming Language :: Python :: 3",
15
+ "Topic :: Home Automation",
16
+ "Topic :: System :: Networking",
17
+ ]
18
+ dependencies = ["cryptography>=42"]
19
+
20
+ [project.urls]
21
+ Homepage = "https://github.com/dasimon135/ha-bluetooth-mesh"
22
+ Repository = "https://github.com/dasimon135/ha-bluetooth-mesh"
23
+ Changelog = "https://github.com/dasimon135/ha-bluetooth-mesh/blob/main/CHANGELOG.md"
24
+ Issues = "https://github.com/dasimon135/ha-bluetooth-mesh/issues"
25
+
26
+ [project.optional-dependencies]
27
+ ble = ["bleak>=0.22", "bleak-retry-connector>=3"]
28
+ # Extra deps the phase0 hardware scripts need to actually talk to an ESP proxy.
29
+ # Not required for the test suite or `--help` (bleak/habluetooth are imported
30
+ # lazily inside btmesh.bearer), so a default `uv sync` stays lean.
31
+ harness = [
32
+ "bleak>=0.22",
33
+ "bleak-esphome>=2.0",
34
+ "aioesphomeapi>=24",
35
+ "habluetooth>=3",
36
+ "bleak-retry-connector>=3",
37
+ ]
38
+
39
+ [build-system]
40
+ requires = ["hatchling"]
41
+ build-backend = "hatchling.build"
42
+
43
+ [tool.hatch.build.targets.wheel]
44
+ packages = ["src/btmesh"]
45
+
46
+ # Keep the sdist to the library itself. Without this, hatchling's default sdist
47
+ # sweeps the whole working tree — including phase0/ (hardware scripts and a
48
+ # decompiled vendor app bundle) and local logs — which is both bloat and content
49
+ # that must never be redistributed. Only the library + its metadata ship.
50
+ [tool.hatch.build.targets.sdist]
51
+ only-include = ["src/btmesh", "README.md", "LICENSE", "CHANGELOG.md"]
52
+
53
+ [dependency-groups]
54
+ dev = ["pytest>=8", "pytest-asyncio>=0.24"]
55
+
56
+ [tool.pytest.ini_options]
57
+ asyncio_mode = "auto"
58
+ testpaths = ["tests", "phase0/tests"]
59
+ pythonpath = ["src", "phase0", "."]
File without changes