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.
@@ -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")