fp-soother-lib 1.0.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.
- fp_soother_lib-1.0.0/LICENSE +21 -0
- fp_soother_lib-1.0.0/PKG-INFO +81 -0
- fp_soother_lib-1.0.0/README.md +52 -0
- fp_soother_lib-1.0.0/pyproject.toml +68 -0
- fp_soother_lib-1.0.0/pyproject.toml.orig +54 -0
- fp_soother_lib-1.0.0/src/fp_soother_lib/__init__.py +61 -0
- fp_soother_lib-1.0.0/src/fp_soother_lib/client.py +671 -0
- fp_soother_lib-1.0.0/src/fp_soother_lib/constants.py +322 -0
- fp_soother_lib-1.0.0/src/fp_soother_lib/encryption.py +187 -0
- fp_soother_lib-1.0.0/src/fp_soother_lib/exceptions.py +22 -0
- fp_soother_lib-1.0.0/src/fp_soother_lib/key_tables.py +81 -0
- fp_soother_lib-1.0.0/src/fp_soother_lib/pairing.py +168 -0
- fp_soother_lib-1.0.0/src/fp_soother_lib/protocol.py +405 -0
- fp_soother_lib-1.0.0/src/fp_soother_lib/py.typed +0 -0
- fp_soother_lib-1.0.0/src/fp_soother_lib/scanner.py +97 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Donald Patrick Seal
|
|
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.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fp-soother-lib
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Python BLE library for Fisher-Price Smart Connect Deluxe Soother
|
|
5
|
+
Keywords: ble,bluetooth,fisher-price,smart connect,soother
|
|
6
|
+
Author: Patrick Seal
|
|
7
|
+
Author-email: Patrick Seal <code@plasticrake.com>
|
|
8
|
+
License-Expression: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
19
|
+
Classifier: Topic :: System :: Hardware :: Hardware Drivers
|
|
20
|
+
Classifier: Topic :: System :: Hardware
|
|
21
|
+
Classifier: Typing :: Typed
|
|
22
|
+
Requires-Dist: bleak>=3.0.2
|
|
23
|
+
Requires-Dist: bleak-retry-connector>=4.6.0
|
|
24
|
+
Requires-Dist: cryptography>=48.0.1
|
|
25
|
+
Requires-Python: >=3.14.7
|
|
26
|
+
Project-URL: homepage, https://github.com/plasticrake/fp-soother
|
|
27
|
+
Project-URL: repository, https://github.com/plasticrake/fp-soother
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# fp-soother-lib
|
|
31
|
+
|
|
32
|
+
A Python BLE library for the **Fisher-Price Smart Connect Deluxe Soother** (model DYW47).
|
|
33
|
+
|
|
34
|
+
The official app was discontinued in 2024, leaving many users with a device that could no longer be fully controlled. This library gives you direct BLE control from Python.
|
|
35
|
+
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
### Standalone (scans/connects by address)
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
import asyncio
|
|
42
|
+
from fp_soother_lib import SootherClient
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
async def main():
|
|
46
|
+
async with SootherClient.connect("AA:BB:CC:DD:EE:FF", session_key=key) as soother:
|
|
47
|
+
if not soother.is_paired:
|
|
48
|
+
await soother.pair() # device must already be in pairing mode
|
|
49
|
+
await soother.set_nightlight(True)
|
|
50
|
+
print(soother.state)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
asyncio.run(main())
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
If `address` is omitted, `SootherClient.connect()` scans for the first soother found.
|
|
57
|
+
|
|
58
|
+
### Host-managed discovery (e.g. Home Assistant)
|
|
59
|
+
|
|
60
|
+
A host that owns its own BLE scanner (Home Assistant's `bluetooth` integration
|
|
61
|
+
is the main example) should resolve `BLEDevice` objects itself rather than
|
|
62
|
+
letting this library run its own scan. Pass `ble_device`/`ble_device_callback`
|
|
63
|
+
to `SootherClient` instead of relying on address-based discovery:
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from fp_soother_lib import SootherClient
|
|
67
|
+
|
|
68
|
+
client = SootherClient(address, session_key=key, ble_device_callback=my_resolver)
|
|
69
|
+
await client.open()
|
|
70
|
+
...
|
|
71
|
+
await client.close()
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`my_resolver` is a zero-arg callable returning the host's current best
|
|
75
|
+
`BLEDevice` for `address` (e.g. Home Assistant's
|
|
76
|
+
`bluetooth.async_ble_device_from_address`), called fresh on every
|
|
77
|
+
(re)connect. See `AGENTS.md` in the repository root for the full rationale.
|
|
78
|
+
|
|
79
|
+
## Legal / Disclaimer
|
|
80
|
+
|
|
81
|
+
This is an independent, open-source project not affiliated with Fisher-Price or Mattel. Reverse engineering for interoperability purposes is generally permitted under applicable law (e.g. EU Software Directive, US DMCA §1201(f)). This project does not redistribute any Fisher-Price code or assets. Use at your own risk. "Fisher-Price" and "Deluxe Soother" are trademarks of their respective owners.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# fp-soother-lib
|
|
2
|
+
|
|
3
|
+
A Python BLE library for the **Fisher-Price Smart Connect Deluxe Soother** (model DYW47).
|
|
4
|
+
|
|
5
|
+
The official app was discontinued in 2024, leaving many users with a device that could no longer be fully controlled. This library gives you direct BLE control from Python.
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
### Standalone (scans/connects by address)
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
import asyncio
|
|
13
|
+
from fp_soother_lib import SootherClient
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
async def main():
|
|
17
|
+
async with SootherClient.connect("AA:BB:CC:DD:EE:FF", session_key=key) as soother:
|
|
18
|
+
if not soother.is_paired:
|
|
19
|
+
await soother.pair() # device must already be in pairing mode
|
|
20
|
+
await soother.set_nightlight(True)
|
|
21
|
+
print(soother.state)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
asyncio.run(main())
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
If `address` is omitted, `SootherClient.connect()` scans for the first soother found.
|
|
28
|
+
|
|
29
|
+
### Host-managed discovery (e.g. Home Assistant)
|
|
30
|
+
|
|
31
|
+
A host that owns its own BLE scanner (Home Assistant's `bluetooth` integration
|
|
32
|
+
is the main example) should resolve `BLEDevice` objects itself rather than
|
|
33
|
+
letting this library run its own scan. Pass `ble_device`/`ble_device_callback`
|
|
34
|
+
to `SootherClient` instead of relying on address-based discovery:
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from fp_soother_lib import SootherClient
|
|
38
|
+
|
|
39
|
+
client = SootherClient(address, session_key=key, ble_device_callback=my_resolver)
|
|
40
|
+
await client.open()
|
|
41
|
+
...
|
|
42
|
+
await client.close()
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`my_resolver` is a zero-arg callable returning the host's current best
|
|
46
|
+
`BLEDevice` for `address` (e.g. Home Assistant's
|
|
47
|
+
`bluetooth.async_ble_device_from_address`), called fresh on every
|
|
48
|
+
(re)connect. See `AGENTS.md` in the repository root for the full rationale.
|
|
49
|
+
|
|
50
|
+
## Legal / Disclaimer
|
|
51
|
+
|
|
52
|
+
This is an independent, open-source project not affiliated with Fisher-Price or Mattel. Reverse engineering for interoperability purposes is generally permitted under applicable law (e.g. EU Software Directive, US DMCA §1201(f)). This project does not redistribute any Fisher-Price code or assets. Use at your own risk. "Fisher-Price" and "Deluxe Soother" are trademarks of their respective owners.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "fp-soother-lib"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "Python BLE library for Fisher-Price Smart Connect Deluxe Soother"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.14.7"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"bleak>=3.0.2",
|
|
9
|
+
"bleak-retry-connector>=4.6.0",
|
|
10
|
+
"cryptography>=48.0.1",
|
|
11
|
+
]
|
|
12
|
+
keywords = [
|
|
13
|
+
"ble",
|
|
14
|
+
"bluetooth",
|
|
15
|
+
"fisher-price",
|
|
16
|
+
"smart connect",
|
|
17
|
+
"soother",
|
|
18
|
+
]
|
|
19
|
+
classifiers = [
|
|
20
|
+
"Development Status :: 3 - Alpha",
|
|
21
|
+
"Intended Audience :: Developers",
|
|
22
|
+
"Operating System :: OS Independent",
|
|
23
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
24
|
+
"Programming Language :: Python :: 3.14",
|
|
25
|
+
"Programming Language :: Python :: 3",
|
|
26
|
+
"Programming Language :: Python",
|
|
27
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
28
|
+
"Topic :: Software Development :: Libraries",
|
|
29
|
+
"Topic :: System :: Hardware :: Hardware Drivers",
|
|
30
|
+
"Topic :: System :: Hardware",
|
|
31
|
+
"Typing :: Typed",
|
|
32
|
+
]
|
|
33
|
+
license = "MIT"
|
|
34
|
+
license-files = ["LICEN[CS]E*"]
|
|
35
|
+
|
|
36
|
+
[[project.authors]]
|
|
37
|
+
name = "Patrick Seal"
|
|
38
|
+
email = "code@plasticrake.com"
|
|
39
|
+
|
|
40
|
+
[project.urls]
|
|
41
|
+
homepage = "https://github.com/plasticrake/fp-soother"
|
|
42
|
+
repository = "https://github.com/plasticrake/fp-soother"
|
|
43
|
+
|
|
44
|
+
[build-system]
|
|
45
|
+
requires = ["uv_build>=0.12.13,<0.13.0"]
|
|
46
|
+
build-backend = "uv_build"
|
|
47
|
+
|
|
48
|
+
[dependency-groups]
|
|
49
|
+
dev = [
|
|
50
|
+
"ruff>=0.16.6",
|
|
51
|
+
"ty>=0.0.79",
|
|
52
|
+
"pytest>=8.3",
|
|
53
|
+
"pytest-asyncio>=0.24",
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
[tool.pytest.ini_options]
|
|
57
|
+
asyncio_mode = "auto"
|
|
58
|
+
|
|
59
|
+
[tool.ruff.lint]
|
|
60
|
+
preview = true
|
|
61
|
+
select = [
|
|
62
|
+
"correctness",
|
|
63
|
+
"suspicious",
|
|
64
|
+
"complexity",
|
|
65
|
+
"performance",
|
|
66
|
+
"style",
|
|
67
|
+
"security",
|
|
68
|
+
]
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "fp-soother-lib"
|
|
3
|
+
version = "1.0.0"
|
|
4
|
+
description = "Python BLE library for Fisher-Price Smart Connect Deluxe Soother"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [{ name = "Patrick Seal", email = "code@plasticrake.com" }]
|
|
7
|
+
requires-python = ">=3.14.7"
|
|
8
|
+
dependencies = [
|
|
9
|
+
"bleak>=3.0.2",
|
|
10
|
+
"bleak-retry-connector>=4.6.0",
|
|
11
|
+
"cryptography>=48.0.1",
|
|
12
|
+
]
|
|
13
|
+
keywords = ["ble", "bluetooth", "fisher-price", "smart connect", "soother"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
19
|
+
"Programming Language :: Python :: 3.14",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python",
|
|
22
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
23
|
+
"Topic :: Software Development :: Libraries",
|
|
24
|
+
"Topic :: System :: Hardware :: Hardware Drivers",
|
|
25
|
+
"Topic :: System :: Hardware",
|
|
26
|
+
"Typing :: Typed",
|
|
27
|
+
]
|
|
28
|
+
license = "MIT"
|
|
29
|
+
license-files = ["LICEN[CS]E*"]
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
homepage = "https://github.com/plasticrake/fp-soother"
|
|
33
|
+
repository = "https://github.com/plasticrake/fp-soother"
|
|
34
|
+
|
|
35
|
+
[build-system]
|
|
36
|
+
requires = ["uv_build>=0.12.13,<0.13.0"]
|
|
37
|
+
build-backend = "uv_build"
|
|
38
|
+
|
|
39
|
+
[dependency-groups]
|
|
40
|
+
dev = ["ruff>=0.16.6", "ty>=0.0.79", "pytest>=8.3", "pytest-asyncio>=0.24"]
|
|
41
|
+
|
|
42
|
+
[tool.pytest.ini_options]
|
|
43
|
+
asyncio_mode = "auto"
|
|
44
|
+
|
|
45
|
+
[tool.ruff.lint]
|
|
46
|
+
preview = true
|
|
47
|
+
select = [
|
|
48
|
+
"correctness",
|
|
49
|
+
"suspicious",
|
|
50
|
+
"complexity",
|
|
51
|
+
"performance",
|
|
52
|
+
"style",
|
|
53
|
+
"security",
|
|
54
|
+
]
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Fisher-Price Smart Connect Deluxe Soother — Python BLE Library
|
|
3
|
+
==============================================================
|
|
4
|
+
|
|
5
|
+
Pairs and controls the device over raw BLE -- no official app or cloud
|
|
6
|
+
account needed.
|
|
7
|
+
|
|
8
|
+
Quick start
|
|
9
|
+
-----------
|
|
10
|
+
import asyncio
|
|
11
|
+
from fp_soother_lib import SootherClient
|
|
12
|
+
|
|
13
|
+
async def main():
|
|
14
|
+
async with SootherClient.connect("AA:BB:CC:DD:EE:FF") as soother:
|
|
15
|
+
if not soother.is_paired:
|
|
16
|
+
await soother.pair() # device must already be in pairing mode
|
|
17
|
+
await soother.set_nightlight(True)
|
|
18
|
+
print(soother.state)
|
|
19
|
+
|
|
20
|
+
asyncio.run(main())
|
|
21
|
+
|
|
22
|
+
Package layout
|
|
23
|
+
--------------
|
|
24
|
+
fp_soother_lib/
|
|
25
|
+
constants.py ← UUIDs, command IDs, state bit-layout tables
|
|
26
|
+
encryption.py ← real AES-128-CBC crypto + key derivation
|
|
27
|
+
protocol.py ← SootherState + command-frame construction
|
|
28
|
+
pairing.py ← the from-scratch pairing handshake
|
|
29
|
+
client.py ← high-level async client (the main entry point)
|
|
30
|
+
scanner.py ← BLE discovery & GATT-dump helpers
|
|
31
|
+
exceptions.py ← library-specific exceptions
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
from importlib.metadata import version
|
|
35
|
+
|
|
36
|
+
from bleak.backends.device import BLEDevice
|
|
37
|
+
|
|
38
|
+
from .client import SootherClient
|
|
39
|
+
from .exceptions import (
|
|
40
|
+
SootherCommandError,
|
|
41
|
+
SootherConnectionError,
|
|
42
|
+
SootherError,
|
|
43
|
+
SootherNotFoundError,
|
|
44
|
+
)
|
|
45
|
+
from .protocol import SootherState
|
|
46
|
+
from .scanner import dump_gatt, find_soother, scan
|
|
47
|
+
|
|
48
|
+
__all__ = [
|
|
49
|
+
"BLEDevice",
|
|
50
|
+
"SootherClient",
|
|
51
|
+
"SootherCommandError",
|
|
52
|
+
"SootherConnectionError",
|
|
53
|
+
"SootherError",
|
|
54
|
+
"SootherNotFoundError",
|
|
55
|
+
"SootherState",
|
|
56
|
+
"dump_gatt",
|
|
57
|
+
"find_soother",
|
|
58
|
+
"scan",
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
__version__ = version("fp-soother-lib")
|