tinkly 0.2.0__tar.gz → 0.2.1__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.
- tinkly-0.2.1/PKG-INFO +61 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/pyproject.toml +22 -1
- tinkly-0.2.1/tinkly.egg-info/PKG-INFO +61 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/uv.lock +2 -2
- tinkly-0.2.0/PKG-INFO +0 -5
- tinkly-0.2.0/tinkly.egg-info/PKG-INFO +0 -5
- {tinkly-0.2.0 → tinkly-0.2.1}/MANIFEST.in +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/README.md +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/doc/contributing.md +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/doc/index.md +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/scripts/build_docs.py +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/scripts/griffe_tinkly.py +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/setup.cfg +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/tests/test_authentication.py +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/tests/test_client.py +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/tests/test_client_authentication.py +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/tests/test_discovery.py +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/tests/test_documentation.py +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/tests/test_frame.py +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/tinkly/__init__.py +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/tinkly/authentication.py +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/tinkly/client.py +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/tinkly/discovery.py +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/tinkly/errors.py +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/tinkly/frame.py +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/tinkly.egg-info/SOURCES.txt +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/tinkly.egg-info/dependency_links.txt +0 -0
- {tinkly-0.2.0 → tinkly-0.2.1}/tinkly.egg-info/top_level.txt +0 -0
tinkly-0.2.1/PKG-INFO
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tinkly
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: Low-level Twinkly discovery, authentication, HTTP, and realtime UDP transport
|
|
5
|
+
Author-email: Tom Ritchford <tom@swirly.com>
|
|
6
|
+
Project-URL: Documentation, https://rec.github.io/tinkly/
|
|
7
|
+
Project-URL: Repository, https://github.com/rec/tinkly
|
|
8
|
+
Project-URL: Issues, https://github.com/rec/tinkly/issues
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
14
|
+
Requires-Python: >=3.12
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# tinkly: a tiny interface to Twinkly v2 lights
|
|
18
|
+
|
|
19
|
+
I love the Twinkly lights but the [xled library](https://github.com/scrool/xled) is
|
|
20
|
+
filled with complicated cruft which obscures the actual communication layer, and seems
|
|
21
|
+
to no longer be in development.
|
|
22
|
+
|
|
23
|
+
In particular, xled has a totally unnecessary ZMQ queue that
|
|
24
|
+
slows everything down and prevents two clients from existing.
|
|
25
|
+
|
|
26
|
+
I re-implemented just the Twinkly communication part, and left all the other
|
|
27
|
+
parts behind. In particular, there is no CLI - for that, you'll have to see my
|
|
28
|
+
upcoming general project, "lyte".
|
|
29
|
+
|
|
30
|
+
## Device communication
|
|
31
|
+
|
|
32
|
+
This package provides UDP discovery, authentication, HTTP endpoint access for generation
|
|
33
|
+
2 Twinkly lights.
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from tinkly.client import TwinklyClient
|
|
37
|
+
from tinkly.discovery import discover
|
|
38
|
+
from tinkly.frame import send_frame
|
|
39
|
+
|
|
40
|
+
devices = list(discover(timeout=2.0))
|
|
41
|
+
client = TwinklyClient(host=devices[0].ip_address)
|
|
42
|
+
info = client.get('gestalt', authenticated=False).data
|
|
43
|
+
client.mac = str(info['mac'])
|
|
44
|
+
token = client.authenticate()
|
|
45
|
+
|
|
46
|
+
client.set_realtime_mode()
|
|
47
|
+
frame = bytes((255, 0, 0)) * int(str(info['number_of_led']))
|
|
48
|
+
send_frame(client.host, token.value, frame)
|
|
49
|
+
client.set_off_mode()
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Frame buffers
|
|
53
|
+
|
|
54
|
+
`lyte` uses `numpy`, but I decided not to make that a dependency. Instead, we use
|
|
55
|
+
Python's buffer protocol `collections.abc.Buffer`. The input is C-style unsigned bytes
|
|
56
|
+
in RGB order, with three bytes per LED. Supported inputs include `bytes`, `bytearray`,
|
|
57
|
+
`array.array('B')`, `memoryview`, and C-contiguous NumPy `uint8` arrays.
|
|
58
|
+
|
|
59
|
+
## The API
|
|
60
|
+
|
|
61
|
+
https://rec.github.io/tinkly/
|
|
@@ -4,9 +4,23 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tinkly"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.1"
|
|
8
8
|
description = "Low-level Twinkly discovery, authentication, HTTP, and realtime UDP transport"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
authors = [{ name = "Tom Ritchford", email = "tom@swirly.com" }]
|
|
9
11
|
requires-python = ">=3.12"
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Programming Language :: Python :: 3",
|
|
14
|
+
"Programming Language :: Python :: 3.12",
|
|
15
|
+
"Programming Language :: Python :: 3.13",
|
|
16
|
+
"Programming Language :: Python :: 3.14",
|
|
17
|
+
"Programming Language :: Python :: 3.15",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[project.urls]
|
|
21
|
+
Documentation = "https://rec.github.io/tinkly/"
|
|
22
|
+
Repository = "https://github.com/rec/tinkly"
|
|
23
|
+
Issues = "https://github.com/rec/tinkly/issues"
|
|
10
24
|
|
|
11
25
|
[tool.setuptools.packages.find]
|
|
12
26
|
where = ["."]
|
|
@@ -15,8 +29,12 @@ include = ["tinkly*"]
|
|
|
15
29
|
[tool.ruff.format]
|
|
16
30
|
quote-style = "single"
|
|
17
31
|
|
|
32
|
+
[tool.ruff.lint]
|
|
33
|
+
select = ["B", "E", "F", "I"]
|
|
34
|
+
|
|
18
35
|
[tool.pytest.ini_options]
|
|
19
36
|
pythonpath = ["."]
|
|
37
|
+
testpaths = ["tests"]
|
|
20
38
|
|
|
21
39
|
[dependency-groups]
|
|
22
40
|
dev = [
|
|
@@ -29,6 +47,9 @@ dev = [
|
|
|
29
47
|
"tyro",
|
|
30
48
|
]
|
|
31
49
|
|
|
50
|
+
[tool.uv]
|
|
51
|
+
exclude-newer = "1 week"
|
|
52
|
+
|
|
32
53
|
[tool.uv.sources]
|
|
33
54
|
reccy = { git = "ssh://git@github.com/rec/reccy.git", branch = "main" }
|
|
34
55
|
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tinkly
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: Low-level Twinkly discovery, authentication, HTTP, and realtime UDP transport
|
|
5
|
+
Author-email: Tom Ritchford <tom@swirly.com>
|
|
6
|
+
Project-URL: Documentation, https://rec.github.io/tinkly/
|
|
7
|
+
Project-URL: Repository, https://github.com/rec/tinkly
|
|
8
|
+
Project-URL: Issues, https://github.com/rec/tinkly/issues
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
14
|
+
Requires-Python: >=3.12
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# tinkly: a tiny interface to Twinkly v2 lights
|
|
18
|
+
|
|
19
|
+
I love the Twinkly lights but the [xled library](https://github.com/scrool/xled) is
|
|
20
|
+
filled with complicated cruft which obscures the actual communication layer, and seems
|
|
21
|
+
to no longer be in development.
|
|
22
|
+
|
|
23
|
+
In particular, xled has a totally unnecessary ZMQ queue that
|
|
24
|
+
slows everything down and prevents two clients from existing.
|
|
25
|
+
|
|
26
|
+
I re-implemented just the Twinkly communication part, and left all the other
|
|
27
|
+
parts behind. In particular, there is no CLI - for that, you'll have to see my
|
|
28
|
+
upcoming general project, "lyte".
|
|
29
|
+
|
|
30
|
+
## Device communication
|
|
31
|
+
|
|
32
|
+
This package provides UDP discovery, authentication, HTTP endpoint access for generation
|
|
33
|
+
2 Twinkly lights.
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from tinkly.client import TwinklyClient
|
|
37
|
+
from tinkly.discovery import discover
|
|
38
|
+
from tinkly.frame import send_frame
|
|
39
|
+
|
|
40
|
+
devices = list(discover(timeout=2.0))
|
|
41
|
+
client = TwinklyClient(host=devices[0].ip_address)
|
|
42
|
+
info = client.get('gestalt', authenticated=False).data
|
|
43
|
+
client.mac = str(info['mac'])
|
|
44
|
+
token = client.authenticate()
|
|
45
|
+
|
|
46
|
+
client.set_realtime_mode()
|
|
47
|
+
frame = bytes((255, 0, 0)) * int(str(info['number_of_led']))
|
|
48
|
+
send_frame(client.host, token.value, frame)
|
|
49
|
+
client.set_off_mode()
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Frame buffers
|
|
53
|
+
|
|
54
|
+
`lyte` uses `numpy`, but I decided not to make that a dependency. Instead, we use
|
|
55
|
+
Python's buffer protocol `collections.abc.Buffer`. The input is C-style unsigned bytes
|
|
56
|
+
in RGB order, with three bytes per LED. Supported inputs include `bytes`, `bytearray`,
|
|
57
|
+
`array.array('B')`, `memoryview`, and C-contiguous NumPy `uint8` arrays.
|
|
58
|
+
|
|
59
|
+
## The API
|
|
60
|
+
|
|
61
|
+
https://rec.github.io/tinkly/
|
|
@@ -7,7 +7,7 @@ resolution-markers = [
|
|
|
7
7
|
]
|
|
8
8
|
|
|
9
9
|
[options]
|
|
10
|
-
exclude-newer = "2026-11-04T19:
|
|
10
|
+
exclude-newer = "2026-11-04T19:32:54.323936Z"
|
|
11
11
|
exclude-newer-span = "P1W"
|
|
12
12
|
|
|
13
13
|
[[package]]
|
|
@@ -327,7 +327,7 @@ wheels = [
|
|
|
327
327
|
|
|
328
328
|
[[package]]
|
|
329
329
|
name = "tinkly"
|
|
330
|
-
version = "0.2.
|
|
330
|
+
version = "0.2.1"
|
|
331
331
|
source = { editable = "." }
|
|
332
332
|
|
|
333
333
|
[package.dev-dependencies]
|
tinkly-0.2.0/PKG-INFO
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|