From 7d4975f7173d15d8a8a0a7e73af5b3a8ee7e6296 Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Sun, 10 Aug 2025 15:36:38 +0000 Subject: [PATCH 01/21] feat: add devcontainer --- .devcontainer/devcontainer.json | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..3dcdd94 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,20 @@ +// For format details, see https://aka.ms/devcontainer.json. +{ + "name": "Python 3", + "image": "mcr.microsoft.com/devcontainers/python:1-3-bookworm", + "runArgs": [ + // Use host network for discovery + "--network=host" + ], + "features": { + "ghcr.io/va-h/devcontainers-features/uv:1": {} + }, + "customizations": { + "vscode": { + "extensions": [ + "charliermarsh.ruff", + "tamasfe.even-better-toml", + ] + } + } +} \ No newline at end of file From aa545e1091f69768557bb8c656b226d9ddacba91 Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Sun, 10 Aug 2025 15:54:43 +0000 Subject: [PATCH 02/21] chore: migrate to pyproject.toml with uv --- MANIFEST.in | 1 - pyproject.toml | 43 +++ requirements.txt | 2 - setup.py | 41 --- uv.lock | 688 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 731 insertions(+), 44 deletions(-) delete mode 100644 MANIFEST.in create mode 100644 pyproject.toml delete mode 100644 requirements.txt delete mode 100644 setup.py create mode 100644 uv.lock diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index 1aba38f..0000000 --- a/MANIFEST.in +++ /dev/null @@ -1 +0,0 @@ -include LICENSE diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..38903f2 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,43 @@ +[project] +name = "dingz" +version = "0.6.0.dev0" +authors = [ + { name = "Fabian Affolter", email = "fabian@affolter-engineering.ch" }, +] +description = "Python API for interacting with Dingz devices" +readme = "README.rst" +license = "Apache-2.0" +requires-python = ">=3.9" +classifiers = [ + "Development Status :: 3 - Alpha", + "Environment :: Console", + "Intended Audience :: Developers", + "License :: OSI Approved :: Apache Software License", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Topic :: Utilities", +] +dependencies = [ + "aiohttp<4", + "async-timeout>=5.0.1 ; python_full_version < '3.11'", + "click>=8.1.8", + "setuptools>=80.9.0", +] + +[project.urls] +Repository = "https://github.com/home-assistant-ecosystem/python-dingz" + +[project.scripts] +dingz = "dingz.cli:main" + +[build-system] +requires = ["uv_build>=0.8.7,<0.9.0"] +build-backend = "uv_build" + +[tool.uv.build-backend] +module-name = "dingz" +module-root = "" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 0005a6c..0000000 --- a/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -# python-dingz requirements. Use setup.py for the dependencies. -. diff --git a/setup.py b/setup.py deleted file mode 100644 index 55725fa..0000000 --- a/setup.py +++ /dev/null @@ -1,41 +0,0 @@ -"""Set up the Python API for dingz devices.""" -import os - -import sys - -from setuptools import setup, find_packages - -here = os.path.abspath(os.path.dirname(__file__)) - -with open(os.path.join(here, "README.rst"), encoding="utf-8") as readme: - long_description = readme.read() - -setup( - name="dingz", - version="0.6.0.dev0", - description="Python API for interacting with Dingz devices", - long_description=long_description, - url="https://github.com/home-assistant-ecosystem/python-dingz", - author="Fabian Affolter", - author_email="fabian@affolter-engineering.ch", - license="Apache License 2.0", - install_requires=["aiohttp<4", "async_timeout; python_version < \"3.11\"", "click", "setuptools"], - packages=find_packages(), - python_requires='>=3.9', - zip_safe=True, - include_package_data=True, - entry_points={"console_scripts": ["dingz = dingz.cli:main"]}, - classifiers=[ - "Development Status :: 3 - Alpha", - "Environment :: Console", - "Intended Audience :: Developers", - "License :: OSI Approved :: Apache Software License", - "Operating System :: MacOS :: MacOS X", - "Operating System :: Microsoft :: Windows", - "Operating System :: POSIX", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Topic :: Utilities", - ], -) diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..511f20f --- /dev/null +++ b/uv.lock @@ -0,0 +1,688 @@ +version = 1 +revision = 3 +requires-python = ">=3.9" +resolution-markers = [ + "python_full_version >= '3.10'", + "python_full_version < '3.10'", +] + +[[package]] +name = "aiohappyeyeballs" +version = "2.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, +] + +[[package]] +name = "aiohttp" +version = "3.12.15" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohappyeyeballs" }, + { name = "aiosignal" }, + { name = "async-timeout", marker = "python_full_version < '3.11'" }, + { name = "attrs" }, + { name = "frozenlist" }, + { name = "multidict" }, + { name = "propcache" }, + { name = "yarl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9b/e7/d92a237d8802ca88483906c388f7c201bbe96cd80a165ffd0ac2f6a8d59f/aiohttp-3.12.15.tar.gz", hash = "sha256:4fc61385e9c98d72fcdf47e6dd81833f47b2f77c114c29cd64a361be57a763a2", size = 7823716, upload-time = "2025-07-29T05:52:32.215Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/dc/ef9394bde9080128ad401ac7ede185267ed637df03b51f05d14d1c99ad67/aiohttp-3.12.15-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b6fc902bff74d9b1879ad55f5404153e2b33a82e72a95c89cec5eb6cc9e92fbc", size = 703921, upload-time = "2025-07-29T05:49:43.584Z" }, + { url = "https://files.pythonhosted.org/packages/8f/42/63fccfc3a7ed97eb6e1a71722396f409c46b60a0552d8a56d7aad74e0df5/aiohttp-3.12.15-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:098e92835b8119b54c693f2f88a1dec690e20798ca5f5fe5f0520245253ee0af", size = 480288, upload-time = "2025-07-29T05:49:47.851Z" }, + { url = "https://files.pythonhosted.org/packages/9c/a2/7b8a020549f66ea2a68129db6960a762d2393248f1994499f8ba9728bbed/aiohttp-3.12.15-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:40b3fee496a47c3b4a39a731954c06f0bd9bd3e8258c059a4beb76ac23f8e421", size = 468063, upload-time = "2025-07-29T05:49:49.789Z" }, + { url = "https://files.pythonhosted.org/packages/8f/f5/d11e088da9176e2ad8220338ae0000ed5429a15f3c9dfd983f39105399cd/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ce13fcfb0bb2f259fb42106cdc63fa5515fb85b7e87177267d89a771a660b79", size = 1650122, upload-time = "2025-07-29T05:49:51.874Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6b/b60ce2757e2faed3d70ed45dafee48cee7bfb878785a9423f7e883f0639c/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3beb14f053222b391bf9cf92ae82e0171067cc9c8f52453a0f1ec7c37df12a77", size = 1624176, upload-time = "2025-07-29T05:49:53.805Z" }, + { url = "https://files.pythonhosted.org/packages/dd/de/8c9fde2072a1b72c4fadecf4f7d4be7a85b1d9a4ab333d8245694057b4c6/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4c39e87afe48aa3e814cac5f535bc6199180a53e38d3f51c5e2530f5aa4ec58c", size = 1696583, upload-time = "2025-07-29T05:49:55.338Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ad/07f863ca3d895a1ad958a54006c6dafb4f9310f8c2fdb5f961b8529029d3/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5f1b4ce5bc528a6ee38dbf5f39bbf11dd127048726323b72b8e85769319ffc4", size = 1738896, upload-time = "2025-07-29T05:49:57.045Z" }, + { url = "https://files.pythonhosted.org/packages/20/43/2bd482ebe2b126533e8755a49b128ec4e58f1a3af56879a3abdb7b42c54f/aiohttp-3.12.15-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1004e67962efabbaf3f03b11b4c43b834081c9e3f9b32b16a7d97d4708a9abe6", size = 1643561, upload-time = "2025-07-29T05:49:58.762Z" }, + { url = "https://files.pythonhosted.org/packages/23/40/2fa9f514c4cf4cbae8d7911927f81a1901838baf5e09a8b2c299de1acfe5/aiohttp-3.12.15-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8faa08fcc2e411f7ab91d1541d9d597d3a90e9004180edb2072238c085eac8c2", size = 1583685, upload-time = "2025-07-29T05:50:00.375Z" }, + { url = "https://files.pythonhosted.org/packages/b8/c3/94dc7357bc421f4fb978ca72a201a6c604ee90148f1181790c129396ceeb/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fe086edf38b2222328cdf89af0dde2439ee173b8ad7cb659b4e4c6f385b2be3d", size = 1627533, upload-time = "2025-07-29T05:50:02.306Z" }, + { url = "https://files.pythonhosted.org/packages/bf/3f/1f8911fe1844a07001e26593b5c255a685318943864b27b4e0267e840f95/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:79b26fe467219add81d5e47b4a4ba0f2394e8b7c7c3198ed36609f9ba161aecb", size = 1638319, upload-time = "2025-07-29T05:50:04.282Z" }, + { url = "https://files.pythonhosted.org/packages/4e/46/27bf57a99168c4e145ffee6b63d0458b9c66e58bb70687c23ad3d2f0bd17/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b761bac1192ef24e16706d761aefcb581438b34b13a2f069a6d343ec8fb693a5", size = 1613776, upload-time = "2025-07-29T05:50:05.863Z" }, + { url = "https://files.pythonhosted.org/packages/0f/7e/1d2d9061a574584bb4ad3dbdba0da90a27fdc795bc227def3a46186a8bc1/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e153e8adacfe2af562861b72f8bc47f8a5c08e010ac94eebbe33dc21d677cd5b", size = 1693359, upload-time = "2025-07-29T05:50:07.563Z" }, + { url = "https://files.pythonhosted.org/packages/08/98/bee429b52233c4a391980a5b3b196b060872a13eadd41c3a34be9b1469ed/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:fc49c4de44977aa8601a00edbf157e9a421f227aa7eb477d9e3df48343311065", size = 1716598, upload-time = "2025-07-29T05:50:09.33Z" }, + { url = "https://files.pythonhosted.org/packages/57/39/b0314c1ea774df3392751b686104a3938c63ece2b7ce0ba1ed7c0b4a934f/aiohttp-3.12.15-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2776c7ec89c54a47029940177e75c8c07c29c66f73464784971d6a81904ce9d1", size = 1644940, upload-time = "2025-07-29T05:50:11.334Z" }, + { url = "https://files.pythonhosted.org/packages/1b/83/3dacb8d3f8f512c8ca43e3fa8a68b20583bd25636ffa4e56ee841ffd79ae/aiohttp-3.12.15-cp310-cp310-win32.whl", hash = "sha256:2c7d81a277fa78b2203ab626ced1487420e8c11a8e373707ab72d189fcdad20a", size = 429239, upload-time = "2025-07-29T05:50:12.803Z" }, + { url = "https://files.pythonhosted.org/packages/eb/f9/470b5daba04d558c9673ca2034f28d067f3202a40e17804425f0c331c89f/aiohttp-3.12.15-cp310-cp310-win_amd64.whl", hash = "sha256:83603f881e11f0f710f8e2327817c82e79431ec976448839f3cd05d7afe8f830", size = 452297, upload-time = "2025-07-29T05:50:14.266Z" }, + { url = "https://files.pythonhosted.org/packages/20/19/9e86722ec8e835959bd97ce8c1efa78cf361fa4531fca372551abcc9cdd6/aiohttp-3.12.15-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d3ce17ce0220383a0f9ea07175eeaa6aa13ae5a41f30bc61d84df17f0e9b1117", size = 711246, upload-time = "2025-07-29T05:50:15.937Z" }, + { url = "https://files.pythonhosted.org/packages/71/f9/0a31fcb1a7d4629ac9d8f01f1cb9242e2f9943f47f5d03215af91c3c1a26/aiohttp-3.12.15-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:010cc9bbd06db80fe234d9003f67e97a10fe003bfbedb40da7d71c1008eda0fe", size = 483515, upload-time = "2025-07-29T05:50:17.442Z" }, + { url = "https://files.pythonhosted.org/packages/62/6c/94846f576f1d11df0c2e41d3001000527c0fdf63fce7e69b3927a731325d/aiohttp-3.12.15-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3f9d7c55b41ed687b9d7165b17672340187f87a773c98236c987f08c858145a9", size = 471776, upload-time = "2025-07-29T05:50:19.568Z" }, + { url = "https://files.pythonhosted.org/packages/f8/6c/f766d0aaafcee0447fad0328da780d344489c042e25cd58fde566bf40aed/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc4fbc61bb3548d3b482f9ac7ddd0f18c67e4225aaa4e8552b9f1ac7e6bda9e5", size = 1741977, upload-time = "2025-07-29T05:50:21.665Z" }, + { url = "https://files.pythonhosted.org/packages/17/e5/fb779a05ba6ff44d7bc1e9d24c644e876bfff5abe5454f7b854cace1b9cc/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7fbc8a7c410bb3ad5d595bb7118147dfbb6449d862cc1125cf8867cb337e8728", size = 1690645, upload-time = "2025-07-29T05:50:23.333Z" }, + { url = "https://files.pythonhosted.org/packages/37/4e/a22e799c2035f5d6a4ad2cf8e7c1d1bd0923192871dd6e367dafb158b14c/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74dad41b3458dbb0511e760fb355bb0b6689e0630de8a22b1b62a98777136e16", size = 1789437, upload-time = "2025-07-29T05:50:25.007Z" }, + { url = "https://files.pythonhosted.org/packages/28/e5/55a33b991f6433569babb56018b2fb8fb9146424f8b3a0c8ecca80556762/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b6f0af863cf17e6222b1735a756d664159e58855da99cfe965134a3ff63b0b0", size = 1828482, upload-time = "2025-07-29T05:50:26.693Z" }, + { url = "https://files.pythonhosted.org/packages/c6/82/1ddf0ea4f2f3afe79dffed5e8a246737cff6cbe781887a6a170299e33204/aiohttp-3.12.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5b7fe4972d48a4da367043b8e023fb70a04d1490aa7d68800e465d1b97e493b", size = 1730944, upload-time = "2025-07-29T05:50:28.382Z" }, + { url = "https://files.pythonhosted.org/packages/1b/96/784c785674117b4cb3877522a177ba1b5e4db9ce0fd519430b5de76eec90/aiohttp-3.12.15-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6443cca89553b7a5485331bc9bedb2342b08d073fa10b8c7d1c60579c4a7b9bd", size = 1668020, upload-time = "2025-07-29T05:50:30.032Z" }, + { url = "https://files.pythonhosted.org/packages/12/8a/8b75f203ea7e5c21c0920d84dd24a5c0e971fe1e9b9ebbf29ae7e8e39790/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6c5f40ec615e5264f44b4282ee27628cea221fcad52f27405b80abb346d9f3f8", size = 1716292, upload-time = "2025-07-29T05:50:31.983Z" }, + { url = "https://files.pythonhosted.org/packages/47/0b/a1451543475bb6b86a5cfc27861e52b14085ae232896a2654ff1231c0992/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:2abbb216a1d3a2fe86dbd2edce20cdc5e9ad0be6378455b05ec7f77361b3ab50", size = 1711451, upload-time = "2025-07-29T05:50:33.989Z" }, + { url = "https://files.pythonhosted.org/packages/55/fd/793a23a197cc2f0d29188805cfc93aa613407f07e5f9da5cd1366afd9d7c/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:db71ce547012a5420a39c1b744d485cfb823564d01d5d20805977f5ea1345676", size = 1691634, upload-time = "2025-07-29T05:50:35.846Z" }, + { url = "https://files.pythonhosted.org/packages/ca/bf/23a335a6670b5f5dfc6d268328e55a22651b440fca341a64fccf1eada0c6/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ced339d7c9b5030abad5854aa5413a77565e5b6e6248ff927d3e174baf3badf7", size = 1785238, upload-time = "2025-07-29T05:50:37.597Z" }, + { url = "https://files.pythonhosted.org/packages/57/4f/ed60a591839a9d85d40694aba5cef86dde9ee51ce6cca0bb30d6eb1581e7/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7c7dd29c7b5bda137464dc9bfc738d7ceea46ff70309859ffde8c022e9b08ba7", size = 1805701, upload-time = "2025-07-29T05:50:39.591Z" }, + { url = "https://files.pythonhosted.org/packages/85/e0/444747a9455c5de188c0f4a0173ee701e2e325d4b2550e9af84abb20cdba/aiohttp-3.12.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:421da6fd326460517873274875c6c5a18ff225b40da2616083c5a34a7570b685", size = 1718758, upload-time = "2025-07-29T05:50:41.292Z" }, + { url = "https://files.pythonhosted.org/packages/36/ab/1006278d1ffd13a698e5dd4bfa01e5878f6bddefc296c8b62649753ff249/aiohttp-3.12.15-cp311-cp311-win32.whl", hash = "sha256:4420cf9d179ec8dfe4be10e7d0fe47d6d606485512ea2265b0d8c5113372771b", size = 428868, upload-time = "2025-07-29T05:50:43.063Z" }, + { url = "https://files.pythonhosted.org/packages/10/97/ad2b18700708452400278039272032170246a1bf8ec5d832772372c71f1a/aiohttp-3.12.15-cp311-cp311-win_amd64.whl", hash = "sha256:edd533a07da85baa4b423ee8839e3e91681c7bfa19b04260a469ee94b778bf6d", size = 453273, upload-time = "2025-07-29T05:50:44.613Z" }, + { url = "https://files.pythonhosted.org/packages/63/97/77cb2450d9b35f517d6cf506256bf4f5bda3f93a66b4ad64ba7fc917899c/aiohttp-3.12.15-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:802d3868f5776e28f7bf69d349c26fc0efadb81676d0afa88ed00d98a26340b7", size = 702333, upload-time = "2025-07-29T05:50:46.507Z" }, + { url = "https://files.pythonhosted.org/packages/83/6d/0544e6b08b748682c30b9f65640d006e51f90763b41d7c546693bc22900d/aiohttp-3.12.15-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2800614cd560287be05e33a679638e586a2d7401f4ddf99e304d98878c29444", size = 476948, upload-time = "2025-07-29T05:50:48.067Z" }, + { url = "https://files.pythonhosted.org/packages/3a/1d/c8c40e611e5094330284b1aea8a4b02ca0858f8458614fa35754cab42b9c/aiohttp-3.12.15-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8466151554b593909d30a0a125d638b4e5f3836e5aecde85b66b80ded1cb5b0d", size = 469787, upload-time = "2025-07-29T05:50:49.669Z" }, + { url = "https://files.pythonhosted.org/packages/38/7d/b76438e70319796bfff717f325d97ce2e9310f752a267bfdf5192ac6082b/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e5a495cb1be69dae4b08f35a6c4579c539e9b5706f606632102c0f855bcba7c", size = 1716590, upload-time = "2025-07-29T05:50:51.368Z" }, + { url = "https://files.pythonhosted.org/packages/79/b1/60370d70cdf8b269ee1444b390cbd72ce514f0d1cd1a715821c784d272c9/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6404dfc8cdde35c69aaa489bb3542fb86ef215fc70277c892be8af540e5e21c0", size = 1699241, upload-time = "2025-07-29T05:50:53.628Z" }, + { url = "https://files.pythonhosted.org/packages/a3/2b/4968a7b8792437ebc12186db31523f541943e99bda8f30335c482bea6879/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3ead1c00f8521a5c9070fcb88f02967b1d8a0544e6d85c253f6968b785e1a2ab", size = 1754335, upload-time = "2025-07-29T05:50:55.394Z" }, + { url = "https://files.pythonhosted.org/packages/fb/c1/49524ed553f9a0bec1a11fac09e790f49ff669bcd14164f9fab608831c4d/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6990ef617f14450bc6b34941dba4f12d5613cbf4e33805932f853fbd1cf18bfb", size = 1800491, upload-time = "2025-07-29T05:50:57.202Z" }, + { url = "https://files.pythonhosted.org/packages/de/5e/3bf5acea47a96a28c121b167f5ef659cf71208b19e52a88cdfa5c37f1fcc/aiohttp-3.12.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd736ed420f4db2b8148b52b46b88ed038d0354255f9a73196b7bbce3ea97545", size = 1719929, upload-time = "2025-07-29T05:50:59.192Z" }, + { url = "https://files.pythonhosted.org/packages/39/94/8ae30b806835bcd1cba799ba35347dee6961a11bd507db634516210e91d8/aiohttp-3.12.15-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c5092ce14361a73086b90c6efb3948ffa5be2f5b6fbcf52e8d8c8b8848bb97c", size = 1635733, upload-time = "2025-07-29T05:51:01.394Z" }, + { url = "https://files.pythonhosted.org/packages/7a/46/06cdef71dd03acd9da7f51ab3a9107318aee12ad38d273f654e4f981583a/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aaa2234bb60c4dbf82893e934d8ee8dea30446f0647e024074237a56a08c01bd", size = 1696790, upload-time = "2025-07-29T05:51:03.657Z" }, + { url = "https://files.pythonhosted.org/packages/02/90/6b4cfaaf92ed98d0ec4d173e78b99b4b1a7551250be8937d9d67ecb356b4/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6d86a2fbdd14192e2f234a92d3b494dd4457e683ba07e5905a0b3ee25389ac9f", size = 1718245, upload-time = "2025-07-29T05:51:05.911Z" }, + { url = "https://files.pythonhosted.org/packages/2e/e6/2593751670fa06f080a846f37f112cbe6f873ba510d070136a6ed46117c6/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a041e7e2612041a6ddf1c6a33b883be6a421247c7afd47e885969ee4cc58bd8d", size = 1658899, upload-time = "2025-07-29T05:51:07.753Z" }, + { url = "https://files.pythonhosted.org/packages/8f/28/c15bacbdb8b8eb5bf39b10680d129ea7410b859e379b03190f02fa104ffd/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5015082477abeafad7203757ae44299a610e89ee82a1503e3d4184e6bafdd519", size = 1738459, upload-time = "2025-07-29T05:51:09.56Z" }, + { url = "https://files.pythonhosted.org/packages/00/de/c269cbc4faa01fb10f143b1670633a8ddd5b2e1ffd0548f7aa49cb5c70e2/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:56822ff5ddfd1b745534e658faba944012346184fbfe732e0d6134b744516eea", size = 1766434, upload-time = "2025-07-29T05:51:11.423Z" }, + { url = "https://files.pythonhosted.org/packages/52/b0/4ff3abd81aa7d929b27d2e1403722a65fc87b763e3a97b3a2a494bfc63bc/aiohttp-3.12.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b2acbbfff69019d9014508c4ba0401822e8bae5a5fdc3b6814285b71231b60f3", size = 1726045, upload-time = "2025-07-29T05:51:13.689Z" }, + { url = "https://files.pythonhosted.org/packages/71/16/949225a6a2dd6efcbd855fbd90cf476052e648fb011aa538e3b15b89a57a/aiohttp-3.12.15-cp312-cp312-win32.whl", hash = "sha256:d849b0901b50f2185874b9a232f38e26b9b3d4810095a7572eacea939132d4e1", size = 423591, upload-time = "2025-07-29T05:51:15.452Z" }, + { url = "https://files.pythonhosted.org/packages/2b/d8/fa65d2a349fe938b76d309db1a56a75c4fb8cc7b17a398b698488a939903/aiohttp-3.12.15-cp312-cp312-win_amd64.whl", hash = "sha256:b390ef5f62bb508a9d67cb3bba9b8356e23b3996da7062f1a57ce1a79d2b3d34", size = 450266, upload-time = "2025-07-29T05:51:17.239Z" }, + { url = "https://files.pythonhosted.org/packages/f2/33/918091abcf102e39d15aba2476ad9e7bd35ddb190dcdd43a854000d3da0d/aiohttp-3.12.15-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9f922ffd05034d439dde1c77a20461cf4a1b0831e6caa26151fe7aa8aaebc315", size = 696741, upload-time = "2025-07-29T05:51:19.021Z" }, + { url = "https://files.pythonhosted.org/packages/b5/2a/7495a81e39a998e400f3ecdd44a62107254803d1681d9189be5c2e4530cd/aiohttp-3.12.15-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:2ee8a8ac39ce45f3e55663891d4b1d15598c157b4d494a4613e704c8b43112cd", size = 474407, upload-time = "2025-07-29T05:51:21.165Z" }, + { url = "https://files.pythonhosted.org/packages/49/fc/a9576ab4be2dcbd0f73ee8675d16c707cfc12d5ee80ccf4015ba543480c9/aiohttp-3.12.15-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3eae49032c29d356b94eee45a3f39fdf4b0814b397638c2f718e96cfadf4c4e4", size = 466703, upload-time = "2025-07-29T05:51:22.948Z" }, + { url = "https://files.pythonhosted.org/packages/09/2f/d4bcc8448cf536b2b54eed48f19682031ad182faa3a3fee54ebe5b156387/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b97752ff12cc12f46a9b20327104448042fce5c33a624f88c18f66f9368091c7", size = 1705532, upload-time = "2025-07-29T05:51:25.211Z" }, + { url = "https://files.pythonhosted.org/packages/f1/f3/59406396083f8b489261e3c011aa8aee9df360a96ac8fa5c2e7e1b8f0466/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:894261472691d6fe76ebb7fcf2e5870a2ac284c7406ddc95823c8598a1390f0d", size = 1686794, upload-time = "2025-07-29T05:51:27.145Z" }, + { url = "https://files.pythonhosted.org/packages/dc/71/164d194993a8d114ee5656c3b7ae9c12ceee7040d076bf7b32fb98a8c5c6/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5fa5d9eb82ce98959fc1031c28198b431b4d9396894f385cb63f1e2f3f20ca6b", size = 1738865, upload-time = "2025-07-29T05:51:29.366Z" }, + { url = "https://files.pythonhosted.org/packages/1c/00/d198461b699188a93ead39cb458554d9f0f69879b95078dce416d3209b54/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0fa751efb11a541f57db59c1dd821bec09031e01452b2b6217319b3a1f34f3d", size = 1788238, upload-time = "2025-07-29T05:51:31.285Z" }, + { url = "https://files.pythonhosted.org/packages/85/b8/9e7175e1fa0ac8e56baa83bf3c214823ce250d0028955dfb23f43d5e61fd/aiohttp-3.12.15-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5346b93e62ab51ee2a9d68e8f73c7cf96ffb73568a23e683f931e52450e4148d", size = 1710566, upload-time = "2025-07-29T05:51:33.219Z" }, + { url = "https://files.pythonhosted.org/packages/59/e4/16a8eac9df39b48ae102ec030fa9f726d3570732e46ba0c592aeeb507b93/aiohttp-3.12.15-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:049ec0360f939cd164ecbfd2873eaa432613d5e77d6b04535e3d1fbae5a9e645", size = 1624270, upload-time = "2025-07-29T05:51:35.195Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f8/cd84dee7b6ace0740908fd0af170f9fab50c2a41ccbc3806aabcb1050141/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b52dcf013b57464b6d1e51b627adfd69a8053e84b7103a7cd49c030f9ca44461", size = 1677294, upload-time = "2025-07-29T05:51:37.215Z" }, + { url = "https://files.pythonhosted.org/packages/ce/42/d0f1f85e50d401eccd12bf85c46ba84f947a84839c8a1c2c5f6e8ab1eb50/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:9b2af240143dd2765e0fb661fd0361a1b469cab235039ea57663cda087250ea9", size = 1708958, upload-time = "2025-07-29T05:51:39.328Z" }, + { url = "https://files.pythonhosted.org/packages/d5/6b/f6fa6c5790fb602538483aa5a1b86fcbad66244997e5230d88f9412ef24c/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ac77f709a2cde2cc71257ab2d8c74dd157c67a0558a0d2799d5d571b4c63d44d", size = 1651553, upload-time = "2025-07-29T05:51:41.356Z" }, + { url = "https://files.pythonhosted.org/packages/04/36/a6d36ad545fa12e61d11d1932eef273928b0495e6a576eb2af04297fdd3c/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:47f6b962246f0a774fbd3b6b7be25d59b06fdb2f164cf2513097998fc6a29693", size = 1727688, upload-time = "2025-07-29T05:51:43.452Z" }, + { url = "https://files.pythonhosted.org/packages/aa/c8/f195e5e06608a97a4e52c5d41c7927301bf757a8e8bb5bbf8cef6c314961/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:760fb7db442f284996e39cf9915a94492e1896baac44f06ae551974907922b64", size = 1761157, upload-time = "2025-07-29T05:51:45.643Z" }, + { url = "https://files.pythonhosted.org/packages/05/6a/ea199e61b67f25ba688d3ce93f63b49b0a4e3b3d380f03971b4646412fc6/aiohttp-3.12.15-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad702e57dc385cae679c39d318def49aef754455f237499d5b99bea4ef582e51", size = 1710050, upload-time = "2025-07-29T05:51:48.203Z" }, + { url = "https://files.pythonhosted.org/packages/b4/2e/ffeb7f6256b33635c29dbed29a22a723ff2dd7401fff42ea60cf2060abfb/aiohttp-3.12.15-cp313-cp313-win32.whl", hash = "sha256:f813c3e9032331024de2eb2e32a88d86afb69291fbc37a3a3ae81cc9917fb3d0", size = 422647, upload-time = "2025-07-29T05:51:50.718Z" }, + { url = "https://files.pythonhosted.org/packages/1b/8e/78ee35774201f38d5e1ba079c9958f7629b1fd079459aea9467441dbfbf5/aiohttp-3.12.15-cp313-cp313-win_amd64.whl", hash = "sha256:1a649001580bdb37c6fdb1bebbd7e3bc688e8ec2b5c6f52edbb664662b17dc84", size = 449067, upload-time = "2025-07-29T05:51:52.549Z" }, + { url = "https://files.pythonhosted.org/packages/18/8d/da08099af8db234d1cd43163e6ffc8e9313d0e988cee1901610f2fa5c764/aiohttp-3.12.15-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:691d203c2bdf4f4637792efbbcdcd157ae11e55eaeb5e9c360c1206fb03d4d98", size = 706829, upload-time = "2025-07-29T05:51:54.434Z" }, + { url = "https://files.pythonhosted.org/packages/4e/94/8eed385cfb60cf4fdb5b8a165f6148f3bebeb365f08663d83c35a5f273ef/aiohttp-3.12.15-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8e995e1abc4ed2a454c731385bf4082be06f875822adc4c6d9eaadf96e20d406", size = 481806, upload-time = "2025-07-29T05:51:56.355Z" }, + { url = "https://files.pythonhosted.org/packages/38/68/b13e1a34584fbf263151b3a72a084e89f2102afe38df1dce5a05a15b83e9/aiohttp-3.12.15-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bd44d5936ab3193c617bfd6c9a7d8d1085a8dc8c3f44d5f1dcf554d17d04cf7d", size = 469205, upload-time = "2025-07-29T05:51:58.277Z" }, + { url = "https://files.pythonhosted.org/packages/38/14/3d7348bf53aa4af54416bc64cbef3a2ac5e8b9bfa97cc45f1cf9a94d9c8d/aiohttp-3.12.15-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46749be6e89cd78d6068cdf7da51dbcfa4321147ab8e4116ee6678d9a056a0cf", size = 1644174, upload-time = "2025-07-29T05:52:00.23Z" }, + { url = "https://files.pythonhosted.org/packages/ba/ed/fd9b5b22b0f6ca1a85c33bb4868cbcc6ae5eae070a0f4c9c5cad003c89d7/aiohttp-3.12.15-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0c643f4d75adea39e92c0f01b3fb83d57abdec8c9279b3078b68a3a52b3933b6", size = 1618672, upload-time = "2025-07-29T05:52:02.272Z" }, + { url = "https://files.pythonhosted.org/packages/39/f7/f6530ab5f8c8c409e44a63fcad35e839c87aabecdfe5b8e96d671ed12f64/aiohttp-3.12.15-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0a23918fedc05806966a2438489dcffccbdf83e921a1170773b6178d04ade142", size = 1692295, upload-time = "2025-07-29T05:52:04.546Z" }, + { url = "https://files.pythonhosted.org/packages/cb/dc/3cf483bb0106566dc97ebaa2bb097f5e44d4bc4ab650a6f107151cd7b193/aiohttp-3.12.15-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:74bdd8c864b36c3673741023343565d95bfbd778ffe1eb4d412c135a28a8dc89", size = 1731609, upload-time = "2025-07-29T05:52:06.552Z" }, + { url = "https://files.pythonhosted.org/packages/de/a4/fd04bf807851197077d9cac9381d58f86d91c95c06cbaf9d3a776ac4467a/aiohttp-3.12.15-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a146708808c9b7a988a4af3821379e379e0f0e5e466ca31a73dbdd0325b0263", size = 1637852, upload-time = "2025-07-29T05:52:08.975Z" }, + { url = "https://files.pythonhosted.org/packages/98/03/29d626ca3bcdcafbd74b45d77ca42645a5c94d396f2ee3446880ad2405fb/aiohttp-3.12.15-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7011a70b56facde58d6d26da4fec3280cc8e2a78c714c96b7a01a87930a9530", size = 1572852, upload-time = "2025-07-29T05:52:11.508Z" }, + { url = "https://files.pythonhosted.org/packages/5f/cd/b4777a9e204f4e01091091027e5d1e2fa86decd0fee5067bc168e4fa1e76/aiohttp-3.12.15-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:3bdd6e17e16e1dbd3db74d7f989e8af29c4d2e025f9828e6ef45fbdee158ec75", size = 1620813, upload-time = "2025-07-29T05:52:13.891Z" }, + { url = "https://files.pythonhosted.org/packages/ae/26/1a44a6e8417e84057beaf8c462529b9e05d4b53b8605784f1eb571f0ff68/aiohttp-3.12.15-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:57d16590a351dfc914670bd72530fd78344b885a00b250e992faea565b7fdc05", size = 1630951, upload-time = "2025-07-29T05:52:15.955Z" }, + { url = "https://files.pythonhosted.org/packages/dd/7f/10c605dbd01c40e2b27df7ef9004bec75d156f0705141e11047ecdfe264d/aiohttp-3.12.15-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:bc9a0f6569ff990e0bbd75506c8d8fe7214c8f6579cca32f0546e54372a3bb54", size = 1607595, upload-time = "2025-07-29T05:52:18.089Z" }, + { url = "https://files.pythonhosted.org/packages/66/f6/2560dcb01731c1d7df1d34b64de95bc4b3ed02bb78830fd82299c1eb314e/aiohttp-3.12.15-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:536ad7234747a37e50e7b6794ea868833d5220b49c92806ae2d7e8a9d6b5de02", size = 1695194, upload-time = "2025-07-29T05:52:20.255Z" }, + { url = "https://files.pythonhosted.org/packages/e7/02/ee105ae82dc2b981039fd25b0cf6eaa52b493731960f9bc861375a72b463/aiohttp-3.12.15-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f0adb4177fa748072546fb650d9bd7398caaf0e15b370ed3317280b13f4083b0", size = 1710872, upload-time = "2025-07-29T05:52:22.769Z" }, + { url = "https://files.pythonhosted.org/packages/88/16/70c4e42ed6a04f78fb58d1a46500a6ce560741d13afde2a5f33840746a5f/aiohttp-3.12.15-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:14954a2988feae3987f1eb49c706bff39947605f4b6fa4027c1d75743723eb09", size = 1640539, upload-time = "2025-07-29T05:52:25.733Z" }, + { url = "https://files.pythonhosted.org/packages/fe/1d/a7eb5fa8a6967117c5c0ad5ab4b1dec0d21e178c89aa08bc442a0b836392/aiohttp-3.12.15-cp39-cp39-win32.whl", hash = "sha256:b784d6ed757f27574dca1c336f968f4e81130b27595e458e69457e6878251f5d", size = 430164, upload-time = "2025-07-29T05:52:27.905Z" }, + { url = "https://files.pythonhosted.org/packages/14/25/e0cf8793aedc41c6d7f2aad646a27e27bdacafe3b402bb373d7651c94d73/aiohttp-3.12.15-cp39-cp39-win_amd64.whl", hash = "sha256:86ceded4e78a992f835209e236617bffae649371c4a50d5e5a3987f237db84b8", size = 453370, upload-time = "2025-07-29T05:52:29.936Z" }, +] + +[[package]] +name = "aiosignal" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "frozenlist" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, +] + +[[package]] +name = "async-timeout" +version = "5.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a5/ae/136395dfbfe00dfc94da3f3e136d0b13f394cba8f4841120e34226265780/async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3", size = 9274, upload-time = "2024-11-06T16:41:39.6Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c", size = 6233, upload-time = "2024-11-06T16:41:37.9Z" }, +] + +[[package]] +name = "attrs" +version = "25.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, +] + +[[package]] +name = "click" +version = "8.1.8" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +dependencies = [ + { name = "colorama", marker = "python_full_version < '3.10' and sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593, upload-time = "2024-12-21T18:38:44.339Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188, upload-time = "2024-12-21T18:38:41.666Z" }, +] + +[[package]] +name = "click" +version = "8.2.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.10'", +] +dependencies = [ + { name = "colorama", marker = "python_full_version >= '3.10' and sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "dingz" +version = "0.6.0.dev0" +source = { editable = "." } +dependencies = [ + { name = "aiohttp" }, + { name = "async-timeout", marker = "python_full_version < '3.11'" }, + { name = "click", version = "8.1.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "click", version = "8.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "setuptools" }, +] + +[package.metadata] +requires-dist = [ + { name = "aiohttp", specifier = "<4" }, + { name = "async-timeout", marker = "python_full_version < '3.11'", specifier = ">=5.0.1" }, + { name = "click", specifier = ">=8.1.8" }, + { name = "setuptools", specifier = ">=80.9.0" }, +] + +[[package]] +name = "frozenlist" +version = "1.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/79/b1/b64018016eeb087db503b038296fd782586432b9c077fc5c7839e9cb6ef6/frozenlist-1.7.0.tar.gz", hash = "sha256:2e310d81923c2437ea8670467121cc3e9b0f76d3043cc1d2331d56c7fb7a3a8f", size = 45078, upload-time = "2025-06-09T23:02:35.538Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/36/0da0a49409f6b47cc2d060dc8c9040b897b5902a8a4e37d9bc1deb11f680/frozenlist-1.7.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cc4df77d638aa2ed703b878dd093725b72a824c3c546c076e8fdf276f78ee84a", size = 81304, upload-time = "2025-06-09T22:59:46.226Z" }, + { url = "https://files.pythonhosted.org/packages/77/f0/77c11d13d39513b298e267b22eb6cb559c103d56f155aa9a49097221f0b6/frozenlist-1.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:716a9973a2cc963160394f701964fe25012600f3d311f60c790400b00e568b61", size = 47735, upload-time = "2025-06-09T22:59:48.133Z" }, + { url = "https://files.pythonhosted.org/packages/37/12/9d07fa18971a44150593de56b2f2947c46604819976784bcf6ea0d5db43b/frozenlist-1.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a0fd1bad056a3600047fb9462cff4c5322cebc59ebf5d0a3725e0ee78955001d", size = 46775, upload-time = "2025-06-09T22:59:49.564Z" }, + { url = "https://files.pythonhosted.org/packages/70/34/f73539227e06288fcd1f8a76853e755b2b48bca6747e99e283111c18bcd4/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3789ebc19cb811163e70fe2bd354cea097254ce6e707ae42e56f45e31e96cb8e", size = 224644, upload-time = "2025-06-09T22:59:51.35Z" }, + { url = "https://files.pythonhosted.org/packages/fb/68/c1d9c2f4a6e438e14613bad0f2973567586610cc22dcb1e1241da71de9d3/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af369aa35ee34f132fcfad5be45fbfcde0e3a5f6a1ec0712857f286b7d20cca9", size = 222125, upload-time = "2025-06-09T22:59:52.884Z" }, + { url = "https://files.pythonhosted.org/packages/b9/d0/98e8f9a515228d708344d7c6986752be3e3192d1795f748c24bcf154ad99/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac64b6478722eeb7a3313d494f8342ef3478dff539d17002f849101b212ef97c", size = 233455, upload-time = "2025-06-09T22:59:54.74Z" }, + { url = "https://files.pythonhosted.org/packages/79/df/8a11bcec5600557f40338407d3e5bea80376ed1c01a6c0910fcfdc4b8993/frozenlist-1.7.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f89f65d85774f1797239693cef07ad4c97fdd0639544bad9ac4b869782eb1981", size = 227339, upload-time = "2025-06-09T22:59:56.187Z" }, + { url = "https://files.pythonhosted.org/packages/50/82/41cb97d9c9a5ff94438c63cc343eb7980dac4187eb625a51bdfdb7707314/frozenlist-1.7.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1073557c941395fdfcfac13eb2456cb8aad89f9de27bae29fabca8e563b12615", size = 212969, upload-time = "2025-06-09T22:59:57.604Z" }, + { url = "https://files.pythonhosted.org/packages/13/47/f9179ee5ee4f55629e4f28c660b3fdf2775c8bfde8f9c53f2de2d93f52a9/frozenlist-1.7.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ed8d2fa095aae4bdc7fdd80351009a48d286635edffee66bf865e37a9125c50", size = 222862, upload-time = "2025-06-09T22:59:59.498Z" }, + { url = "https://files.pythonhosted.org/packages/1a/52/df81e41ec6b953902c8b7e3a83bee48b195cb0e5ec2eabae5d8330c78038/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:24c34bea555fe42d9f928ba0a740c553088500377448febecaa82cc3e88aa1fa", size = 222492, upload-time = "2025-06-09T23:00:01.026Z" }, + { url = "https://files.pythonhosted.org/packages/84/17/30d6ea87fa95a9408245a948604b82c1a4b8b3e153cea596421a2aef2754/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:69cac419ac6a6baad202c85aaf467b65ac860ac2e7f2ac1686dc40dbb52f6577", size = 238250, upload-time = "2025-06-09T23:00:03.401Z" }, + { url = "https://files.pythonhosted.org/packages/8f/00/ecbeb51669e3c3df76cf2ddd66ae3e48345ec213a55e3887d216eb4fbab3/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:960d67d0611f4c87da7e2ae2eacf7ea81a5be967861e0c63cf205215afbfac59", size = 218720, upload-time = "2025-06-09T23:00:05.282Z" }, + { url = "https://files.pythonhosted.org/packages/1a/c0/c224ce0e0eb31cc57f67742071bb470ba8246623c1823a7530be0e76164c/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:41be2964bd4b15bf575e5daee5a5ce7ed3115320fb3c2b71fca05582ffa4dc9e", size = 232585, upload-time = "2025-06-09T23:00:07.962Z" }, + { url = "https://files.pythonhosted.org/packages/55/3c/34cb694abf532f31f365106deebdeac9e45c19304d83cf7d51ebbb4ca4d1/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:46d84d49e00c9429238a7ce02dc0be8f6d7cd0cd405abd1bebdc991bf27c15bd", size = 234248, upload-time = "2025-06-09T23:00:09.428Z" }, + { url = "https://files.pythonhosted.org/packages/98/c0/2052d8b6cecda2e70bd81299e3512fa332abb6dcd2969b9c80dfcdddbf75/frozenlist-1.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:15900082e886edb37480335d9d518cec978afc69ccbc30bd18610b7c1b22a718", size = 221621, upload-time = "2025-06-09T23:00:11.32Z" }, + { url = "https://files.pythonhosted.org/packages/c5/bf/7dcebae315436903b1d98ffb791a09d674c88480c158aa171958a3ac07f0/frozenlist-1.7.0-cp310-cp310-win32.whl", hash = "sha256:400ddd24ab4e55014bba442d917203c73b2846391dd42ca5e38ff52bb18c3c5e", size = 39578, upload-time = "2025-06-09T23:00:13.526Z" }, + { url = "https://files.pythonhosted.org/packages/8f/5f/f69818f017fa9a3d24d1ae39763e29b7f60a59e46d5f91b9c6b21622f4cd/frozenlist-1.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:6eb93efb8101ef39d32d50bce242c84bcbddb4f7e9febfa7b524532a239b4464", size = 43830, upload-time = "2025-06-09T23:00:14.98Z" }, + { url = "https://files.pythonhosted.org/packages/34/7e/803dde33760128acd393a27eb002f2020ddb8d99d30a44bfbaab31c5f08a/frozenlist-1.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:aa51e147a66b2d74de1e6e2cf5921890de6b0f4820b257465101d7f37b49fb5a", size = 82251, upload-time = "2025-06-09T23:00:16.279Z" }, + { url = "https://files.pythonhosted.org/packages/75/a9/9c2c5760b6ba45eae11334db454c189d43d34a4c0b489feb2175e5e64277/frozenlist-1.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9b35db7ce1cd71d36ba24f80f0c9e7cff73a28d7a74e91fe83e23d27c7828750", size = 48183, upload-time = "2025-06-09T23:00:17.698Z" }, + { url = "https://files.pythonhosted.org/packages/47/be/4038e2d869f8a2da165f35a6befb9158c259819be22eeaf9c9a8f6a87771/frozenlist-1.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:34a69a85e34ff37791e94542065c8416c1afbf820b68f720452f636d5fb990cd", size = 47107, upload-time = "2025-06-09T23:00:18.952Z" }, + { url = "https://files.pythonhosted.org/packages/79/26/85314b8a83187c76a37183ceed886381a5f992975786f883472fcb6dc5f2/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a646531fa8d82c87fe4bb2e596f23173caec9185bfbca5d583b4ccfb95183e2", size = 237333, upload-time = "2025-06-09T23:00:20.275Z" }, + { url = "https://files.pythonhosted.org/packages/1f/fd/e5b64f7d2c92a41639ffb2ad44a6a82f347787abc0c7df5f49057cf11770/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:79b2ffbba483f4ed36a0f236ccb85fbb16e670c9238313709638167670ba235f", size = 231724, upload-time = "2025-06-09T23:00:21.705Z" }, + { url = "https://files.pythonhosted.org/packages/20/fb/03395c0a43a5976af4bf7534759d214405fbbb4c114683f434dfdd3128ef/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a26f205c9ca5829cbf82bb2a84b5c36f7184c4316617d7ef1b271a56720d6b30", size = 245842, upload-time = "2025-06-09T23:00:23.148Z" }, + { url = "https://files.pythonhosted.org/packages/d0/15/c01c8e1dffdac5d9803507d824f27aed2ba76b6ed0026fab4d9866e82f1f/frozenlist-1.7.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcacfad3185a623fa11ea0e0634aac7b691aa925d50a440f39b458e41c561d98", size = 239767, upload-time = "2025-06-09T23:00:25.103Z" }, + { url = "https://files.pythonhosted.org/packages/14/99/3f4c6fe882c1f5514b6848aa0a69b20cb5e5d8e8f51a339d48c0e9305ed0/frozenlist-1.7.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:72c1b0fe8fe451b34f12dce46445ddf14bd2a5bcad7e324987194dc8e3a74c86", size = 224130, upload-time = "2025-06-09T23:00:27.061Z" }, + { url = "https://files.pythonhosted.org/packages/4d/83/220a374bd7b2aeba9d0725130665afe11de347d95c3620b9b82cc2fcab97/frozenlist-1.7.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61d1a5baeaac6c0798ff6edfaeaa00e0e412d49946c53fae8d4b8e8b3566c4ae", size = 235301, upload-time = "2025-06-09T23:00:29.02Z" }, + { url = "https://files.pythonhosted.org/packages/03/3c/3e3390d75334a063181625343e8daab61b77e1b8214802cc4e8a1bb678fc/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7edf5c043c062462f09b6820de9854bf28cc6cc5b6714b383149745e287181a8", size = 234606, upload-time = "2025-06-09T23:00:30.514Z" }, + { url = "https://files.pythonhosted.org/packages/23/1e/58232c19608b7a549d72d9903005e2d82488f12554a32de2d5fb59b9b1ba/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:d50ac7627b3a1bd2dcef6f9da89a772694ec04d9a61b66cf87f7d9446b4a0c31", size = 248372, upload-time = "2025-06-09T23:00:31.966Z" }, + { url = "https://files.pythonhosted.org/packages/c0/a4/e4a567e01702a88a74ce8a324691e62a629bf47d4f8607f24bf1c7216e7f/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ce48b2fece5aeb45265bb7a58259f45027db0abff478e3077e12b05b17fb9da7", size = 229860, upload-time = "2025-06-09T23:00:33.375Z" }, + { url = "https://files.pythonhosted.org/packages/73/a6/63b3374f7d22268b41a9db73d68a8233afa30ed164c46107b33c4d18ecdd/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:fe2365ae915a1fafd982c146754e1de6ab3478def8a59c86e1f7242d794f97d5", size = 245893, upload-time = "2025-06-09T23:00:35.002Z" }, + { url = "https://files.pythonhosted.org/packages/6d/eb/d18b3f6e64799a79673c4ba0b45e4cfbe49c240edfd03a68be20002eaeaa/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:45a6f2fdbd10e074e8814eb98b05292f27bad7d1883afbe009d96abdcf3bc898", size = 246323, upload-time = "2025-06-09T23:00:36.468Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f5/720f3812e3d06cd89a1d5db9ff6450088b8f5c449dae8ffb2971a44da506/frozenlist-1.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:21884e23cffabb157a9dd7e353779077bf5b8f9a58e9b262c6caad2ef5f80a56", size = 233149, upload-time = "2025-06-09T23:00:37.963Z" }, + { url = "https://files.pythonhosted.org/packages/69/68/03efbf545e217d5db8446acfd4c447c15b7c8cf4dbd4a58403111df9322d/frozenlist-1.7.0-cp311-cp311-win32.whl", hash = "sha256:284d233a8953d7b24f9159b8a3496fc1ddc00f4db99c324bd5fb5f22d8698ea7", size = 39565, upload-time = "2025-06-09T23:00:39.753Z" }, + { url = "https://files.pythonhosted.org/packages/58/17/fe61124c5c333ae87f09bb67186d65038834a47d974fc10a5fadb4cc5ae1/frozenlist-1.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:387cbfdcde2f2353f19c2f66bbb52406d06ed77519ac7ee21be0232147c2592d", size = 44019, upload-time = "2025-06-09T23:00:40.988Z" }, + { url = "https://files.pythonhosted.org/packages/ef/a2/c8131383f1e66adad5f6ecfcce383d584ca94055a34d683bbb24ac5f2f1c/frozenlist-1.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3dbf9952c4bb0e90e98aec1bd992b3318685005702656bc6f67c1a32b76787f2", size = 81424, upload-time = "2025-06-09T23:00:42.24Z" }, + { url = "https://files.pythonhosted.org/packages/4c/9d/02754159955088cb52567337d1113f945b9e444c4960771ea90eb73de8db/frozenlist-1.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1f5906d3359300b8a9bb194239491122e6cf1444c2efb88865426f170c262cdb", size = 47952, upload-time = "2025-06-09T23:00:43.481Z" }, + { url = "https://files.pythonhosted.org/packages/01/7a/0046ef1bd6699b40acd2067ed6d6670b4db2f425c56980fa21c982c2a9db/frozenlist-1.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3dabd5a8f84573c8d10d8859a50ea2dec01eea372031929871368c09fa103478", size = 46688, upload-time = "2025-06-09T23:00:44.793Z" }, + { url = "https://files.pythonhosted.org/packages/d6/a2/a910bafe29c86997363fb4c02069df4ff0b5bc39d33c5198b4e9dd42d8f8/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa57daa5917f1738064f302bf2626281a1cb01920c32f711fbc7bc36111058a8", size = 243084, upload-time = "2025-06-09T23:00:46.125Z" }, + { url = "https://files.pythonhosted.org/packages/64/3e/5036af9d5031374c64c387469bfcc3af537fc0f5b1187d83a1cf6fab1639/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c193dda2b6d49f4c4398962810fa7d7c78f032bf45572b3e04dd5249dff27e08", size = 233524, upload-time = "2025-06-09T23:00:47.73Z" }, + { url = "https://files.pythonhosted.org/packages/06/39/6a17b7c107a2887e781a48ecf20ad20f1c39d94b2a548c83615b5b879f28/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfe2b675cf0aaa6d61bf8fbffd3c274b3c9b7b1623beb3809df8a81399a4a9c4", size = 248493, upload-time = "2025-06-09T23:00:49.742Z" }, + { url = "https://files.pythonhosted.org/packages/be/00/711d1337c7327d88c44d91dd0f556a1c47fb99afc060ae0ef66b4d24793d/frozenlist-1.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8fc5d5cda37f62b262405cf9652cf0856839c4be8ee41be0afe8858f17f4c94b", size = 244116, upload-time = "2025-06-09T23:00:51.352Z" }, + { url = "https://files.pythonhosted.org/packages/24/fe/74e6ec0639c115df13d5850e75722750adabdc7de24e37e05a40527ca539/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0d5ce521d1dd7d620198829b87ea002956e4319002ef0bc8d3e6d045cb4646e", size = 224557, upload-time = "2025-06-09T23:00:52.855Z" }, + { url = "https://files.pythonhosted.org/packages/8d/db/48421f62a6f77c553575201e89048e97198046b793f4a089c79a6e3268bd/frozenlist-1.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:488d0a7d6a0008ca0db273c542098a0fa9e7dfaa7e57f70acef43f32b3f69dca", size = 241820, upload-time = "2025-06-09T23:00:54.43Z" }, + { url = "https://files.pythonhosted.org/packages/1d/fa/cb4a76bea23047c8462976ea7b7a2bf53997a0ca171302deae9d6dd12096/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:15a7eaba63983d22c54d255b854e8108e7e5f3e89f647fc854bd77a237e767df", size = 236542, upload-time = "2025-06-09T23:00:56.409Z" }, + { url = "https://files.pythonhosted.org/packages/5d/32/476a4b5cfaa0ec94d3f808f193301debff2ea42288a099afe60757ef6282/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1eaa7e9c6d15df825bf255649e05bd8a74b04a4d2baa1ae46d9c2d00b2ca2cb5", size = 249350, upload-time = "2025-06-09T23:00:58.468Z" }, + { url = "https://files.pythonhosted.org/packages/8d/ba/9a28042f84a6bf8ea5dbc81cfff8eaef18d78b2a1ad9d51c7bc5b029ad16/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e4389e06714cfa9d47ab87f784a7c5be91d3934cd6e9a7b85beef808297cc025", size = 225093, upload-time = "2025-06-09T23:01:00.015Z" }, + { url = "https://files.pythonhosted.org/packages/bc/29/3a32959e68f9cf000b04e79ba574527c17e8842e38c91d68214a37455786/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:73bd45e1488c40b63fe5a7df892baf9e2a4d4bb6409a2b3b78ac1c6236178e01", size = 245482, upload-time = "2025-06-09T23:01:01.474Z" }, + { url = "https://files.pythonhosted.org/packages/80/e8/edf2f9e00da553f07f5fa165325cfc302dead715cab6ac8336a5f3d0adc2/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:99886d98e1643269760e5fe0df31e5ae7050788dd288947f7f007209b8c33f08", size = 249590, upload-time = "2025-06-09T23:01:02.961Z" }, + { url = "https://files.pythonhosted.org/packages/1c/80/9a0eb48b944050f94cc51ee1c413eb14a39543cc4f760ed12657a5a3c45a/frozenlist-1.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:290a172aae5a4c278c6da8a96222e6337744cd9c77313efe33d5670b9f65fc43", size = 237785, upload-time = "2025-06-09T23:01:05.095Z" }, + { url = "https://files.pythonhosted.org/packages/f3/74/87601e0fb0369b7a2baf404ea921769c53b7ae00dee7dcfe5162c8c6dbf0/frozenlist-1.7.0-cp312-cp312-win32.whl", hash = "sha256:426c7bc70e07cfebc178bc4c2bf2d861d720c4fff172181eeb4a4c41d4ca2ad3", size = 39487, upload-time = "2025-06-09T23:01:06.54Z" }, + { url = "https://files.pythonhosted.org/packages/0b/15/c026e9a9fc17585a9d461f65d8593d281fedf55fbf7eb53f16c6df2392f9/frozenlist-1.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:563b72efe5da92e02eb68c59cb37205457c977aa7a449ed1b37e6939e5c47c6a", size = 43874, upload-time = "2025-06-09T23:01:07.752Z" }, + { url = "https://files.pythonhosted.org/packages/24/90/6b2cebdabdbd50367273c20ff6b57a3dfa89bd0762de02c3a1eb42cb6462/frozenlist-1.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee80eeda5e2a4e660651370ebffd1286542b67e268aa1ac8d6dbe973120ef7ee", size = 79791, upload-time = "2025-06-09T23:01:09.368Z" }, + { url = "https://files.pythonhosted.org/packages/83/2e/5b70b6a3325363293fe5fc3ae74cdcbc3e996c2a11dde2fd9f1fb0776d19/frozenlist-1.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d1a81c85417b914139e3a9b995d4a1c84559afc839a93cf2cb7f15e6e5f6ed2d", size = 47165, upload-time = "2025-06-09T23:01:10.653Z" }, + { url = "https://files.pythonhosted.org/packages/f4/25/a0895c99270ca6966110f4ad98e87e5662eab416a17e7fd53c364bf8b954/frozenlist-1.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cbb65198a9132ebc334f237d7b0df163e4de83fb4f2bdfe46c1e654bdb0c5d43", size = 45881, upload-time = "2025-06-09T23:01:12.296Z" }, + { url = "https://files.pythonhosted.org/packages/19/7c/71bb0bbe0832793c601fff68cd0cf6143753d0c667f9aec93d3c323f4b55/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dab46c723eeb2c255a64f9dc05b8dd601fde66d6b19cdb82b2e09cc6ff8d8b5d", size = 232409, upload-time = "2025-06-09T23:01:13.641Z" }, + { url = "https://files.pythonhosted.org/packages/c0/45/ed2798718910fe6eb3ba574082aaceff4528e6323f9a8570be0f7028d8e9/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6aeac207a759d0dedd2e40745575ae32ab30926ff4fa49b1635def65806fddee", size = 225132, upload-time = "2025-06-09T23:01:15.264Z" }, + { url = "https://files.pythonhosted.org/packages/ba/e2/8417ae0f8eacb1d071d4950f32f229aa6bf68ab69aab797b72a07ea68d4f/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bd8c4e58ad14b4fa7802b8be49d47993182fdd4023393899632c88fd8cd994eb", size = 237638, upload-time = "2025-06-09T23:01:16.752Z" }, + { url = "https://files.pythonhosted.org/packages/f8/b7/2ace5450ce85f2af05a871b8c8719b341294775a0a6c5585d5e6170f2ce7/frozenlist-1.7.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04fb24d104f425da3540ed83cbfc31388a586a7696142004c577fa61c6298c3f", size = 233539, upload-time = "2025-06-09T23:01:18.202Z" }, + { url = "https://files.pythonhosted.org/packages/46/b9/6989292c5539553dba63f3c83dc4598186ab2888f67c0dc1d917e6887db6/frozenlist-1.7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6a5c505156368e4ea6b53b5ac23c92d7edc864537ff911d2fb24c140bb175e60", size = 215646, upload-time = "2025-06-09T23:01:19.649Z" }, + { url = "https://files.pythonhosted.org/packages/72/31/bc8c5c99c7818293458fe745dab4fd5730ff49697ccc82b554eb69f16a24/frozenlist-1.7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8bd7eb96a675f18aa5c553eb7ddc24a43c8c18f22e1f9925528128c052cdbe00", size = 232233, upload-time = "2025-06-09T23:01:21.175Z" }, + { url = "https://files.pythonhosted.org/packages/59/52/460db4d7ba0811b9ccb85af996019f5d70831f2f5f255f7cc61f86199795/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:05579bf020096fe05a764f1f84cd104a12f78eaab68842d036772dc6d4870b4b", size = 227996, upload-time = "2025-06-09T23:01:23.098Z" }, + { url = "https://files.pythonhosted.org/packages/ba/c9/f4b39e904c03927b7ecf891804fd3b4df3db29b9e487c6418e37988d6e9d/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:376b6222d114e97eeec13d46c486facd41d4f43bab626b7c3f6a8b4e81a5192c", size = 242280, upload-time = "2025-06-09T23:01:24.808Z" }, + { url = "https://files.pythonhosted.org/packages/b8/33/3f8d6ced42f162d743e3517781566b8481322be321b486d9d262adf70bfb/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0aa7e176ebe115379b5b1c95b4096fb1c17cce0847402e227e712c27bdb5a949", size = 217717, upload-time = "2025-06-09T23:01:26.28Z" }, + { url = "https://files.pythonhosted.org/packages/3e/e8/ad683e75da6ccef50d0ab0c2b2324b32f84fc88ceee778ed79b8e2d2fe2e/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3fbba20e662b9c2130dc771e332a99eff5da078b2b2648153a40669a6d0e36ca", size = 236644, upload-time = "2025-06-09T23:01:27.887Z" }, + { url = "https://files.pythonhosted.org/packages/b2/14/8d19ccdd3799310722195a72ac94ddc677541fb4bef4091d8e7775752360/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:f3f4410a0a601d349dd406b5713fec59b4cee7e71678d5b17edda7f4655a940b", size = 238879, upload-time = "2025-06-09T23:01:29.524Z" }, + { url = "https://files.pythonhosted.org/packages/ce/13/c12bf657494c2fd1079a48b2db49fa4196325909249a52d8f09bc9123fd7/frozenlist-1.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2cdfaaec6a2f9327bf43c933c0319a7c429058e8537c508964a133dffee412e", size = 232502, upload-time = "2025-06-09T23:01:31.287Z" }, + { url = "https://files.pythonhosted.org/packages/d7/8b/e7f9dfde869825489382bc0d512c15e96d3964180c9499efcec72e85db7e/frozenlist-1.7.0-cp313-cp313-win32.whl", hash = "sha256:5fc4df05a6591c7768459caba1b342d9ec23fa16195e744939ba5914596ae3e1", size = 39169, upload-time = "2025-06-09T23:01:35.503Z" }, + { url = "https://files.pythonhosted.org/packages/35/89/a487a98d94205d85745080a37860ff5744b9820a2c9acbcdd9440bfddf98/frozenlist-1.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:52109052b9791a3e6b5d1b65f4b909703984b770694d3eb64fad124c835d7cba", size = 43219, upload-time = "2025-06-09T23:01:36.784Z" }, + { url = "https://files.pythonhosted.org/packages/56/d5/5c4cf2319a49eddd9dd7145e66c4866bdc6f3dbc67ca3d59685149c11e0d/frozenlist-1.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a6f86e4193bb0e235ef6ce3dde5cbabed887e0b11f516ce8a0f4d3b33078ec2d", size = 84345, upload-time = "2025-06-09T23:01:38.295Z" }, + { url = "https://files.pythonhosted.org/packages/a4/7d/ec2c1e1dc16b85bc9d526009961953df9cec8481b6886debb36ec9107799/frozenlist-1.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:82d664628865abeb32d90ae497fb93df398a69bb3434463d172b80fc25b0dd7d", size = 48880, upload-time = "2025-06-09T23:01:39.887Z" }, + { url = "https://files.pythonhosted.org/packages/69/86/f9596807b03de126e11e7d42ac91e3d0b19a6599c714a1989a4e85eeefc4/frozenlist-1.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:912a7e8375a1c9a68325a902f3953191b7b292aa3c3fb0d71a216221deca460b", size = 48498, upload-time = "2025-06-09T23:01:41.318Z" }, + { url = "https://files.pythonhosted.org/packages/5e/cb/df6de220f5036001005f2d726b789b2c0b65f2363b104bbc16f5be8084f8/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9537c2777167488d539bc5de2ad262efc44388230e5118868e172dd4a552b146", size = 292296, upload-time = "2025-06-09T23:01:42.685Z" }, + { url = "https://files.pythonhosted.org/packages/83/1f/de84c642f17c8f851a2905cee2dae401e5e0daca9b5ef121e120e19aa825/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:f34560fb1b4c3e30ba35fa9a13894ba39e5acfc5f60f57d8accde65f46cc5e74", size = 273103, upload-time = "2025-06-09T23:01:44.166Z" }, + { url = "https://files.pythonhosted.org/packages/88/3c/c840bfa474ba3fa13c772b93070893c6e9d5c0350885760376cbe3b6c1b3/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:acd03d224b0175f5a850edc104ac19040d35419eddad04e7cf2d5986d98427f1", size = 292869, upload-time = "2025-06-09T23:01:45.681Z" }, + { url = "https://files.pythonhosted.org/packages/a6/1c/3efa6e7d5a39a1d5ef0abeb51c48fb657765794a46cf124e5aca2c7a592c/frozenlist-1.7.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f2038310bc582f3d6a09b3816ab01737d60bf7b1ec70f5356b09e84fb7408ab1", size = 291467, upload-time = "2025-06-09T23:01:47.234Z" }, + { url = "https://files.pythonhosted.org/packages/4f/00/d5c5e09d4922c395e2f2f6b79b9a20dab4b67daaf78ab92e7729341f61f6/frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c05e4c8e5f36e5e088caa1bf78a687528f83c043706640a92cb76cd6999384", size = 266028, upload-time = "2025-06-09T23:01:48.819Z" }, + { url = "https://files.pythonhosted.org/packages/4e/27/72765be905619dfde25a7f33813ac0341eb6b076abede17a2e3fbfade0cb/frozenlist-1.7.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:765bb588c86e47d0b68f23c1bee323d4b703218037765dcf3f25c838c6fecceb", size = 284294, upload-time = "2025-06-09T23:01:50.394Z" }, + { url = "https://files.pythonhosted.org/packages/88/67/c94103a23001b17808eb7dd1200c156bb69fb68e63fcf0693dde4cd6228c/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:32dc2e08c67d86d0969714dd484fd60ff08ff81d1a1e40a77dd34a387e6ebc0c", size = 281898, upload-time = "2025-06-09T23:01:52.234Z" }, + { url = "https://files.pythonhosted.org/packages/42/34/a3e2c00c00f9e2a9db5653bca3fec306349e71aff14ae45ecc6d0951dd24/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:c0303e597eb5a5321b4de9c68e9845ac8f290d2ab3f3e2c864437d3c5a30cd65", size = 290465, upload-time = "2025-06-09T23:01:53.788Z" }, + { url = "https://files.pythonhosted.org/packages/bb/73/f89b7fbce8b0b0c095d82b008afd0590f71ccb3dee6eee41791cf8cd25fd/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a47f2abb4e29b3a8d0b530f7c3598badc6b134562b1a5caee867f7c62fee51e3", size = 266385, upload-time = "2025-06-09T23:01:55.769Z" }, + { url = "https://files.pythonhosted.org/packages/cd/45/e365fdb554159462ca12df54bc59bfa7a9a273ecc21e99e72e597564d1ae/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:3d688126c242a6fabbd92e02633414d40f50bb6002fa4cf995a1d18051525657", size = 288771, upload-time = "2025-06-09T23:01:57.4Z" }, + { url = "https://files.pythonhosted.org/packages/00/11/47b6117002a0e904f004d70ec5194fe9144f117c33c851e3d51c765962d0/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:4e7e9652b3d367c7bd449a727dc79d5043f48b88d0cbfd4f9f1060cf2b414104", size = 288206, upload-time = "2025-06-09T23:01:58.936Z" }, + { url = "https://files.pythonhosted.org/packages/40/37/5f9f3c3fd7f7746082ec67bcdc204db72dad081f4f83a503d33220a92973/frozenlist-1.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1a85e345b4c43db8b842cab1feb41be5cc0b10a1830e6295b69d7310f99becaf", size = 282620, upload-time = "2025-06-09T23:02:00.493Z" }, + { url = "https://files.pythonhosted.org/packages/0b/31/8fbc5af2d183bff20f21aa743b4088eac4445d2bb1cdece449ae80e4e2d1/frozenlist-1.7.0-cp313-cp313t-win32.whl", hash = "sha256:3a14027124ddb70dfcee5148979998066897e79f89f64b13328595c4bdf77c81", size = 43059, upload-time = "2025-06-09T23:02:02.072Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ed/41956f52105b8dbc26e457c5705340c67c8cc2b79f394b79bffc09d0e938/frozenlist-1.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3bf8010d71d4507775f658e9823210b7427be36625b387221642725b515dcf3e", size = 47516, upload-time = "2025-06-09T23:02:03.779Z" }, + { url = "https://files.pythonhosted.org/packages/dd/b1/ee59496f51cd244039330015d60f13ce5a54a0f2bd8d79e4a4a375ab7469/frozenlist-1.7.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cea3dbd15aea1341ea2de490574a4a37ca080b2ae24e4b4f4b51b9057b4c3630", size = 82434, upload-time = "2025-06-09T23:02:05.195Z" }, + { url = "https://files.pythonhosted.org/packages/75/e1/d518391ce36a6279b3fa5bc14327dde80bcb646bb50d059c6ca0756b8d05/frozenlist-1.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7d536ee086b23fecc36c2073c371572374ff50ef4db515e4e503925361c24f71", size = 48232, upload-time = "2025-06-09T23:02:07.728Z" }, + { url = "https://files.pythonhosted.org/packages/b7/8d/a0d04f28b6e821a9685c22e67b5fb798a5a7b68752f104bfbc2dccf080c4/frozenlist-1.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dfcebf56f703cb2e346315431699f00db126d158455e513bd14089d992101e44", size = 47186, upload-time = "2025-06-09T23:02:09.243Z" }, + { url = "https://files.pythonhosted.org/packages/93/3a/a5334c0535c8b7c78eeabda1579179e44fe3d644e07118e59a2276dedaf1/frozenlist-1.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:974c5336e61d6e7eb1ea5b929cb645e882aadab0095c5a6974a111e6479f8878", size = 226617, upload-time = "2025-06-09T23:02:10.949Z" }, + { url = "https://files.pythonhosted.org/packages/0a/67/8258d971f519dc3f278c55069a775096cda6610a267b53f6248152b72b2f/frozenlist-1.7.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c70db4a0ab5ab20878432c40563573229a7ed9241506181bba12f6b7d0dc41cb", size = 224179, upload-time = "2025-06-09T23:02:12.603Z" }, + { url = "https://files.pythonhosted.org/packages/fc/89/8225905bf889b97c6d935dd3aeb45668461e59d415cb019619383a8a7c3b/frozenlist-1.7.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1137b78384eebaf70560a36b7b229f752fb64d463d38d1304939984d5cb887b6", size = 235783, upload-time = "2025-06-09T23:02:14.678Z" }, + { url = "https://files.pythonhosted.org/packages/54/6e/ef52375aa93d4bc510d061df06205fa6dcfd94cd631dd22956b09128f0d4/frozenlist-1.7.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e793a9f01b3e8b5c0bc646fb59140ce0efcc580d22a3468d70766091beb81b35", size = 229210, upload-time = "2025-06-09T23:02:16.313Z" }, + { url = "https://files.pythonhosted.org/packages/ee/55/62c87d1a6547bfbcd645df10432c129100c5bd0fd92a384de6e3378b07c1/frozenlist-1.7.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74739ba8e4e38221d2c5c03d90a7e542cb8ad681915f4ca8f68d04f810ee0a87", size = 215994, upload-time = "2025-06-09T23:02:17.9Z" }, + { url = "https://files.pythonhosted.org/packages/45/d2/263fea1f658b8ad648c7d94d18a87bca7e8c67bd6a1bbf5445b1bd5b158c/frozenlist-1.7.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e63344c4e929b1a01e29bc184bbb5fd82954869033765bfe8d65d09e336a677", size = 225122, upload-time = "2025-06-09T23:02:19.479Z" }, + { url = "https://files.pythonhosted.org/packages/7b/22/7145e35d12fb368d92124f679bea87309495e2e9ddf14c6533990cb69218/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2ea2a7369eb76de2217a842f22087913cdf75f63cf1307b9024ab82dfb525938", size = 224019, upload-time = "2025-06-09T23:02:20.969Z" }, + { url = "https://files.pythonhosted.org/packages/44/1e/7dae8c54301beb87bcafc6144b9a103bfd2c8f38078c7902984c9a0c4e5b/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:836b42f472a0e006e02499cef9352ce8097f33df43baaba3e0a28a964c26c7d2", size = 239925, upload-time = "2025-06-09T23:02:22.466Z" }, + { url = "https://files.pythonhosted.org/packages/4b/1e/99c93e54aa382e949a98976a73b9b20c3aae6d9d893f31bbe4991f64e3a8/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e22b9a99741294b2571667c07d9f8cceec07cb92aae5ccda39ea1b6052ed4319", size = 220881, upload-time = "2025-06-09T23:02:24.521Z" }, + { url = "https://files.pythonhosted.org/packages/5e/9c/ca5105fa7fb5abdfa8837581be790447ae051da75d32f25c8f81082ffc45/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:9a19e85cc503d958abe5218953df722748d87172f71b73cf3c9257a91b999890", size = 234046, upload-time = "2025-06-09T23:02:26.206Z" }, + { url = "https://files.pythonhosted.org/packages/8d/4d/e99014756093b4ddbb67fb8f0df11fe7a415760d69ace98e2ac6d5d43402/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:f22dac33bb3ee8fe3e013aa7b91dc12f60d61d05b7fe32191ffa84c3aafe77bd", size = 235756, upload-time = "2025-06-09T23:02:27.79Z" }, + { url = "https://files.pythonhosted.org/packages/8b/72/a19a40bcdaa28a51add2aaa3a1a294ec357f36f27bd836a012e070c5e8a5/frozenlist-1.7.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9ccec739a99e4ccf664ea0775149f2749b8a6418eb5b8384b4dc0a7d15d304cb", size = 222894, upload-time = "2025-06-09T23:02:29.848Z" }, + { url = "https://files.pythonhosted.org/packages/08/49/0042469993e023a758af81db68c76907cd29e847d772334d4d201cbe9a42/frozenlist-1.7.0-cp39-cp39-win32.whl", hash = "sha256:b3950f11058310008a87757f3eee16a8e1ca97979833239439586857bc25482e", size = 39848, upload-time = "2025-06-09T23:02:31.413Z" }, + { url = "https://files.pythonhosted.org/packages/5a/45/827d86ee475c877f5f766fbc23fb6acb6fada9e52f1c9720e2ba3eae32da/frozenlist-1.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:43a82fce6769c70f2f5a06248b614a7d268080a9d20f7457ef10ecee5af82b63", size = 44102, upload-time = "2025-06-09T23:02:32.808Z" }, + { url = "https://files.pythonhosted.org/packages/ee/45/b82e3c16be2182bff01179db177fe144d58b5dc787a7d4492c6ed8b9317f/frozenlist-1.7.0-py3-none-any.whl", hash = "sha256:9a5af342e34f7e97caf8c995864c7a396418ae2859cc6fdf1b1073020d516a7e", size = 13106, upload-time = "2025-06-09T23:02:34.204Z" }, +] + +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, +] + +[[package]] +name = "multidict" +version = "6.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/2c/5dad12e82fbdf7470f29bff2171484bf07cb3b16ada60a6589af8f376440/multidict-6.6.3.tar.gz", hash = "sha256:798a9eb12dab0a6c2e29c1de6f3468af5cb2da6053a20dfa3344907eed0937cc", size = 101006, upload-time = "2025-06-30T15:53:46.929Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/67/414933982bce2efce7cbcb3169eaaf901e0f25baec69432b4874dfb1f297/multidict-6.6.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a2be5b7b35271f7fff1397204ba6708365e3d773579fe2a30625e16c4b4ce817", size = 77017, upload-time = "2025-06-30T15:50:58.931Z" }, + { url = "https://files.pythonhosted.org/packages/8a/fe/d8a3ee1fad37dc2ef4f75488b0d9d4f25bf204aad8306cbab63d97bff64a/multidict-6.6.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:12f4581d2930840295c461764b9a65732ec01250b46c6b2c510d7ee68872b140", size = 44897, upload-time = "2025-06-30T15:51:00.999Z" }, + { url = "https://files.pythonhosted.org/packages/1f/e0/265d89af8c98240265d82b8cbcf35897f83b76cd59ee3ab3879050fd8c45/multidict-6.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dd7793bab517e706c9ed9d7310b06c8672fd0aeee5781bfad612f56b8e0f7d14", size = 44574, upload-time = "2025-06-30T15:51:02.449Z" }, + { url = "https://files.pythonhosted.org/packages/e6/05/6b759379f7e8e04ccc97cfb2a5dcc5cdbd44a97f072b2272dc51281e6a40/multidict-6.6.3-cp310-cp310-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:72d8815f2cd3cf3df0f83cac3f3ef801d908b2d90409ae28102e0553af85545a", size = 225729, upload-time = "2025-06-30T15:51:03.794Z" }, + { url = "https://files.pythonhosted.org/packages/4e/f5/8d5a15488edd9a91fa4aad97228d785df208ed6298580883aa3d9def1959/multidict-6.6.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:531e331a2ee53543ab32b16334e2deb26f4e6b9b28e41f8e0c87e99a6c8e2d69", size = 242515, upload-time = "2025-06-30T15:51:05.002Z" }, + { url = "https://files.pythonhosted.org/packages/6e/b5/a8f317d47d0ac5bb746d6d8325885c8967c2a8ce0bb57be5399e3642cccb/multidict-6.6.3-cp310-cp310-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:42ca5aa9329a63be8dc49040f63817d1ac980e02eeddba763a9ae5b4027b9c9c", size = 222224, upload-time = "2025-06-30T15:51:06.148Z" }, + { url = "https://files.pythonhosted.org/packages/76/88/18b2a0d5e80515fa22716556061189c2853ecf2aa2133081ebbe85ebea38/multidict-6.6.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:208b9b9757060b9faa6f11ab4bc52846e4f3c2fb8b14d5680c8aac80af3dc751", size = 253124, upload-time = "2025-06-30T15:51:07.375Z" }, + { url = "https://files.pythonhosted.org/packages/62/bf/ebfcfd6b55a1b05ef16d0775ae34c0fe15e8dab570d69ca9941073b969e7/multidict-6.6.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:acf6b97bd0884891af6a8b43d0f586ab2fcf8e717cbd47ab4bdddc09e20652d8", size = 251529, upload-time = "2025-06-30T15:51:08.691Z" }, + { url = "https://files.pythonhosted.org/packages/44/11/780615a98fd3775fc309d0234d563941af69ade2df0bb82c91dda6ddaea1/multidict-6.6.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:68e9e12ed00e2089725669bdc88602b0b6f8d23c0c95e52b95f0bc69f7fe9b55", size = 241627, upload-time = "2025-06-30T15:51:10.605Z" }, + { url = "https://files.pythonhosted.org/packages/28/3d/35f33045e21034b388686213752cabc3a1b9d03e20969e6fa8f1b1d82db1/multidict-6.6.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:05db2f66c9addb10cfa226e1acb363450fab2ff8a6df73c622fefe2f5af6d4e7", size = 239351, upload-time = "2025-06-30T15:51:12.18Z" }, + { url = "https://files.pythonhosted.org/packages/6e/cc/ff84c03b95b430015d2166d9aae775a3985d757b94f6635010d0038d9241/multidict-6.6.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:0db58da8eafb514db832a1b44f8fa7906fdd102f7d982025f816a93ba45e3dcb", size = 233429, upload-time = "2025-06-30T15:51:13.533Z" }, + { url = "https://files.pythonhosted.org/packages/2e/f0/8cd49a0b37bdea673a4b793c2093f2f4ba8e7c9d6d7c9bd672fd6d38cd11/multidict-6.6.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:14117a41c8fdb3ee19c743b1c027da0736fdb79584d61a766da53d399b71176c", size = 243094, upload-time = "2025-06-30T15:51:14.815Z" }, + { url = "https://files.pythonhosted.org/packages/96/19/5d9a0cfdafe65d82b616a45ae950975820289069f885328e8185e64283c2/multidict-6.6.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:877443eaaabcd0b74ff32ebeed6f6176c71850feb7d6a1d2db65945256ea535c", size = 248957, upload-time = "2025-06-30T15:51:16.076Z" }, + { url = "https://files.pythonhosted.org/packages/e6/dc/c90066151da87d1e489f147b9b4327927241e65f1876702fafec6729c014/multidict-6.6.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:70b72e749a4f6e7ed8fb334fa8d8496384840319512746a5f42fa0aec79f4d61", size = 243590, upload-time = "2025-06-30T15:51:17.413Z" }, + { url = "https://files.pythonhosted.org/packages/ec/39/458afb0cccbb0ee9164365273be3e039efddcfcb94ef35924b7dbdb05db0/multidict-6.6.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:43571f785b86afd02b3855c5ac8e86ec921b760298d6f82ff2a61daf5a35330b", size = 237487, upload-time = "2025-06-30T15:51:19.039Z" }, + { url = "https://files.pythonhosted.org/packages/35/38/0016adac3990426610a081787011177e661875546b434f50a26319dc8372/multidict-6.6.3-cp310-cp310-win32.whl", hash = "sha256:20c5a0c3c13a15fd5ea86c42311859f970070e4e24de5a550e99d7c271d76318", size = 41390, upload-time = "2025-06-30T15:51:20.362Z" }, + { url = "https://files.pythonhosted.org/packages/f3/d2/17897a8f3f2c5363d969b4c635aa40375fe1f09168dc09a7826780bfb2a4/multidict-6.6.3-cp310-cp310-win_amd64.whl", hash = "sha256:ab0a34a007704c625e25a9116c6770b4d3617a071c8a7c30cd338dfbadfe6485", size = 45954, upload-time = "2025-06-30T15:51:21.383Z" }, + { url = "https://files.pythonhosted.org/packages/2d/5f/d4a717c1e457fe44072e33fa400d2b93eb0f2819c4d669381f925b7cba1f/multidict-6.6.3-cp310-cp310-win_arm64.whl", hash = "sha256:769841d70ca8bdd140a715746199fc6473414bd02efd678d75681d2d6a8986c5", size = 42981, upload-time = "2025-06-30T15:51:22.809Z" }, + { url = "https://files.pythonhosted.org/packages/08/f0/1a39863ced51f639c81a5463fbfa9eb4df59c20d1a8769ab9ef4ca57ae04/multidict-6.6.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:18f4eba0cbac3546b8ae31e0bbc55b02c801ae3cbaf80c247fcdd89b456ff58c", size = 76445, upload-time = "2025-06-30T15:51:24.01Z" }, + { url = "https://files.pythonhosted.org/packages/c9/0e/a7cfa451c7b0365cd844e90b41e21fab32edaa1e42fc0c9f68461ce44ed7/multidict-6.6.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef43b5dd842382329e4797c46f10748d8c2b6e0614f46b4afe4aee9ac33159df", size = 44610, upload-time = "2025-06-30T15:51:25.158Z" }, + { url = "https://files.pythonhosted.org/packages/c6/bb/a14a4efc5ee748cc1904b0748be278c31b9295ce5f4d2ef66526f410b94d/multidict-6.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bf9bd1fd5eec01494e0f2e8e446a74a85d5e49afb63d75a9934e4a5423dba21d", size = 44267, upload-time = "2025-06-30T15:51:26.326Z" }, + { url = "https://files.pythonhosted.org/packages/c2/f8/410677d563c2d55e063ef74fe578f9d53fe6b0a51649597a5861f83ffa15/multidict-6.6.3-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:5bd8d6f793a787153956cd35e24f60485bf0651c238e207b9a54f7458b16d539", size = 230004, upload-time = "2025-06-30T15:51:27.491Z" }, + { url = "https://files.pythonhosted.org/packages/fd/df/2b787f80059314a98e1ec6a4cc7576244986df3e56b3c755e6fc7c99e038/multidict-6.6.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1bf99b4daf908c73856bd87ee0a2499c3c9a3d19bb04b9c6025e66af3fd07462", size = 247196, upload-time = "2025-06-30T15:51:28.762Z" }, + { url = "https://files.pythonhosted.org/packages/05/f2/f9117089151b9a8ab39f9019620d10d9718eec2ac89e7ca9d30f3ec78e96/multidict-6.6.3-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0b9e59946b49dafaf990fd9c17ceafa62976e8471a14952163d10a7a630413a9", size = 225337, upload-time = "2025-06-30T15:51:30.025Z" }, + { url = "https://files.pythonhosted.org/packages/93/2d/7115300ec5b699faa152c56799b089a53ed69e399c3c2d528251f0aeda1a/multidict-6.6.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e2db616467070d0533832d204c54eea6836a5e628f2cb1e6dfd8cd6ba7277cb7", size = 257079, upload-time = "2025-06-30T15:51:31.716Z" }, + { url = "https://files.pythonhosted.org/packages/15/ea/ff4bab367623e39c20d3b07637225c7688d79e4f3cc1f3b9f89867677f9a/multidict-6.6.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7394888236621f61dcdd25189b2768ae5cc280f041029a5bcf1122ac63df79f9", size = 255461, upload-time = "2025-06-30T15:51:33.029Z" }, + { url = "https://files.pythonhosted.org/packages/74/07/2c9246cda322dfe08be85f1b8739646f2c4c5113a1422d7a407763422ec4/multidict-6.6.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f114d8478733ca7388e7c7e0ab34b72547476b97009d643644ac33d4d3fe1821", size = 246611, upload-time = "2025-06-30T15:51:34.47Z" }, + { url = "https://files.pythonhosted.org/packages/a8/62/279c13d584207d5697a752a66ffc9bb19355a95f7659140cb1b3cf82180e/multidict-6.6.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cdf22e4db76d323bcdc733514bf732e9fb349707c98d341d40ebcc6e9318ef3d", size = 243102, upload-time = "2025-06-30T15:51:36.525Z" }, + { url = "https://files.pythonhosted.org/packages/69/cc/e06636f48c6d51e724a8bc8d9e1db5f136fe1df066d7cafe37ef4000f86a/multidict-6.6.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:e995a34c3d44ab511bfc11aa26869b9d66c2d8c799fa0e74b28a473a692532d6", size = 238693, upload-time = "2025-06-30T15:51:38.278Z" }, + { url = "https://files.pythonhosted.org/packages/89/a4/66c9d8fb9acf3b226cdd468ed009537ac65b520aebdc1703dd6908b19d33/multidict-6.6.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:766a4a5996f54361d8d5a9050140aa5362fe48ce51c755a50c0bc3706460c430", size = 246582, upload-time = "2025-06-30T15:51:39.709Z" }, + { url = "https://files.pythonhosted.org/packages/cf/01/c69e0317be556e46257826d5449feb4e6aa0d18573e567a48a2c14156f1f/multidict-6.6.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:3893a0d7d28a7fe6ca7a1f760593bc13038d1d35daf52199d431b61d2660602b", size = 253355, upload-time = "2025-06-30T15:51:41.013Z" }, + { url = "https://files.pythonhosted.org/packages/c0/da/9cc1da0299762d20e626fe0042e71b5694f9f72d7d3f9678397cbaa71b2b/multidict-6.6.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:934796c81ea996e61914ba58064920d6cad5d99140ac3167901eb932150e2e56", size = 247774, upload-time = "2025-06-30T15:51:42.291Z" }, + { url = "https://files.pythonhosted.org/packages/e6/91/b22756afec99cc31105ddd4a52f95ab32b1a4a58f4d417979c570c4a922e/multidict-6.6.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9ed948328aec2072bc00f05d961ceadfd3e9bfc2966c1319aeaf7b7c21219183", size = 242275, upload-time = "2025-06-30T15:51:43.642Z" }, + { url = "https://files.pythonhosted.org/packages/be/f1/adcc185b878036a20399d5be5228f3cbe7f823d78985d101d425af35c800/multidict-6.6.3-cp311-cp311-win32.whl", hash = "sha256:9f5b28c074c76afc3e4c610c488e3493976fe0e596dd3db6c8ddfbb0134dcac5", size = 41290, upload-time = "2025-06-30T15:51:45.264Z" }, + { url = "https://files.pythonhosted.org/packages/e0/d4/27652c1c6526ea6b4f5ddd397e93f4232ff5de42bea71d339bc6a6cc497f/multidict-6.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc7f6fbc61b1c16050a389c630da0b32fc6d4a3d191394ab78972bf5edc568c2", size = 45942, upload-time = "2025-06-30T15:51:46.377Z" }, + { url = "https://files.pythonhosted.org/packages/16/18/23f4932019804e56d3c2413e237f866444b774b0263bcb81df2fdecaf593/multidict-6.6.3-cp311-cp311-win_arm64.whl", hash = "sha256:d4e47d8faffaae822fb5cba20937c048d4f734f43572e7079298a6c39fb172cb", size = 42880, upload-time = "2025-06-30T15:51:47.561Z" }, + { url = "https://files.pythonhosted.org/packages/0e/a0/6b57988ea102da0623ea814160ed78d45a2645e4bbb499c2896d12833a70/multidict-6.6.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:056bebbeda16b2e38642d75e9e5310c484b7c24e3841dc0fb943206a72ec89d6", size = 76514, upload-time = "2025-06-30T15:51:48.728Z" }, + { url = "https://files.pythonhosted.org/packages/07/7a/d1e92665b0850c6c0508f101f9cf0410c1afa24973e1115fe9c6a185ebf7/multidict-6.6.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e5f481cccb3c5c5e5de5d00b5141dc589c1047e60d07e85bbd7dea3d4580d63f", size = 45394, upload-time = "2025-06-30T15:51:49.986Z" }, + { url = "https://files.pythonhosted.org/packages/52/6f/dd104490e01be6ef8bf9573705d8572f8c2d2c561f06e3826b081d9e6591/multidict-6.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:10bea2ee839a759ee368b5a6e47787f399b41e70cf0c20d90dfaf4158dfb4e55", size = 43590, upload-time = "2025-06-30T15:51:51.331Z" }, + { url = "https://files.pythonhosted.org/packages/44/fe/06e0e01b1b0611e6581b7fd5a85b43dacc08b6cea3034f902f383b0873e5/multidict-6.6.3-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:2334cfb0fa9549d6ce2c21af2bfbcd3ac4ec3646b1b1581c88e3e2b1779ec92b", size = 237292, upload-time = "2025-06-30T15:51:52.584Z" }, + { url = "https://files.pythonhosted.org/packages/ce/71/4f0e558fb77696b89c233c1ee2d92f3e1d5459070a0e89153c9e9e804186/multidict-6.6.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8fee016722550a2276ca2cb5bb624480e0ed2bd49125b2b73b7010b9090e888", size = 258385, upload-time = "2025-06-30T15:51:53.913Z" }, + { url = "https://files.pythonhosted.org/packages/e3/25/cca0e68228addad24903801ed1ab42e21307a1b4b6dd2cf63da5d3ae082a/multidict-6.6.3-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5511cb35f5c50a2db21047c875eb42f308c5583edf96bd8ebf7d770a9d68f6d", size = 242328, upload-time = "2025-06-30T15:51:55.672Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a3/46f2d420d86bbcb8fe660b26a10a219871a0fbf4d43cb846a4031533f3e0/multidict-6.6.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:712b348f7f449948e0a6c4564a21c7db965af900973a67db432d724619b3c680", size = 268057, upload-time = "2025-06-30T15:51:57.037Z" }, + { url = "https://files.pythonhosted.org/packages/9e/73/1c743542fe00794a2ec7466abd3f312ccb8fad8dff9f36d42e18fb1ec33e/multidict-6.6.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e4e15d2138ee2694e038e33b7c3da70e6b0ad8868b9f8094a72e1414aeda9c1a", size = 269341, upload-time = "2025-06-30T15:51:59.111Z" }, + { url = "https://files.pythonhosted.org/packages/a4/11/6ec9dcbe2264b92778eeb85407d1df18812248bf3506a5a1754bc035db0c/multidict-6.6.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8df25594989aebff8a130f7899fa03cbfcc5d2b5f4a461cf2518236fe6f15961", size = 256081, upload-time = "2025-06-30T15:52:00.533Z" }, + { url = "https://files.pythonhosted.org/packages/9b/2b/631b1e2afeb5f1696846d747d36cda075bfdc0bc7245d6ba5c319278d6c4/multidict-6.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:159ca68bfd284a8860f8d8112cf0521113bffd9c17568579e4d13d1f1dc76b65", size = 253581, upload-time = "2025-06-30T15:52:02.43Z" }, + { url = "https://files.pythonhosted.org/packages/bf/0e/7e3b93f79efeb6111d3bf9a1a69e555ba1d07ad1c11bceb56b7310d0d7ee/multidict-6.6.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e098c17856a8c9ade81b4810888c5ad1914099657226283cab3062c0540b0643", size = 250750, upload-time = "2025-06-30T15:52:04.26Z" }, + { url = "https://files.pythonhosted.org/packages/ad/9e/086846c1d6601948e7de556ee464a2d4c85e33883e749f46b9547d7b0704/multidict-6.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:67c92ed673049dec52d7ed39f8cf9ebbadf5032c774058b4406d18c8f8fe7063", size = 251548, upload-time = "2025-06-30T15:52:06.002Z" }, + { url = "https://files.pythonhosted.org/packages/8c/7b/86ec260118e522f1a31550e87b23542294880c97cfbf6fb18cc67b044c66/multidict-6.6.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:bd0578596e3a835ef451784053cfd327d607fc39ea1a14812139339a18a0dbc3", size = 262718, upload-time = "2025-06-30T15:52:07.707Z" }, + { url = "https://files.pythonhosted.org/packages/8c/bd/22ce8f47abb0be04692c9fc4638508b8340987b18691aa7775d927b73f72/multidict-6.6.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:346055630a2df2115cd23ae271910b4cae40f4e336773550dca4889b12916e75", size = 259603, upload-time = "2025-06-30T15:52:09.58Z" }, + { url = "https://files.pythonhosted.org/packages/07/9c/91b7ac1691be95cd1f4a26e36a74b97cda6aa9820632d31aab4410f46ebd/multidict-6.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:555ff55a359302b79de97e0468e9ee80637b0de1fce77721639f7cd9440b3a10", size = 251351, upload-time = "2025-06-30T15:52:10.947Z" }, + { url = "https://files.pythonhosted.org/packages/6f/5c/4d7adc739884f7a9fbe00d1eac8c034023ef8bad71f2ebe12823ca2e3649/multidict-6.6.3-cp312-cp312-win32.whl", hash = "sha256:73ab034fb8d58ff85c2bcbadc470efc3fafeea8affcf8722855fb94557f14cc5", size = 41860, upload-time = "2025-06-30T15:52:12.334Z" }, + { url = "https://files.pythonhosted.org/packages/6a/a3/0fbc7afdf7cb1aa12a086b02959307848eb6bcc8f66fcb66c0cb57e2a2c1/multidict-6.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:04cbcce84f63b9af41bad04a54d4cc4e60e90c35b9e6ccb130be2d75b71f8c17", size = 45982, upload-time = "2025-06-30T15:52:13.6Z" }, + { url = "https://files.pythonhosted.org/packages/b8/95/8c825bd70ff9b02462dc18d1295dd08d3e9e4eb66856d292ffa62cfe1920/multidict-6.6.3-cp312-cp312-win_arm64.whl", hash = "sha256:0f1130b896ecb52d2a1e615260f3ea2af55fa7dc3d7c3003ba0c3121a759b18b", size = 43210, upload-time = "2025-06-30T15:52:14.893Z" }, + { url = "https://files.pythonhosted.org/packages/52/1d/0bebcbbb4f000751fbd09957257903d6e002943fc668d841a4cf2fb7f872/multidict-6.6.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:540d3c06d48507357a7d57721e5094b4f7093399a0106c211f33540fdc374d55", size = 75843, upload-time = "2025-06-30T15:52:16.155Z" }, + { url = "https://files.pythonhosted.org/packages/07/8f/cbe241b0434cfe257f65c2b1bcf9e8d5fb52bc708c5061fb29b0fed22bdf/multidict-6.6.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9c19cea2a690f04247d43f366d03e4eb110a0dc4cd1bbeee4d445435428ed35b", size = 45053, upload-time = "2025-06-30T15:52:17.429Z" }, + { url = "https://files.pythonhosted.org/packages/32/d2/0b3b23f9dbad5b270b22a3ac3ea73ed0a50ef2d9a390447061178ed6bdb8/multidict-6.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7af039820cfd00effec86bda5d8debef711a3e86a1d3772e85bea0f243a4bd65", size = 43273, upload-time = "2025-06-30T15:52:19.346Z" }, + { url = "https://files.pythonhosted.org/packages/fd/fe/6eb68927e823999e3683bc49678eb20374ba9615097d085298fd5b386564/multidict-6.6.3-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:500b84f51654fdc3944e936f2922114349bf8fdcac77c3092b03449f0e5bc2b3", size = 237124, upload-time = "2025-06-30T15:52:20.773Z" }, + { url = "https://files.pythonhosted.org/packages/e7/ab/320d8507e7726c460cb77117848b3834ea0d59e769f36fdae495f7669929/multidict-6.6.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3fc723ab8a5c5ed6c50418e9bfcd8e6dceba6c271cee6728a10a4ed8561520c", size = 256892, upload-time = "2025-06-30T15:52:22.242Z" }, + { url = "https://files.pythonhosted.org/packages/76/60/38ee422db515ac69834e60142a1a69111ac96026e76e8e9aa347fd2e4591/multidict-6.6.3-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:94c47ea3ade005b5976789baaed66d4de4480d0a0bf31cef6edaa41c1e7b56a6", size = 240547, upload-time = "2025-06-30T15:52:23.736Z" }, + { url = "https://files.pythonhosted.org/packages/27/fb/905224fde2dff042b030c27ad95a7ae744325cf54b890b443d30a789b80e/multidict-6.6.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dbc7cf464cc6d67e83e136c9f55726da3a30176f020a36ead246eceed87f1cd8", size = 266223, upload-time = "2025-06-30T15:52:25.185Z" }, + { url = "https://files.pythonhosted.org/packages/76/35/dc38ab361051beae08d1a53965e3e1a418752fc5be4d3fb983c5582d8784/multidict-6.6.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:900eb9f9da25ada070f8ee4a23f884e0ee66fe4e1a38c3af644256a508ad81ca", size = 267262, upload-time = "2025-06-30T15:52:26.969Z" }, + { url = "https://files.pythonhosted.org/packages/1f/a3/0a485b7f36e422421b17e2bbb5a81c1af10eac1d4476f2ff92927c730479/multidict-6.6.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c6df517cf177da5d47ab15407143a89cd1a23f8b335f3a28d57e8b0a3dbb884", size = 254345, upload-time = "2025-06-30T15:52:28.467Z" }, + { url = "https://files.pythonhosted.org/packages/b4/59/bcdd52c1dab7c0e0d75ff19cac751fbd5f850d1fc39172ce809a74aa9ea4/multidict-6.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4ef421045f13879e21c994b36e728d8e7d126c91a64b9185810ab51d474f27e7", size = 252248, upload-time = "2025-06-30T15:52:29.938Z" }, + { url = "https://files.pythonhosted.org/packages/bb/a4/2d96aaa6eae8067ce108d4acee6f45ced5728beda55c0f02ae1072c730d1/multidict-6.6.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6c1e61bb4f80895c081790b6b09fa49e13566df8fbff817da3f85b3a8192e36b", size = 250115, upload-time = "2025-06-30T15:52:31.416Z" }, + { url = "https://files.pythonhosted.org/packages/25/d2/ed9f847fa5c7d0677d4f02ea2c163d5e48573de3f57bacf5670e43a5ffaa/multidict-6.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:e5e8523bb12d7623cd8300dbd91b9e439a46a028cd078ca695eb66ba31adee3c", size = 249649, upload-time = "2025-06-30T15:52:32.996Z" }, + { url = "https://files.pythonhosted.org/packages/1f/af/9155850372563fc550803d3f25373308aa70f59b52cff25854086ecb4a79/multidict-6.6.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ef58340cc896219e4e653dade08fea5c55c6df41bcc68122e3be3e9d873d9a7b", size = 261203, upload-time = "2025-06-30T15:52:34.521Z" }, + { url = "https://files.pythonhosted.org/packages/36/2f/c6a728f699896252cf309769089568a33c6439626648843f78743660709d/multidict-6.6.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fc9dc435ec8699e7b602b94fe0cd4703e69273a01cbc34409af29e7820f777f1", size = 258051, upload-time = "2025-06-30T15:52:35.999Z" }, + { url = "https://files.pythonhosted.org/packages/d0/60/689880776d6b18fa2b70f6cc74ff87dd6c6b9b47bd9cf74c16fecfaa6ad9/multidict-6.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9e864486ef4ab07db5e9cb997bad2b681514158d6954dd1958dfb163b83d53e6", size = 249601, upload-time = "2025-06-30T15:52:37.473Z" }, + { url = "https://files.pythonhosted.org/packages/75/5e/325b11f2222a549019cf2ef879c1f81f94a0d40ace3ef55cf529915ba6cc/multidict-6.6.3-cp313-cp313-win32.whl", hash = "sha256:5633a82fba8e841bc5c5c06b16e21529573cd654f67fd833650a215520a6210e", size = 41683, upload-time = "2025-06-30T15:52:38.927Z" }, + { url = "https://files.pythonhosted.org/packages/b1/ad/cf46e73f5d6e3c775cabd2a05976547f3f18b39bee06260369a42501f053/multidict-6.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:e93089c1570a4ad54c3714a12c2cef549dc9d58e97bcded193d928649cab78e9", size = 45811, upload-time = "2025-06-30T15:52:40.207Z" }, + { url = "https://files.pythonhosted.org/packages/c5/c9/2e3fe950db28fb7c62e1a5f46e1e38759b072e2089209bc033c2798bb5ec/multidict-6.6.3-cp313-cp313-win_arm64.whl", hash = "sha256:c60b401f192e79caec61f166da9c924e9f8bc65548d4246842df91651e83d600", size = 43056, upload-time = "2025-06-30T15:52:41.575Z" }, + { url = "https://files.pythonhosted.org/packages/3a/58/aaf8114cf34966e084a8cc9517771288adb53465188843d5a19862cb6dc3/multidict-6.6.3-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:02fd8f32d403a6ff13864b0851f1f523d4c988051eea0471d4f1fd8010f11134", size = 82811, upload-time = "2025-06-30T15:52:43.281Z" }, + { url = "https://files.pythonhosted.org/packages/71/af/5402e7b58a1f5b987a07ad98f2501fdba2a4f4b4c30cf114e3ce8db64c87/multidict-6.6.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:f3aa090106b1543f3f87b2041eef3c156c8da2aed90c63a2fbed62d875c49c37", size = 48304, upload-time = "2025-06-30T15:52:45.026Z" }, + { url = "https://files.pythonhosted.org/packages/39/65/ab3c8cafe21adb45b24a50266fd747147dec7847425bc2a0f6934b3ae9ce/multidict-6.6.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e924fb978615a5e33ff644cc42e6aa241effcf4f3322c09d4f8cebde95aff5f8", size = 46775, upload-time = "2025-06-30T15:52:46.459Z" }, + { url = "https://files.pythonhosted.org/packages/49/ba/9fcc1b332f67cc0c0c8079e263bfab6660f87fe4e28a35921771ff3eea0d/multidict-6.6.3-cp313-cp313t-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:b9fe5a0e57c6dbd0e2ce81ca66272282c32cd11d31658ee9553849d91289e1c1", size = 229773, upload-time = "2025-06-30T15:52:47.88Z" }, + { url = "https://files.pythonhosted.org/packages/a4/14/0145a251f555f7c754ce2dcbcd012939bbd1f34f066fa5d28a50e722a054/multidict-6.6.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b24576f208793ebae00280c59927c3b7c2a3b1655e443a25f753c4611bc1c373", size = 250083, upload-time = "2025-06-30T15:52:49.366Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d4/d5c0bd2bbb173b586c249a151a26d2fb3ec7d53c96e42091c9fef4e1f10c/multidict-6.6.3-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:135631cb6c58eac37d7ac0df380294fecdc026b28837fa07c02e459c7fb9c54e", size = 228980, upload-time = "2025-06-30T15:52:50.903Z" }, + { url = "https://files.pythonhosted.org/packages/21/32/c9a2d8444a50ec48c4733ccc67254100c10e1c8ae8e40c7a2d2183b59b97/multidict-6.6.3-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:274d416b0df887aef98f19f21578653982cfb8a05b4e187d4a17103322eeaf8f", size = 257776, upload-time = "2025-06-30T15:52:52.764Z" }, + { url = "https://files.pythonhosted.org/packages/68/d0/14fa1699f4ef629eae08ad6201c6b476098f5efb051b296f4c26be7a9fdf/multidict-6.6.3-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e252017a817fad7ce05cafbe5711ed40faeb580e63b16755a3a24e66fa1d87c0", size = 256882, upload-time = "2025-06-30T15:52:54.596Z" }, + { url = "https://files.pythonhosted.org/packages/da/88/84a27570fbe303c65607d517a5f147cd2fc046c2d1da02b84b17b9bdc2aa/multidict-6.6.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e4cc8d848cd4fe1cdee28c13ea79ab0ed37fc2e89dd77bac86a2e7959a8c3bc", size = 247816, upload-time = "2025-06-30T15:52:56.175Z" }, + { url = "https://files.pythonhosted.org/packages/1c/60/dca352a0c999ce96a5d8b8ee0b2b9f729dcad2e0b0c195f8286269a2074c/multidict-6.6.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9e236a7094b9c4c1b7585f6b9cca34b9d833cf079f7e4c49e6a4a6ec9bfdc68f", size = 245341, upload-time = "2025-06-30T15:52:57.752Z" }, + { url = "https://files.pythonhosted.org/packages/50/ef/433fa3ed06028f03946f3993223dada70fb700f763f70c00079533c34578/multidict-6.6.3-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:e0cb0ab69915c55627c933f0b555a943d98ba71b4d1c57bc0d0a66e2567c7471", size = 235854, upload-time = "2025-06-30T15:52:59.74Z" }, + { url = "https://files.pythonhosted.org/packages/1b/1f/487612ab56fbe35715320905215a57fede20de7db40a261759690dc80471/multidict-6.6.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:81ef2f64593aba09c5212a3d0f8c906a0d38d710a011f2f42759704d4557d3f2", size = 243432, upload-time = "2025-06-30T15:53:01.602Z" }, + { url = "https://files.pythonhosted.org/packages/da/6f/ce8b79de16cd885c6f9052c96a3671373d00c59b3ee635ea93e6e81b8ccf/multidict-6.6.3-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:b9cbc60010de3562545fa198bfc6d3825df430ea96d2cc509c39bd71e2e7d648", size = 252731, upload-time = "2025-06-30T15:53:03.517Z" }, + { url = "https://files.pythonhosted.org/packages/bb/fe/a2514a6aba78e5abefa1624ca85ae18f542d95ac5cde2e3815a9fbf369aa/multidict-6.6.3-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:70d974eaaa37211390cd02ef93b7e938de564bbffa866f0b08d07e5e65da783d", size = 247086, upload-time = "2025-06-30T15:53:05.48Z" }, + { url = "https://files.pythonhosted.org/packages/8c/22/b788718d63bb3cce752d107a57c85fcd1a212c6c778628567c9713f9345a/multidict-6.6.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3713303e4a6663c6d01d648a68f2848701001f3390a030edaaf3fc949c90bf7c", size = 243338, upload-time = "2025-06-30T15:53:07.522Z" }, + { url = "https://files.pythonhosted.org/packages/22/d6/fdb3d0670819f2228f3f7d9af613d5e652c15d170c83e5f1c94fbc55a25b/multidict-6.6.3-cp313-cp313t-win32.whl", hash = "sha256:639ecc9fe7cd73f2495f62c213e964843826f44505a3e5d82805aa85cac6f89e", size = 47812, upload-time = "2025-06-30T15:53:09.263Z" }, + { url = "https://files.pythonhosted.org/packages/b6/d6/a9d2c808f2c489ad199723197419207ecbfbc1776f6e155e1ecea9c883aa/multidict-6.6.3-cp313-cp313t-win_amd64.whl", hash = "sha256:9f97e181f344a0ef3881b573d31de8542cc0dbc559ec68c8f8b5ce2c2e91646d", size = 53011, upload-time = "2025-06-30T15:53:11.038Z" }, + { url = "https://files.pythonhosted.org/packages/f2/40/b68001cba8188dd267590a111f9661b6256debc327137667e832bf5d66e8/multidict-6.6.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ce8b7693da41a3c4fde5871c738a81490cea5496c671d74374c8ab889e1834fb", size = 45254, upload-time = "2025-06-30T15:53:12.421Z" }, + { url = "https://files.pythonhosted.org/packages/d2/64/ba29bd6dfc895e592b2f20f92378e692ac306cf25dd0be2f8e0a0f898edb/multidict-6.6.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c8161b5a7778d3137ea2ee7ae8a08cce0010de3b00ac671c5ebddeaa17cefd22", size = 76959, upload-time = "2025-06-30T15:53:13.827Z" }, + { url = "https://files.pythonhosted.org/packages/ca/cd/872ae4c134257dacebff59834983c1615d6ec863b6e3d360f3203aad8400/multidict-6.6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1328201ee930f069961ae707d59c6627ac92e351ed5b92397cf534d1336ce557", size = 44864, upload-time = "2025-06-30T15:53:15.658Z" }, + { url = "https://files.pythonhosted.org/packages/15/35/d417d8f62f2886784b76df60522d608aba39dfc83dd53b230ca71f2d4c53/multidict-6.6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b1db4d2093d6b235de76932febf9d50766cf49a5692277b2c28a501c9637f616", size = 44540, upload-time = "2025-06-30T15:53:17.208Z" }, + { url = "https://files.pythonhosted.org/packages/85/59/25cddf781f12cddb2386baa29744a3fdd160eb705539b48065f0cffd86d5/multidict-6.6.3-cp39-cp39-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:53becb01dd8ebd19d1724bebe369cfa87e4e7f29abbbe5c14c98ce4c383e16cd", size = 224075, upload-time = "2025-06-30T15:53:18.705Z" }, + { url = "https://files.pythonhosted.org/packages/c4/21/4055b6a527954c572498a8068c26bd3b75f2b959080e17e12104b592273c/multidict-6.6.3-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41bb9d1d4c303886e2d85bade86e59885112a7f4277af5ad47ab919a2251f306", size = 240535, upload-time = "2025-06-30T15:53:20.359Z" }, + { url = "https://files.pythonhosted.org/packages/58/98/17f1f80bdba0b2fef49cf4ba59cebf8a81797f745f547abb5c9a4039df62/multidict-6.6.3-cp39-cp39-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:775b464d31dac90f23192af9c291dc9f423101857e33e9ebf0020a10bfcf4144", size = 219361, upload-time = "2025-06-30T15:53:22.371Z" }, + { url = "https://files.pythonhosted.org/packages/f8/0e/a5e595fdd0820069f0c29911d5dc9dc3a75ec755ae733ce59a4e6962ae42/multidict-6.6.3-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d04d01f0a913202205a598246cf77826fe3baa5a63e9f6ccf1ab0601cf56eca0", size = 251207, upload-time = "2025-06-30T15:53:24.307Z" }, + { url = "https://files.pythonhosted.org/packages/66/9e/0f51e4cffea2daf24c137feabc9ec848ce50f8379c9badcbac00b41ab55e/multidict-6.6.3-cp39-cp39-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d25594d3b38a2e6cabfdcafef339f754ca6e81fbbdb6650ad773ea9775af35ab", size = 249749, upload-time = "2025-06-30T15:53:26.056Z" }, + { url = "https://files.pythonhosted.org/packages/49/a0/a7cfc13c9a71ceb8c1c55457820733af9ce01e121139271f7b13e30c29d2/multidict-6.6.3-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:35712f1748d409e0707b165bf49f9f17f9e28ae85470c41615778f8d4f7d9609", size = 239202, upload-time = "2025-06-30T15:53:28.096Z" }, + { url = "https://files.pythonhosted.org/packages/c7/50/7ae0d1149ac71cab6e20bb7faf2a1868435974994595dadfdb7377f7140f/multidict-6.6.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1c8082e5814b662de8589d6a06c17e77940d5539080cbab9fe6794b5241b76d9", size = 237269, upload-time = "2025-06-30T15:53:30.124Z" }, + { url = "https://files.pythonhosted.org/packages/b4/ac/2d0bf836c9c63a57360d57b773359043b371115e1c78ff648993bf19abd0/multidict-6.6.3-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:61af8a4b771f1d4d000b3168c12c3120ccf7284502a94aa58c68a81f5afac090", size = 232961, upload-time = "2025-06-30T15:53:31.766Z" }, + { url = "https://files.pythonhosted.org/packages/85/e1/68a65f069df298615591e70e48bfd379c27d4ecb252117c18bf52eebc237/multidict-6.6.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:448e4a9afccbf297577f2eaa586f07067441e7b63c8362a3540ba5a38dc0f14a", size = 240863, upload-time = "2025-06-30T15:53:33.488Z" }, + { url = "https://files.pythonhosted.org/packages/ae/ab/702f1baca649f88ea1dc6259fc2aa4509f4ad160ba48c8e61fbdb4a5a365/multidict-6.6.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:233ad16999afc2bbd3e534ad8dbe685ef8ee49a37dbc2cdc9514e57b6d589ced", size = 246800, upload-time = "2025-06-30T15:53:35.21Z" }, + { url = "https://files.pythonhosted.org/packages/5e/0b/726e690bfbf887985a8710ef2f25f1d6dd184a35bd3b36429814f810a2fc/multidict-6.6.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:bb933c891cd4da6bdcc9733d048e994e22e1883287ff7540c2a0f3b117605092", size = 242034, upload-time = "2025-06-30T15:53:36.913Z" }, + { url = "https://files.pythonhosted.org/packages/73/bb/839486b27bcbcc2e0d875fb9d4012b4b6aa99639137343106aa7210e047a/multidict-6.6.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:37b09ca60998e87734699e88c2363abfd457ed18cfbf88e4009a4e83788e63ed", size = 235377, upload-time = "2025-06-30T15:53:38.618Z" }, + { url = "https://files.pythonhosted.org/packages/e3/46/574d75ab7b9ae8690fe27e89f5fcd0121633112b438edfb9ed2be8be096b/multidict-6.6.3-cp39-cp39-win32.whl", hash = "sha256:f54cb79d26d0cd420637d184af38f0668558f3c4bbe22ab7ad830e67249f2e0b", size = 41420, upload-time = "2025-06-30T15:53:40.309Z" }, + { url = "https://files.pythonhosted.org/packages/78/c3/8b3bc755508b777868349f4bfa844d3d31832f075ee800a3d6f1807338c5/multidict-6.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:295adc9c0551e5d5214b45cf29ca23dbc28c2d197a9c30d51aed9e037cb7c578", size = 46124, upload-time = "2025-06-30T15:53:41.984Z" }, + { url = "https://files.pythonhosted.org/packages/b2/30/5a66e7e4550e80975faee5b5dd9e9bd09194d2fd8f62363119b9e46e204b/multidict-6.6.3-cp39-cp39-win_arm64.whl", hash = "sha256:15332783596f227db50fb261c2c251a58ac3873c457f3a550a95d5c0aa3c770d", size = 42973, upload-time = "2025-06-30T15:53:43.505Z" }, + { url = "https://files.pythonhosted.org/packages/d8/30/9aec301e9772b098c1f5c0ca0279237c9766d94b97802e9888010c64b0ed/multidict-6.6.3-py3-none-any.whl", hash = "sha256:8db10f29c7541fc5da4defd8cd697e1ca429db743fa716325f236079b96f775a", size = 12313, upload-time = "2025-06-30T15:53:45.437Z" }, +] + +[[package]] +name = "propcache" +version = "0.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/16/43264e4a779dd8588c21a70f0709665ee8f611211bdd2c87d952cfa7c776/propcache-0.3.2.tar.gz", hash = "sha256:20d7d62e4e7ef05f221e0db2856b979540686342e7dd9973b815599c7057e168", size = 44139, upload-time = "2025-06-09T22:56:06.081Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/14/510deed325e262afeb8b360043c5d7c960da7d3ecd6d6f9496c9c56dc7f4/propcache-0.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:22d9962a358aedbb7a2e36187ff273adeaab9743373a272976d2e348d08c7770", size = 73178, upload-time = "2025-06-09T22:53:40.126Z" }, + { url = "https://files.pythonhosted.org/packages/cd/4e/ad52a7925ff01c1325653a730c7ec3175a23f948f08626a534133427dcff/propcache-0.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0d0fda578d1dc3f77b6b5a5dce3b9ad69a8250a891760a548df850a5e8da87f3", size = 43133, upload-time = "2025-06-09T22:53:41.965Z" }, + { url = "https://files.pythonhosted.org/packages/63/7c/e9399ba5da7780871db4eac178e9c2e204c23dd3e7d32df202092a1ed400/propcache-0.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3def3da3ac3ce41562d85db655d18ebac740cb3fa4367f11a52b3da9d03a5cc3", size = 43039, upload-time = "2025-06-09T22:53:43.268Z" }, + { url = "https://files.pythonhosted.org/packages/22/e1/58da211eb8fdc6fc854002387d38f415a6ca5f5c67c1315b204a5d3e9d7a/propcache-0.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bec58347a5a6cebf239daba9bda37dffec5b8d2ce004d9fe4edef3d2815137e", size = 201903, upload-time = "2025-06-09T22:53:44.872Z" }, + { url = "https://files.pythonhosted.org/packages/c4/0a/550ea0f52aac455cb90111c8bab995208443e46d925e51e2f6ebdf869525/propcache-0.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55ffda449a507e9fbd4aca1a7d9aa6753b07d6166140e5a18d2ac9bc49eac220", size = 213362, upload-time = "2025-06-09T22:53:46.707Z" }, + { url = "https://files.pythonhosted.org/packages/5a/af/9893b7d878deda9bb69fcf54600b247fba7317761b7db11fede6e0f28bd0/propcache-0.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:64a67fb39229a8a8491dd42f864e5e263155e729c2e7ff723d6e25f596b1e8cb", size = 210525, upload-time = "2025-06-09T22:53:48.547Z" }, + { url = "https://files.pythonhosted.org/packages/7c/bb/38fd08b278ca85cde36d848091ad2b45954bc5f15cce494bb300b9285831/propcache-0.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9da1cf97b92b51253d5b68cf5a2b9e0dafca095e36b7f2da335e27dc6172a614", size = 198283, upload-time = "2025-06-09T22:53:50.067Z" }, + { url = "https://files.pythonhosted.org/packages/78/8c/9fe55bd01d362bafb413dfe508c48753111a1e269737fa143ba85693592c/propcache-0.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f559e127134b07425134b4065be45b166183fdcb433cb6c24c8e4149056ad50", size = 191872, upload-time = "2025-06-09T22:53:51.438Z" }, + { url = "https://files.pythonhosted.org/packages/54/14/4701c33852937a22584e08abb531d654c8bcf7948a8f87ad0a4822394147/propcache-0.3.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aff2e4e06435d61f11a428360a932138d0ec288b0a31dd9bd78d200bd4a2b339", size = 199452, upload-time = "2025-06-09T22:53:53.229Z" }, + { url = "https://files.pythonhosted.org/packages/16/44/447f2253d859602095356007657ee535e0093215ea0b3d1d6a41d16e5201/propcache-0.3.2-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4927842833830942a5d0a56e6f4839bc484785b8e1ce8d287359794818633ba0", size = 191567, upload-time = "2025-06-09T22:53:54.541Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b3/e4756258749bb2d3b46defcff606a2f47410bab82be5824a67e84015b267/propcache-0.3.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6107ddd08b02654a30fb8ad7a132021759d750a82578b94cd55ee2772b6ebea2", size = 193015, upload-time = "2025-06-09T22:53:56.44Z" }, + { url = "https://files.pythonhosted.org/packages/1e/df/e6d3c7574233164b6330b9fd697beeac402afd367280e6dc377bb99b43d9/propcache-0.3.2-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:70bd8b9cd6b519e12859c99f3fc9a93f375ebd22a50296c3a295028bea73b9e7", size = 204660, upload-time = "2025-06-09T22:53:57.839Z" }, + { url = "https://files.pythonhosted.org/packages/b2/53/e4d31dd5170b4a0e2e6b730f2385a96410633b4833dc25fe5dffd1f73294/propcache-0.3.2-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2183111651d710d3097338dd1893fcf09c9f54e27ff1a8795495a16a469cc90b", size = 206105, upload-time = "2025-06-09T22:53:59.638Z" }, + { url = "https://files.pythonhosted.org/packages/7f/fe/74d54cf9fbe2a20ff786e5f7afcfde446588f0cf15fb2daacfbc267b866c/propcache-0.3.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:fb075ad271405dcad8e2a7ffc9a750a3bf70e533bd86e89f0603e607b93aa64c", size = 196980, upload-time = "2025-06-09T22:54:01.071Z" }, + { url = "https://files.pythonhosted.org/packages/22/ec/c469c9d59dada8a7679625e0440b544fe72e99311a4679c279562051f6fc/propcache-0.3.2-cp310-cp310-win32.whl", hash = "sha256:404d70768080d3d3bdb41d0771037da19d8340d50b08e104ca0e7f9ce55fce70", size = 37679, upload-time = "2025-06-09T22:54:03.003Z" }, + { url = "https://files.pythonhosted.org/packages/38/35/07a471371ac89d418f8d0b699c75ea6dca2041fbda360823de21f6a9ce0a/propcache-0.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:7435d766f978b4ede777002e6b3b6641dd229cd1da8d3d3106a45770365f9ad9", size = 41459, upload-time = "2025-06-09T22:54:04.134Z" }, + { url = "https://files.pythonhosted.org/packages/80/8d/e8b436717ab9c2cfc23b116d2c297305aa4cd8339172a456d61ebf5669b8/propcache-0.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0b8d2f607bd8f80ddc04088bc2a037fdd17884a6fcadc47a96e334d72f3717be", size = 74207, upload-time = "2025-06-09T22:54:05.399Z" }, + { url = "https://files.pythonhosted.org/packages/d6/29/1e34000e9766d112171764b9fa3226fa0153ab565d0c242c70e9945318a7/propcache-0.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06766d8f34733416e2e34f46fea488ad5d60726bb9481d3cddf89a6fa2d9603f", size = 43648, upload-time = "2025-06-09T22:54:08.023Z" }, + { url = "https://files.pythonhosted.org/packages/46/92/1ad5af0df781e76988897da39b5f086c2bf0f028b7f9bd1f409bb05b6874/propcache-0.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a2dc1f4a1df4fecf4e6f68013575ff4af84ef6f478fe5344317a65d38a8e6dc9", size = 43496, upload-time = "2025-06-09T22:54:09.228Z" }, + { url = "https://files.pythonhosted.org/packages/b3/ce/e96392460f9fb68461fabab3e095cb00c8ddf901205be4eae5ce246e5b7e/propcache-0.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be29c4f4810c5789cf10ddf6af80b041c724e629fa51e308a7a0fb19ed1ef7bf", size = 217288, upload-time = "2025-06-09T22:54:10.466Z" }, + { url = "https://files.pythonhosted.org/packages/c5/2a/866726ea345299f7ceefc861a5e782b045545ae6940851930a6adaf1fca6/propcache-0.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59d61f6970ecbd8ff2e9360304d5c8876a6abd4530cb752c06586849ac8a9dc9", size = 227456, upload-time = "2025-06-09T22:54:11.828Z" }, + { url = "https://files.pythonhosted.org/packages/de/03/07d992ccb6d930398689187e1b3c718339a1c06b8b145a8d9650e4726166/propcache-0.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:62180e0b8dbb6b004baec00a7983e4cc52f5ada9cd11f48c3528d8cfa7b96a66", size = 225429, upload-time = "2025-06-09T22:54:13.823Z" }, + { url = "https://files.pythonhosted.org/packages/5d/e6/116ba39448753b1330f48ab8ba927dcd6cf0baea8a0ccbc512dfb49ba670/propcache-0.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c144ca294a204c470f18cf4c9d78887810d04a3e2fbb30eea903575a779159df", size = 213472, upload-time = "2025-06-09T22:54:15.232Z" }, + { url = "https://files.pythonhosted.org/packages/a6/85/f01f5d97e54e428885a5497ccf7f54404cbb4f906688a1690cd51bf597dc/propcache-0.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5c2a784234c28854878d68978265617aa6dc0780e53d44b4d67f3651a17a9a2", size = 204480, upload-time = "2025-06-09T22:54:17.104Z" }, + { url = "https://files.pythonhosted.org/packages/e3/79/7bf5ab9033b8b8194cc3f7cf1aaa0e9c3256320726f64a3e1f113a812dce/propcache-0.3.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5745bc7acdafa978ca1642891b82c19238eadc78ba2aaa293c6863b304e552d7", size = 214530, upload-time = "2025-06-09T22:54:18.512Z" }, + { url = "https://files.pythonhosted.org/packages/31/0b/bd3e0c00509b609317df4a18e6b05a450ef2d9a963e1d8bc9c9415d86f30/propcache-0.3.2-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:c0075bf773d66fa8c9d41f66cc132ecc75e5bb9dd7cce3cfd14adc5ca184cb95", size = 205230, upload-time = "2025-06-09T22:54:19.947Z" }, + { url = "https://files.pythonhosted.org/packages/7a/23/fae0ff9b54b0de4e819bbe559508da132d5683c32d84d0dc2ccce3563ed4/propcache-0.3.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5f57aa0847730daceff0497f417c9de353c575d8da3579162cc74ac294c5369e", size = 206754, upload-time = "2025-06-09T22:54:21.716Z" }, + { url = "https://files.pythonhosted.org/packages/b7/7f/ad6a3c22630aaa5f618b4dc3c3598974a72abb4c18e45a50b3cdd091eb2f/propcache-0.3.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:eef914c014bf72d18efb55619447e0aecd5fb7c2e3fa7441e2e5d6099bddff7e", size = 218430, upload-time = "2025-06-09T22:54:23.17Z" }, + { url = "https://files.pythonhosted.org/packages/5b/2c/ba4f1c0e8a4b4c75910742f0d333759d441f65a1c7f34683b4a74c0ee015/propcache-0.3.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2a4092e8549031e82facf3decdbc0883755d5bbcc62d3aea9d9e185549936dcf", size = 223884, upload-time = "2025-06-09T22:54:25.539Z" }, + { url = "https://files.pythonhosted.org/packages/88/e4/ebe30fc399e98572019eee82ad0caf512401661985cbd3da5e3140ffa1b0/propcache-0.3.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:85871b050f174bc0bfb437efbdb68aaf860611953ed12418e4361bc9c392749e", size = 211480, upload-time = "2025-06-09T22:54:26.892Z" }, + { url = "https://files.pythonhosted.org/packages/96/0a/7d5260b914e01d1d0906f7f38af101f8d8ed0dc47426219eeaf05e8ea7c2/propcache-0.3.2-cp311-cp311-win32.whl", hash = "sha256:36c8d9b673ec57900c3554264e630d45980fd302458e4ac801802a7fd2ef7897", size = 37757, upload-time = "2025-06-09T22:54:28.241Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2d/89fe4489a884bc0da0c3278c552bd4ffe06a1ace559db5ef02ef24ab446b/propcache-0.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53af8cb6a781b02d2ea079b5b853ba9430fcbe18a8e3ce647d5982a3ff69f39", size = 41500, upload-time = "2025-06-09T22:54:29.4Z" }, + { url = "https://files.pythonhosted.org/packages/a8/42/9ca01b0a6f48e81615dca4765a8f1dd2c057e0540f6116a27dc5ee01dfb6/propcache-0.3.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8de106b6c84506b31c27168582cd3cb3000a6412c16df14a8628e5871ff83c10", size = 73674, upload-time = "2025-06-09T22:54:30.551Z" }, + { url = "https://files.pythonhosted.org/packages/af/6e/21293133beb550f9c901bbece755d582bfaf2176bee4774000bd4dd41884/propcache-0.3.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:28710b0d3975117239c76600ea351934ac7b5ff56e60953474342608dbbb6154", size = 43570, upload-time = "2025-06-09T22:54:32.296Z" }, + { url = "https://files.pythonhosted.org/packages/0c/c8/0393a0a3a2b8760eb3bde3c147f62b20044f0ddac81e9d6ed7318ec0d852/propcache-0.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce26862344bdf836650ed2487c3d724b00fbfec4233a1013f597b78c1cb73615", size = 43094, upload-time = "2025-06-09T22:54:33.929Z" }, + { url = "https://files.pythonhosted.org/packages/37/2c/489afe311a690399d04a3e03b069225670c1d489eb7b044a566511c1c498/propcache-0.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bca54bd347a253af2cf4544bbec232ab982f4868de0dd684246b67a51bc6b1db", size = 226958, upload-time = "2025-06-09T22:54:35.186Z" }, + { url = "https://files.pythonhosted.org/packages/9d/ca/63b520d2f3d418c968bf596839ae26cf7f87bead026b6192d4da6a08c467/propcache-0.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:55780d5e9a2ddc59711d727226bb1ba83a22dd32f64ee15594b9392b1f544eb1", size = 234894, upload-time = "2025-06-09T22:54:36.708Z" }, + { url = "https://files.pythonhosted.org/packages/11/60/1d0ed6fff455a028d678df30cc28dcee7af77fa2b0e6962ce1df95c9a2a9/propcache-0.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:035e631be25d6975ed87ab23153db6a73426a48db688070d925aa27e996fe93c", size = 233672, upload-time = "2025-06-09T22:54:38.062Z" }, + { url = "https://files.pythonhosted.org/packages/37/7c/54fd5301ef38505ab235d98827207176a5c9b2aa61939b10a460ca53e123/propcache-0.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee6f22b6eaa39297c751d0e80c0d3a454f112f5c6481214fcf4c092074cecd67", size = 224395, upload-time = "2025-06-09T22:54:39.634Z" }, + { url = "https://files.pythonhosted.org/packages/ee/1a/89a40e0846f5de05fdc6779883bf46ba980e6df4d2ff8fb02643de126592/propcache-0.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7ca3aee1aa955438c4dba34fc20a9f390e4c79967257d830f137bd5a8a32ed3b", size = 212510, upload-time = "2025-06-09T22:54:41.565Z" }, + { url = "https://files.pythonhosted.org/packages/5e/33/ca98368586c9566a6b8d5ef66e30484f8da84c0aac3f2d9aec6d31a11bd5/propcache-0.3.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7a4f30862869fa2b68380d677cc1c5fcf1e0f2b9ea0cf665812895c75d0ca3b8", size = 222949, upload-time = "2025-06-09T22:54:43.038Z" }, + { url = "https://files.pythonhosted.org/packages/ba/11/ace870d0aafe443b33b2f0b7efdb872b7c3abd505bfb4890716ad7865e9d/propcache-0.3.2-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b77ec3c257d7816d9f3700013639db7491a434644c906a2578a11daf13176251", size = 217258, upload-time = "2025-06-09T22:54:44.376Z" }, + { url = "https://files.pythonhosted.org/packages/5b/d2/86fd6f7adffcfc74b42c10a6b7db721d1d9ca1055c45d39a1a8f2a740a21/propcache-0.3.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:cab90ac9d3f14b2d5050928483d3d3b8fb6b4018893fc75710e6aa361ecb2474", size = 213036, upload-time = "2025-06-09T22:54:46.243Z" }, + { url = "https://files.pythonhosted.org/packages/07/94/2d7d1e328f45ff34a0a284cf5a2847013701e24c2a53117e7c280a4316b3/propcache-0.3.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0b504d29f3c47cf6b9e936c1852246c83d450e8e063d50562115a6be6d3a2535", size = 227684, upload-time = "2025-06-09T22:54:47.63Z" }, + { url = "https://files.pythonhosted.org/packages/b7/05/37ae63a0087677e90b1d14710e532ff104d44bc1efa3b3970fff99b891dc/propcache-0.3.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:ce2ac2675a6aa41ddb2a0c9cbff53780a617ac3d43e620f8fd77ba1c84dcfc06", size = 234562, upload-time = "2025-06-09T22:54:48.982Z" }, + { url = "https://files.pythonhosted.org/packages/a4/7c/3f539fcae630408d0bd8bf3208b9a647ccad10976eda62402a80adf8fc34/propcache-0.3.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:62b4239611205294cc433845b914131b2a1f03500ff3c1ed093ed216b82621e1", size = 222142, upload-time = "2025-06-09T22:54:50.424Z" }, + { url = "https://files.pythonhosted.org/packages/7c/d2/34b9eac8c35f79f8a962546b3e97e9d4b990c420ee66ac8255d5d9611648/propcache-0.3.2-cp312-cp312-win32.whl", hash = "sha256:df4a81b9b53449ebc90cc4deefb052c1dd934ba85012aa912c7ea7b7e38b60c1", size = 37711, upload-time = "2025-06-09T22:54:52.072Z" }, + { url = "https://files.pythonhosted.org/packages/19/61/d582be5d226cf79071681d1b46b848d6cb03d7b70af7063e33a2787eaa03/propcache-0.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:7046e79b989d7fe457bb755844019e10f693752d169076138abf17f31380800c", size = 41479, upload-time = "2025-06-09T22:54:53.234Z" }, + { url = "https://files.pythonhosted.org/packages/dc/d1/8c747fafa558c603c4ca19d8e20b288aa0c7cda74e9402f50f31eb65267e/propcache-0.3.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ca592ed634a73ca002967458187109265e980422116c0a107cf93d81f95af945", size = 71286, upload-time = "2025-06-09T22:54:54.369Z" }, + { url = "https://files.pythonhosted.org/packages/61/99/d606cb7986b60d89c36de8a85d58764323b3a5ff07770a99d8e993b3fa73/propcache-0.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9ecb0aad4020e275652ba3975740f241bd12a61f1a784df044cf7477a02bc252", size = 42425, upload-time = "2025-06-09T22:54:55.642Z" }, + { url = "https://files.pythonhosted.org/packages/8c/96/ef98f91bbb42b79e9bb82bdd348b255eb9d65f14dbbe3b1594644c4073f7/propcache-0.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7f08f1cc28bd2eade7a8a3d2954ccc673bb02062e3e7da09bc75d843386b342f", size = 41846, upload-time = "2025-06-09T22:54:57.246Z" }, + { url = "https://files.pythonhosted.org/packages/5b/ad/3f0f9a705fb630d175146cd7b1d2bf5555c9beaed54e94132b21aac098a6/propcache-0.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1a342c834734edb4be5ecb1e9fb48cb64b1e2320fccbd8c54bf8da8f2a84c33", size = 208871, upload-time = "2025-06-09T22:54:58.975Z" }, + { url = "https://files.pythonhosted.org/packages/3a/38/2085cda93d2c8b6ec3e92af2c89489a36a5886b712a34ab25de9fbca7992/propcache-0.3.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a544caaae1ac73f1fecfae70ded3e93728831affebd017d53449e3ac052ac1e", size = 215720, upload-time = "2025-06-09T22:55:00.471Z" }, + { url = "https://files.pythonhosted.org/packages/61/c1/d72ea2dc83ac7f2c8e182786ab0fc2c7bd123a1ff9b7975bee671866fe5f/propcache-0.3.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:310d11aa44635298397db47a3ebce7db99a4cc4b9bbdfcf6c98a60c8d5261cf1", size = 215203, upload-time = "2025-06-09T22:55:01.834Z" }, + { url = "https://files.pythonhosted.org/packages/af/81/b324c44ae60c56ef12007105f1460d5c304b0626ab0cc6b07c8f2a9aa0b8/propcache-0.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1396592321ac83157ac03a2023aa6cc4a3cc3cfdecb71090054c09e5a7cce3", size = 206365, upload-time = "2025-06-09T22:55:03.199Z" }, + { url = "https://files.pythonhosted.org/packages/09/73/88549128bb89e66d2aff242488f62869014ae092db63ccea53c1cc75a81d/propcache-0.3.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cabf5b5902272565e78197edb682017d21cf3b550ba0460ee473753f28d23c1", size = 196016, upload-time = "2025-06-09T22:55:04.518Z" }, + { url = "https://files.pythonhosted.org/packages/b9/3f/3bdd14e737d145114a5eb83cb172903afba7242f67c5877f9909a20d948d/propcache-0.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0a2f2235ac46a7aa25bdeb03a9e7060f6ecbd213b1f9101c43b3090ffb971ef6", size = 205596, upload-time = "2025-06-09T22:55:05.942Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ca/2f4aa819c357d3107c3763d7ef42c03980f9ed5c48c82e01e25945d437c1/propcache-0.3.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:92b69e12e34869a6970fd2f3da91669899994b47c98f5d430b781c26f1d9f387", size = 200977, upload-time = "2025-06-09T22:55:07.792Z" }, + { url = "https://files.pythonhosted.org/packages/cd/4a/e65276c7477533c59085251ae88505caf6831c0e85ff8b2e31ebcbb949b1/propcache-0.3.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:54e02207c79968ebbdffc169591009f4474dde3b4679e16634d34c9363ff56b4", size = 197220, upload-time = "2025-06-09T22:55:09.173Z" }, + { url = "https://files.pythonhosted.org/packages/7c/54/fc7152e517cf5578278b242396ce4d4b36795423988ef39bb8cd5bf274c8/propcache-0.3.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4adfb44cb588001f68c5466579d3f1157ca07f7504fc91ec87862e2b8e556b88", size = 210642, upload-time = "2025-06-09T22:55:10.62Z" }, + { url = "https://files.pythonhosted.org/packages/b9/80/abeb4a896d2767bf5f1ea7b92eb7be6a5330645bd7fb844049c0e4045d9d/propcache-0.3.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fd3e6019dc1261cd0291ee8919dd91fbab7b169bb76aeef6c716833a3f65d206", size = 212789, upload-time = "2025-06-09T22:55:12.029Z" }, + { url = "https://files.pythonhosted.org/packages/b3/db/ea12a49aa7b2b6d68a5da8293dcf50068d48d088100ac016ad92a6a780e6/propcache-0.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4c181cad81158d71c41a2bce88edce078458e2dd5ffee7eddd6b05da85079f43", size = 205880, upload-time = "2025-06-09T22:55:13.45Z" }, + { url = "https://files.pythonhosted.org/packages/d1/e5/9076a0bbbfb65d1198007059c65639dfd56266cf8e477a9707e4b1999ff4/propcache-0.3.2-cp313-cp313-win32.whl", hash = "sha256:8a08154613f2249519e549de2330cf8e2071c2887309a7b07fb56098f5170a02", size = 37220, upload-time = "2025-06-09T22:55:15.284Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f5/b369e026b09a26cd77aa88d8fffd69141d2ae00a2abaaf5380d2603f4b7f/propcache-0.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:e41671f1594fc4ab0a6dec1351864713cb3a279910ae8b58f884a88a0a632c05", size = 40678, upload-time = "2025-06-09T22:55:16.445Z" }, + { url = "https://files.pythonhosted.org/packages/a4/3a/6ece377b55544941a08d03581c7bc400a3c8cd3c2865900a68d5de79e21f/propcache-0.3.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:9a3cf035bbaf035f109987d9d55dc90e4b0e36e04bbbb95af3055ef17194057b", size = 76560, upload-time = "2025-06-09T22:55:17.598Z" }, + { url = "https://files.pythonhosted.org/packages/0c/da/64a2bb16418740fa634b0e9c3d29edff1db07f56d3546ca2d86ddf0305e1/propcache-0.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:156c03d07dc1323d8dacaa221fbe028c5c70d16709cdd63502778e6c3ccca1b0", size = 44676, upload-time = "2025-06-09T22:55:18.922Z" }, + { url = "https://files.pythonhosted.org/packages/36/7b/f025e06ea51cb72c52fb87e9b395cced02786610b60a3ed51da8af017170/propcache-0.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:74413c0ba02ba86f55cf60d18daab219f7e531620c15f1e23d95563f505efe7e", size = 44701, upload-time = "2025-06-09T22:55:20.106Z" }, + { url = "https://files.pythonhosted.org/packages/a4/00/faa1b1b7c3b74fc277f8642f32a4c72ba1d7b2de36d7cdfb676db7f4303e/propcache-0.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f066b437bb3fa39c58ff97ab2ca351db465157d68ed0440abecb21715eb24b28", size = 276934, upload-time = "2025-06-09T22:55:21.5Z" }, + { url = "https://files.pythonhosted.org/packages/74/ab/935beb6f1756e0476a4d5938ff44bf0d13a055fed880caf93859b4f1baf4/propcache-0.3.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1304b085c83067914721e7e9d9917d41ad87696bf70f0bc7dee450e9c71ad0a", size = 278316, upload-time = "2025-06-09T22:55:22.918Z" }, + { url = "https://files.pythonhosted.org/packages/f8/9d/994a5c1ce4389610838d1caec74bdf0e98b306c70314d46dbe4fcf21a3e2/propcache-0.3.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab50cef01b372763a13333b4e54021bdcb291fc9a8e2ccb9c2df98be51bcde6c", size = 282619, upload-time = "2025-06-09T22:55:24.651Z" }, + { url = "https://files.pythonhosted.org/packages/2b/00/a10afce3d1ed0287cef2e09506d3be9822513f2c1e96457ee369adb9a6cd/propcache-0.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fad3b2a085ec259ad2c2842666b2a0a49dea8463579c606426128925af1ed725", size = 265896, upload-time = "2025-06-09T22:55:26.049Z" }, + { url = "https://files.pythonhosted.org/packages/2e/a8/2aa6716ffa566ca57c749edb909ad27884680887d68517e4be41b02299f3/propcache-0.3.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:261fa020c1c14deafd54c76b014956e2f86991af198c51139faf41c4d5e83892", size = 252111, upload-time = "2025-06-09T22:55:27.381Z" }, + { url = "https://files.pythonhosted.org/packages/36/4f/345ca9183b85ac29c8694b0941f7484bf419c7f0fea2d1e386b4f7893eed/propcache-0.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:46d7f8aa79c927e5f987ee3a80205c987717d3659f035c85cf0c3680526bdb44", size = 268334, upload-time = "2025-06-09T22:55:28.747Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ca/fcd54f78b59e3f97b3b9715501e3147f5340167733d27db423aa321e7148/propcache-0.3.2-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:6d8f3f0eebf73e3c0ff0e7853f68be638b4043c65a70517bb575eff54edd8dbe", size = 255026, upload-time = "2025-06-09T22:55:30.184Z" }, + { url = "https://files.pythonhosted.org/packages/8b/95/8e6a6bbbd78ac89c30c225210a5c687790e532ba4088afb8c0445b77ef37/propcache-0.3.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:03c89c1b14a5452cf15403e291c0ccd7751d5b9736ecb2c5bab977ad6c5bcd81", size = 250724, upload-time = "2025-06-09T22:55:31.646Z" }, + { url = "https://files.pythonhosted.org/packages/ee/b0/0dd03616142baba28e8b2d14ce5df6631b4673850a3d4f9c0f9dd714a404/propcache-0.3.2-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:0cc17efde71e12bbaad086d679ce575268d70bc123a5a71ea7ad76f70ba30bba", size = 268868, upload-time = "2025-06-09T22:55:33.209Z" }, + { url = "https://files.pythonhosted.org/packages/c5/98/2c12407a7e4fbacd94ddd32f3b1e3d5231e77c30ef7162b12a60e2dd5ce3/propcache-0.3.2-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:acdf05d00696bc0447e278bb53cb04ca72354e562cf88ea6f9107df8e7fd9770", size = 271322, upload-time = "2025-06-09T22:55:35.065Z" }, + { url = "https://files.pythonhosted.org/packages/35/91/9cb56efbb428b006bb85db28591e40b7736847b8331d43fe335acf95f6c8/propcache-0.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4445542398bd0b5d32df908031cb1b30d43ac848e20470a878b770ec2dcc6330", size = 265778, upload-time = "2025-06-09T22:55:36.45Z" }, + { url = "https://files.pythonhosted.org/packages/9a/4c/b0fe775a2bdd01e176b14b574be679d84fc83958335790f7c9a686c1f468/propcache-0.3.2-cp313-cp313t-win32.whl", hash = "sha256:f86e5d7cd03afb3a1db8e9f9f6eff15794e79e791350ac48a8c924e6f439f394", size = 41175, upload-time = "2025-06-09T22:55:38.436Z" }, + { url = "https://files.pythonhosted.org/packages/a4/ff/47f08595e3d9b5e149c150f88d9714574f1a7cbd89fe2817158a952674bf/propcache-0.3.2-cp313-cp313t-win_amd64.whl", hash = "sha256:9704bedf6e7cbe3c65eca4379a9b53ee6a83749f047808cbb5044d40d7d72198", size = 44857, upload-time = "2025-06-09T22:55:39.687Z" }, + { url = "https://files.pythonhosted.org/packages/6c/39/8ea9bcfaaff16fd0b0fc901ee522e24c9ec44b4ca0229cfffb8066a06959/propcache-0.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a7fad897f14d92086d6b03fdd2eb844777b0c4d7ec5e3bac0fbae2ab0602bbe5", size = 74678, upload-time = "2025-06-09T22:55:41.227Z" }, + { url = "https://files.pythonhosted.org/packages/d3/85/cab84c86966e1d354cf90cdc4ba52f32f99a5bca92a1529d666d957d7686/propcache-0.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1f43837d4ca000243fd7fd6301947d7cb93360d03cd08369969450cc6b2ce3b4", size = 43829, upload-time = "2025-06-09T22:55:42.417Z" }, + { url = "https://files.pythonhosted.org/packages/23/f7/9cb719749152d8b26d63801b3220ce2d3931312b2744d2b3a088b0ee9947/propcache-0.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:261df2e9474a5949c46e962065d88eb9b96ce0f2bd30e9d3136bcde84befd8f2", size = 43729, upload-time = "2025-06-09T22:55:43.651Z" }, + { url = "https://files.pythonhosted.org/packages/a2/a2/0b2b5a210ff311260002a315f6f9531b65a36064dfb804655432b2f7d3e3/propcache-0.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e514326b79e51f0a177daab1052bc164d9d9e54133797a3a58d24c9c87a3fe6d", size = 204483, upload-time = "2025-06-09T22:55:45.327Z" }, + { url = "https://files.pythonhosted.org/packages/3f/e0/7aff5de0c535f783b0c8be5bdb750c305c1961d69fbb136939926e155d98/propcache-0.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4a996adb6904f85894570301939afeee65f072b4fd265ed7e569e8d9058e4ec", size = 217425, upload-time = "2025-06-09T22:55:46.729Z" }, + { url = "https://files.pythonhosted.org/packages/92/1d/65fa889eb3b2a7d6e4ed3c2b568a9cb8817547a1450b572de7bf24872800/propcache-0.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76cace5d6b2a54e55b137669b30f31aa15977eeed390c7cbfb1dafa8dfe9a701", size = 214723, upload-time = "2025-06-09T22:55:48.342Z" }, + { url = "https://files.pythonhosted.org/packages/9a/e2/eecf6989870988dfd731de408a6fa366e853d361a06c2133b5878ce821ad/propcache-0.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31248e44b81d59d6addbb182c4720f90b44e1efdc19f58112a3c3a1615fb47ef", size = 200166, upload-time = "2025-06-09T22:55:49.775Z" }, + { url = "https://files.pythonhosted.org/packages/12/06/c32be4950967f18f77489268488c7cdc78cbfc65a8ba8101b15e526b83dc/propcache-0.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abb7fa19dbf88d3857363e0493b999b8011eea856b846305d8c0512dfdf8fbb1", size = 194004, upload-time = "2025-06-09T22:55:51.335Z" }, + { url = "https://files.pythonhosted.org/packages/46/6c/17b521a6b3b7cbe277a4064ff0aa9129dd8c89f425a5a9b6b4dd51cc3ff4/propcache-0.3.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d81ac3ae39d38588ad0549e321e6f773a4e7cc68e7751524a22885d5bbadf886", size = 203075, upload-time = "2025-06-09T22:55:52.681Z" }, + { url = "https://files.pythonhosted.org/packages/62/cb/3bdba2b736b3e45bc0e40f4370f745b3e711d439ffbffe3ae416393eece9/propcache-0.3.2-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:cc2782eb0f7a16462285b6f8394bbbd0e1ee5f928034e941ffc444012224171b", size = 195407, upload-time = "2025-06-09T22:55:54.048Z" }, + { url = "https://files.pythonhosted.org/packages/29/bd/760c5c6a60a4a2c55a421bc34a25ba3919d49dee411ddb9d1493bb51d46e/propcache-0.3.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:db429c19a6c7e8a1c320e6a13c99799450f411b02251fb1b75e6217cf4a14fcb", size = 196045, upload-time = "2025-06-09T22:55:55.485Z" }, + { url = "https://files.pythonhosted.org/packages/76/58/ced2757a46f55b8c84358d6ab8de4faf57cba831c51e823654da7144b13a/propcache-0.3.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:21d8759141a9e00a681d35a1f160892a36fb6caa715ba0b832f7747da48fb6ea", size = 208432, upload-time = "2025-06-09T22:55:56.884Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ec/d98ea8d5a4d8fe0e372033f5254eddf3254344c0c5dc6c49ab84349e4733/propcache-0.3.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2ca6d378f09adb13837614ad2754fa8afaee330254f404299611bce41a8438cb", size = 210100, upload-time = "2025-06-09T22:55:58.498Z" }, + { url = "https://files.pythonhosted.org/packages/56/84/b6d8a7ecf3f62d7dd09d9d10bbf89fad6837970ef868b35b5ffa0d24d9de/propcache-0.3.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:34a624af06c048946709f4278b4176470073deda88d91342665d95f7c6270fbe", size = 200712, upload-time = "2025-06-09T22:55:59.906Z" }, + { url = "https://files.pythonhosted.org/packages/bf/32/889f4903ddfe4a9dc61da71ee58b763758cf2d608fe1decede06e6467f8d/propcache-0.3.2-cp39-cp39-win32.whl", hash = "sha256:4ba3fef1c30f306b1c274ce0b8baaa2c3cdd91f645c48f06394068f37d3837a1", size = 38187, upload-time = "2025-06-09T22:56:01.212Z" }, + { url = "https://files.pythonhosted.org/packages/67/74/d666795fb9ba1dc139d30de64f3b6fd1ff9c9d3d96ccfdb992cd715ce5d2/propcache-0.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:7a2368eed65fc69a7a7a40b27f22e85e7627b74216f0846b04ba5c116e191ec9", size = 42025, upload-time = "2025-06-09T22:56:02.875Z" }, + { url = "https://files.pythonhosted.org/packages/cc/35/cc0aaecf278bb4575b8555f2b137de5ab821595ddae9da9d3cd1da4072c7/propcache-0.3.2-py3-none-any.whl", hash = "sha256:98f1ec44fb675f5052cccc8e609c46ed23a35a1cfd18545ad4e29002d858a43f", size = 12663, upload-time = "2025-06-09T22:56:04.484Z" }, +] + +[[package]] +name = "setuptools" +version = "80.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.14.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/5a/da40306b885cc8c09109dc2e1abd358d5684b1425678151cdaed4731c822/typing_extensions-4.14.1.tar.gz", hash = "sha256:38b39f4aeeab64884ce9f74c94263ef78f3c22467c8724005483154c26648d36", size = 107673, upload-time = "2025-07-04T13:28:34.16Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, +] + +[[package]] +name = "yarl" +version = "1.20.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "multidict" }, + { name = "propcache" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3c/fb/efaa23fa4e45537b827620f04cf8f3cd658b76642205162e072703a5b963/yarl-1.20.1.tar.gz", hash = "sha256:d017a4997ee50c91fd5466cef416231bb82177b93b029906cefc542ce14c35ac", size = 186428, upload-time = "2025-06-10T00:46:09.923Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/65/7fed0d774abf47487c64be14e9223749468922817b5e8792b8a64792a1bb/yarl-1.20.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6032e6da6abd41e4acda34d75a816012717000fa6839f37124a47fcefc49bec4", size = 132910, upload-time = "2025-06-10T00:42:31.108Z" }, + { url = "https://files.pythonhosted.org/packages/8a/7b/988f55a52da99df9e56dc733b8e4e5a6ae2090081dc2754fc8fd34e60aa0/yarl-1.20.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2c7b34d804b8cf9b214f05015c4fee2ebe7ed05cf581e7192c06555c71f4446a", size = 90644, upload-time = "2025-06-10T00:42:33.851Z" }, + { url = "https://files.pythonhosted.org/packages/f7/de/30d98f03e95d30c7e3cc093759982d038c8833ec2451001d45ef4854edc1/yarl-1.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0c869f2651cc77465f6cd01d938d91a11d9ea5d798738c1dc077f3de0b5e5fed", size = 89322, upload-time = "2025-06-10T00:42:35.688Z" }, + { url = "https://files.pythonhosted.org/packages/e0/7a/f2f314f5ebfe9200724b0b748de2186b927acb334cf964fd312eb86fc286/yarl-1.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62915e6688eb4d180d93840cda4110995ad50c459bf931b8b3775b37c264af1e", size = 323786, upload-time = "2025-06-10T00:42:37.817Z" }, + { url = "https://files.pythonhosted.org/packages/15/3f/718d26f189db96d993d14b984ce91de52e76309d0fd1d4296f34039856aa/yarl-1.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:41ebd28167bc6af8abb97fec1a399f412eec5fd61a3ccbe2305a18b84fb4ca73", size = 319627, upload-time = "2025-06-10T00:42:39.937Z" }, + { url = "https://files.pythonhosted.org/packages/a5/76/8fcfbf5fa2369157b9898962a4a7d96764b287b085b5b3d9ffae69cdefd1/yarl-1.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21242b4288a6d56f04ea193adde174b7e347ac46ce6bc84989ff7c1b1ecea84e", size = 339149, upload-time = "2025-06-10T00:42:42.627Z" }, + { url = "https://files.pythonhosted.org/packages/3c/95/d7fc301cc4661785967acc04f54a4a42d5124905e27db27bb578aac49b5c/yarl-1.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bea21cdae6c7eb02ba02a475f37463abfe0a01f5d7200121b03e605d6a0439f8", size = 333327, upload-time = "2025-06-10T00:42:44.842Z" }, + { url = "https://files.pythonhosted.org/packages/65/94/e21269718349582eee81efc5c1c08ee71c816bfc1585b77d0ec3f58089eb/yarl-1.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f8a891e4a22a89f5dde7862994485e19db246b70bb288d3ce73a34422e55b23", size = 326054, upload-time = "2025-06-10T00:42:47.149Z" }, + { url = "https://files.pythonhosted.org/packages/32/ae/8616d1f07853704523519f6131d21f092e567c5af93de7e3e94b38d7f065/yarl-1.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dd803820d44c8853a109a34e3660e5a61beae12970da479cf44aa2954019bf70", size = 315035, upload-time = "2025-06-10T00:42:48.852Z" }, + { url = "https://files.pythonhosted.org/packages/48/aa/0ace06280861ef055855333707db5e49c6e3a08840a7ce62682259d0a6c0/yarl-1.20.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b982fa7f74c80d5c0c7b5b38f908971e513380a10fecea528091405f519b9ebb", size = 338962, upload-time = "2025-06-10T00:42:51.024Z" }, + { url = "https://files.pythonhosted.org/packages/20/52/1e9d0e6916f45a8fb50e6844f01cb34692455f1acd548606cbda8134cd1e/yarl-1.20.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:33f29ecfe0330c570d997bcf1afd304377f2e48f61447f37e846a6058a4d33b2", size = 335399, upload-time = "2025-06-10T00:42:53.007Z" }, + { url = "https://files.pythonhosted.org/packages/f2/65/60452df742952c630e82f394cd409de10610481d9043aa14c61bf846b7b1/yarl-1.20.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:835ab2cfc74d5eb4a6a528c57f05688099da41cf4957cf08cad38647e4a83b30", size = 338649, upload-time = "2025-06-10T00:42:54.964Z" }, + { url = "https://files.pythonhosted.org/packages/7b/f5/6cd4ff38dcde57a70f23719a838665ee17079640c77087404c3d34da6727/yarl-1.20.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:46b5e0ccf1943a9a6e766b2c2b8c732c55b34e28be57d8daa2b3c1d1d4009309", size = 358563, upload-time = "2025-06-10T00:42:57.28Z" }, + { url = "https://files.pythonhosted.org/packages/d1/90/c42eefd79d0d8222cb3227bdd51b640c0c1d0aa33fe4cc86c36eccba77d3/yarl-1.20.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:df47c55f7d74127d1b11251fe6397d84afdde0d53b90bedb46a23c0e534f9d24", size = 357609, upload-time = "2025-06-10T00:42:59.055Z" }, + { url = "https://files.pythonhosted.org/packages/03/c8/cea6b232cb4617514232e0f8a718153a95b5d82b5290711b201545825532/yarl-1.20.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76d12524d05841276b0e22573f28d5fbcb67589836772ae9244d90dd7d66aa13", size = 350224, upload-time = "2025-06-10T00:43:01.248Z" }, + { url = "https://files.pythonhosted.org/packages/ce/a3/eaa0ab9712f1f3d01faf43cf6f1f7210ce4ea4a7e9b28b489a2261ca8db9/yarl-1.20.1-cp310-cp310-win32.whl", hash = "sha256:6c4fbf6b02d70e512d7ade4b1f998f237137f1417ab07ec06358ea04f69134f8", size = 81753, upload-time = "2025-06-10T00:43:03.486Z" }, + { url = "https://files.pythonhosted.org/packages/8f/34/e4abde70a9256465fe31c88ed02c3f8502b7b5dead693a4f350a06413f28/yarl-1.20.1-cp310-cp310-win_amd64.whl", hash = "sha256:aef6c4d69554d44b7f9d923245f8ad9a707d971e6209d51279196d8e8fe1ae16", size = 86817, upload-time = "2025-06-10T00:43:05.231Z" }, + { url = "https://files.pythonhosted.org/packages/b1/18/893b50efc2350e47a874c5c2d67e55a0ea5df91186b2a6f5ac52eff887cd/yarl-1.20.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:47ee6188fea634bdfaeb2cc420f5b3b17332e6225ce88149a17c413c77ff269e", size = 133833, upload-time = "2025-06-10T00:43:07.393Z" }, + { url = "https://files.pythonhosted.org/packages/89/ed/b8773448030e6fc47fa797f099ab9eab151a43a25717f9ac043844ad5ea3/yarl-1.20.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d0f6500f69e8402d513e5eedb77a4e1818691e8f45e6b687147963514d84b44b", size = 91070, upload-time = "2025-06-10T00:43:09.538Z" }, + { url = "https://files.pythonhosted.org/packages/e3/e3/409bd17b1e42619bf69f60e4f031ce1ccb29bd7380117a55529e76933464/yarl-1.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7a8900a42fcdaad568de58887c7b2f602962356908eedb7628eaf6021a6e435b", size = 89818, upload-time = "2025-06-10T00:43:11.575Z" }, + { url = "https://files.pythonhosted.org/packages/f8/77/64d8431a4d77c856eb2d82aa3de2ad6741365245a29b3a9543cd598ed8c5/yarl-1.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bad6d131fda8ef508b36be3ece16d0902e80b88ea7200f030a0f6c11d9e508d4", size = 347003, upload-time = "2025-06-10T00:43:14.088Z" }, + { url = "https://files.pythonhosted.org/packages/8d/d2/0c7e4def093dcef0bd9fa22d4d24b023788b0a33b8d0088b51aa51e21e99/yarl-1.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:df018d92fe22aaebb679a7f89fe0c0f368ec497e3dda6cb81a567610f04501f1", size = 336537, upload-time = "2025-06-10T00:43:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f3/fc514f4b2cf02cb59d10cbfe228691d25929ce8f72a38db07d3febc3f706/yarl-1.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f969afbb0a9b63c18d0feecf0db09d164b7a44a053e78a7d05f5df163e43833", size = 362358, upload-time = "2025-06-10T00:43:18.704Z" }, + { url = "https://files.pythonhosted.org/packages/ea/6d/a313ac8d8391381ff9006ac05f1d4331cee3b1efaa833a53d12253733255/yarl-1.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:812303eb4aa98e302886ccda58d6b099e3576b1b9276161469c25803a8db277d", size = 357362, upload-time = "2025-06-10T00:43:20.888Z" }, + { url = "https://files.pythonhosted.org/packages/00/70/8f78a95d6935a70263d46caa3dd18e1f223cf2f2ff2037baa01a22bc5b22/yarl-1.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98c4a7d166635147924aa0bf9bfe8d8abad6fffa6102de9c99ea04a1376f91e8", size = 348979, upload-time = "2025-06-10T00:43:23.169Z" }, + { url = "https://files.pythonhosted.org/packages/cb/05/42773027968968f4f15143553970ee36ead27038d627f457cc44bbbeecf3/yarl-1.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12e768f966538e81e6e7550f9086a6236b16e26cd964cf4df35349970f3551cf", size = 337274, upload-time = "2025-06-10T00:43:27.111Z" }, + { url = "https://files.pythonhosted.org/packages/05/be/665634aa196954156741ea591d2f946f1b78ceee8bb8f28488bf28c0dd62/yarl-1.20.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe41919b9d899661c5c28a8b4b0acf704510b88f27f0934ac7a7bebdd8938d5e", size = 363294, upload-time = "2025-06-10T00:43:28.96Z" }, + { url = "https://files.pythonhosted.org/packages/eb/90/73448401d36fa4e210ece5579895731f190d5119c4b66b43b52182e88cd5/yarl-1.20.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:8601bc010d1d7780592f3fc1bdc6c72e2b6466ea34569778422943e1a1f3c389", size = 358169, upload-time = "2025-06-10T00:43:30.701Z" }, + { url = "https://files.pythonhosted.org/packages/c3/b0/fce922d46dc1eb43c811f1889f7daa6001b27a4005587e94878570300881/yarl-1.20.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:daadbdc1f2a9033a2399c42646fbd46da7992e868a5fe9513860122d7fe7a73f", size = 362776, upload-time = "2025-06-10T00:43:32.51Z" }, + { url = "https://files.pythonhosted.org/packages/f1/0d/b172628fce039dae8977fd22caeff3eeebffd52e86060413f5673767c427/yarl-1.20.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:03aa1e041727cb438ca762628109ef1333498b122e4c76dd858d186a37cec845", size = 381341, upload-time = "2025-06-10T00:43:34.543Z" }, + { url = "https://files.pythonhosted.org/packages/6b/9b/5b886d7671f4580209e855974fe1cecec409aa4a89ea58b8f0560dc529b1/yarl-1.20.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:642980ef5e0fa1de5fa96d905c7e00cb2c47cb468bfcac5a18c58e27dbf8d8d1", size = 379988, upload-time = "2025-06-10T00:43:36.489Z" }, + { url = "https://files.pythonhosted.org/packages/73/be/75ef5fd0fcd8f083a5d13f78fd3f009528132a1f2a1d7c925c39fa20aa79/yarl-1.20.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:86971e2795584fe8c002356d3b97ef6c61862720eeff03db2a7c86b678d85b3e", size = 371113, upload-time = "2025-06-10T00:43:38.592Z" }, + { url = "https://files.pythonhosted.org/packages/50/4f/62faab3b479dfdcb741fe9e3f0323e2a7d5cd1ab2edc73221d57ad4834b2/yarl-1.20.1-cp311-cp311-win32.whl", hash = "sha256:597f40615b8d25812f14562699e287f0dcc035d25eb74da72cae043bb884d773", size = 81485, upload-time = "2025-06-10T00:43:41.038Z" }, + { url = "https://files.pythonhosted.org/packages/f0/09/d9c7942f8f05c32ec72cd5c8e041c8b29b5807328b68b4801ff2511d4d5e/yarl-1.20.1-cp311-cp311-win_amd64.whl", hash = "sha256:26ef53a9e726e61e9cd1cda6b478f17e350fb5800b4bd1cd9fe81c4d91cfeb2e", size = 86686, upload-time = "2025-06-10T00:43:42.692Z" }, + { url = "https://files.pythonhosted.org/packages/5f/9a/cb7fad7d73c69f296eda6815e4a2c7ed53fc70c2f136479a91c8e5fbdb6d/yarl-1.20.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdcc4cd244e58593a4379fe60fdee5ac0331f8eb70320a24d591a3be197b94a9", size = 133667, upload-time = "2025-06-10T00:43:44.369Z" }, + { url = "https://files.pythonhosted.org/packages/67/38/688577a1cb1e656e3971fb66a3492501c5a5df56d99722e57c98249e5b8a/yarl-1.20.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b29a2c385a5f5b9c7d9347e5812b6f7ab267193c62d282a540b4fc528c8a9d2a", size = 91025, upload-time = "2025-06-10T00:43:46.295Z" }, + { url = "https://files.pythonhosted.org/packages/50/ec/72991ae51febeb11a42813fc259f0d4c8e0507f2b74b5514618d8b640365/yarl-1.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1112ae8154186dfe2de4732197f59c05a83dc814849a5ced892b708033f40dc2", size = 89709, upload-time = "2025-06-10T00:43:48.22Z" }, + { url = "https://files.pythonhosted.org/packages/99/da/4d798025490e89426e9f976702e5f9482005c548c579bdae792a4c37769e/yarl-1.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:90bbd29c4fe234233f7fa2b9b121fb63c321830e5d05b45153a2ca68f7d310ee", size = 352287, upload-time = "2025-06-10T00:43:49.924Z" }, + { url = "https://files.pythonhosted.org/packages/1a/26/54a15c6a567aac1c61b18aa0f4b8aa2e285a52d547d1be8bf48abe2b3991/yarl-1.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:680e19c7ce3710ac4cd964e90dad99bf9b5029372ba0c7cbfcd55e54d90ea819", size = 345429, upload-time = "2025-06-10T00:43:51.7Z" }, + { url = "https://files.pythonhosted.org/packages/d6/95/9dcf2386cb875b234353b93ec43e40219e14900e046bf6ac118f94b1e353/yarl-1.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a979218c1fdb4246a05efc2cc23859d47c89af463a90b99b7c56094daf25a16", size = 365429, upload-time = "2025-06-10T00:43:53.494Z" }, + { url = "https://files.pythonhosted.org/packages/91/b2/33a8750f6a4bc224242a635f5f2cff6d6ad5ba651f6edcccf721992c21a0/yarl-1.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255b468adf57b4a7b65d8aad5b5138dce6a0752c139965711bdcb81bc370e1b6", size = 363862, upload-time = "2025-06-10T00:43:55.766Z" }, + { url = "https://files.pythonhosted.org/packages/98/28/3ab7acc5b51f4434b181b0cee8f1f4b77a65919700a355fb3617f9488874/yarl-1.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a97d67108e79cfe22e2b430d80d7571ae57d19f17cda8bb967057ca8a7bf5bfd", size = 355616, upload-time = "2025-06-10T00:43:58.056Z" }, + { url = "https://files.pythonhosted.org/packages/36/a3/f666894aa947a371724ec7cd2e5daa78ee8a777b21509b4252dd7bd15e29/yarl-1.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8570d998db4ddbfb9a590b185a0a33dbf8aafb831d07a5257b4ec9948df9cb0a", size = 339954, upload-time = "2025-06-10T00:43:59.773Z" }, + { url = "https://files.pythonhosted.org/packages/f1/81/5f466427e09773c04219d3450d7a1256138a010b6c9f0af2d48565e9ad13/yarl-1.20.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:97c75596019baae7c71ccf1d8cc4738bc08134060d0adfcbe5642f778d1dca38", size = 365575, upload-time = "2025-06-10T00:44:02.051Z" }, + { url = "https://files.pythonhosted.org/packages/2e/e3/e4b0ad8403e97e6c9972dd587388940a032f030ebec196ab81a3b8e94d31/yarl-1.20.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:1c48912653e63aef91ff988c5432832692ac5a1d8f0fb8a33091520b5bbe19ef", size = 365061, upload-time = "2025-06-10T00:44:04.196Z" }, + { url = "https://files.pythonhosted.org/packages/ac/99/b8a142e79eb86c926f9f06452eb13ecb1bb5713bd01dc0038faf5452e544/yarl-1.20.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4c3ae28f3ae1563c50f3d37f064ddb1511ecc1d5584e88c6b7c63cf7702a6d5f", size = 364142, upload-time = "2025-06-10T00:44:06.527Z" }, + { url = "https://files.pythonhosted.org/packages/34/f2/08ed34a4a506d82a1a3e5bab99ccd930a040f9b6449e9fd050320e45845c/yarl-1.20.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c5e9642f27036283550f5f57dc6156c51084b458570b9d0d96100c8bebb186a8", size = 381894, upload-time = "2025-06-10T00:44:08.379Z" }, + { url = "https://files.pythonhosted.org/packages/92/f8/9a3fbf0968eac704f681726eff595dce9b49c8a25cd92bf83df209668285/yarl-1.20.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:2c26b0c49220d5799f7b22c6838409ee9bc58ee5c95361a4d7831f03cc225b5a", size = 383378, upload-time = "2025-06-10T00:44:10.51Z" }, + { url = "https://files.pythonhosted.org/packages/af/85/9363f77bdfa1e4d690957cd39d192c4cacd1c58965df0470a4905253b54f/yarl-1.20.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:564ab3d517e3d01c408c67f2e5247aad4019dcf1969982aba3974b4093279004", size = 374069, upload-time = "2025-06-10T00:44:12.834Z" }, + { url = "https://files.pythonhosted.org/packages/35/99/9918c8739ba271dcd935400cff8b32e3cd319eaf02fcd023d5dcd487a7c8/yarl-1.20.1-cp312-cp312-win32.whl", hash = "sha256:daea0d313868da1cf2fac6b2d3a25c6e3a9e879483244be38c8e6a41f1d876a5", size = 81249, upload-time = "2025-06-10T00:44:14.731Z" }, + { url = "https://files.pythonhosted.org/packages/eb/83/5d9092950565481b413b31a23e75dd3418ff0a277d6e0abf3729d4d1ce25/yarl-1.20.1-cp312-cp312-win_amd64.whl", hash = "sha256:48ea7d7f9be0487339828a4de0360d7ce0efc06524a48e1810f945c45b813698", size = 86710, upload-time = "2025-06-10T00:44:16.716Z" }, + { url = "https://files.pythonhosted.org/packages/8a/e1/2411b6d7f769a07687acee88a062af5833cf1966b7266f3d8dfb3d3dc7d3/yarl-1.20.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:0b5ff0fbb7c9f1b1b5ab53330acbfc5247893069e7716840c8e7d5bb7355038a", size = 131811, upload-time = "2025-06-10T00:44:18.933Z" }, + { url = "https://files.pythonhosted.org/packages/b2/27/584394e1cb76fb771371770eccad35de400e7b434ce3142c2dd27392c968/yarl-1.20.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:14f326acd845c2b2e2eb38fb1346c94f7f3b01a4f5c788f8144f9b630bfff9a3", size = 90078, upload-time = "2025-06-10T00:44:20.635Z" }, + { url = "https://files.pythonhosted.org/packages/bf/9a/3246ae92d4049099f52d9b0fe3486e3b500e29b7ea872d0f152966fc209d/yarl-1.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f60e4ad5db23f0b96e49c018596707c3ae89f5d0bd97f0ad3684bcbad899f1e7", size = 88748, upload-time = "2025-06-10T00:44:22.34Z" }, + { url = "https://files.pythonhosted.org/packages/a3/25/35afe384e31115a1a801fbcf84012d7a066d89035befae7c5d4284df1e03/yarl-1.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49bdd1b8e00ce57e68ba51916e4bb04461746e794e7c4d4bbc42ba2f18297691", size = 349595, upload-time = "2025-06-10T00:44:24.314Z" }, + { url = "https://files.pythonhosted.org/packages/28/2d/8aca6cb2cabc8f12efcb82749b9cefecbccfc7b0384e56cd71058ccee433/yarl-1.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:66252d780b45189975abfed839616e8fd2dbacbdc262105ad7742c6ae58f3e31", size = 342616, upload-time = "2025-06-10T00:44:26.167Z" }, + { url = "https://files.pythonhosted.org/packages/0b/e9/1312633d16b31acf0098d30440ca855e3492d66623dafb8e25b03d00c3da/yarl-1.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59174e7332f5d153d8f7452a102b103e2e74035ad085f404df2e40e663a22b28", size = 361324, upload-time = "2025-06-10T00:44:27.915Z" }, + { url = "https://files.pythonhosted.org/packages/bc/a0/688cc99463f12f7669eec7c8acc71ef56a1521b99eab7cd3abb75af887b0/yarl-1.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3968ec7d92a0c0f9ac34d5ecfd03869ec0cab0697c91a45db3fbbd95fe1b653", size = 359676, upload-time = "2025-06-10T00:44:30.041Z" }, + { url = "https://files.pythonhosted.org/packages/af/44/46407d7f7a56e9a85a4c207724c9f2c545c060380718eea9088f222ba697/yarl-1.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1a4fbb50e14396ba3d375f68bfe02215d8e7bc3ec49da8341fe3157f59d2ff5", size = 352614, upload-time = "2025-06-10T00:44:32.171Z" }, + { url = "https://files.pythonhosted.org/packages/b1/91/31163295e82b8d5485d31d9cf7754d973d41915cadce070491778d9c9825/yarl-1.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11a62c839c3a8eac2410e951301309426f368388ff2f33799052787035793b02", size = 336766, upload-time = "2025-06-10T00:44:34.494Z" }, + { url = "https://files.pythonhosted.org/packages/b4/8e/c41a5bc482121f51c083c4c2bcd16b9e01e1cf8729e380273a952513a21f/yarl-1.20.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:041eaa14f73ff5a8986b4388ac6bb43a77f2ea09bf1913df7a35d4646db69e53", size = 364615, upload-time = "2025-06-10T00:44:36.856Z" }, + { url = "https://files.pythonhosted.org/packages/e3/5b/61a3b054238d33d70ea06ebba7e58597891b71c699e247df35cc984ab393/yarl-1.20.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:377fae2fef158e8fd9d60b4c8751387b8d1fb121d3d0b8e9b0be07d1b41e83dc", size = 360982, upload-time = "2025-06-10T00:44:39.141Z" }, + { url = "https://files.pythonhosted.org/packages/df/a3/6a72fb83f8d478cb201d14927bc8040af901811a88e0ff2da7842dd0ed19/yarl-1.20.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1c92f4390e407513f619d49319023664643d3339bd5e5a56a3bebe01bc67ec04", size = 369792, upload-time = "2025-06-10T00:44:40.934Z" }, + { url = "https://files.pythonhosted.org/packages/7c/af/4cc3c36dfc7c077f8dedb561eb21f69e1e9f2456b91b593882b0b18c19dc/yarl-1.20.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d25ddcf954df1754ab0f86bb696af765c5bfaba39b74095f27eececa049ef9a4", size = 382049, upload-time = "2025-06-10T00:44:42.854Z" }, + { url = "https://files.pythonhosted.org/packages/19/3a/e54e2c4752160115183a66dc9ee75a153f81f3ab2ba4bf79c3c53b33de34/yarl-1.20.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:909313577e9619dcff8c31a0ea2aa0a2a828341d92673015456b3ae492e7317b", size = 384774, upload-time = "2025-06-10T00:44:45.275Z" }, + { url = "https://files.pythonhosted.org/packages/9c/20/200ae86dabfca89060ec6447649f219b4cbd94531e425e50d57e5f5ac330/yarl-1.20.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:793fd0580cb9664548c6b83c63b43c477212c0260891ddf86809e1c06c8b08f1", size = 374252, upload-time = "2025-06-10T00:44:47.31Z" }, + { url = "https://files.pythonhosted.org/packages/83/75/11ee332f2f516b3d094e89448da73d557687f7d137d5a0f48c40ff211487/yarl-1.20.1-cp313-cp313-win32.whl", hash = "sha256:468f6e40285de5a5b3c44981ca3a319a4b208ccc07d526b20b12aeedcfa654b7", size = 81198, upload-time = "2025-06-10T00:44:49.164Z" }, + { url = "https://files.pythonhosted.org/packages/ba/ba/39b1ecbf51620b40ab402b0fc817f0ff750f6d92712b44689c2c215be89d/yarl-1.20.1-cp313-cp313-win_amd64.whl", hash = "sha256:495b4ef2fea40596bfc0affe3837411d6aa3371abcf31aac0ccc4bdd64d4ef5c", size = 86346, upload-time = "2025-06-10T00:44:51.182Z" }, + { url = "https://files.pythonhosted.org/packages/43/c7/669c52519dca4c95153c8ad96dd123c79f354a376346b198f438e56ffeb4/yarl-1.20.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:f60233b98423aab21d249a30eb27c389c14929f47be8430efa7dbd91493a729d", size = 138826, upload-time = "2025-06-10T00:44:52.883Z" }, + { url = "https://files.pythonhosted.org/packages/6a/42/fc0053719b44f6ad04a75d7f05e0e9674d45ef62f2d9ad2c1163e5c05827/yarl-1.20.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:6f3eff4cc3f03d650d8755c6eefc844edde99d641d0dcf4da3ab27141a5f8ddf", size = 93217, upload-time = "2025-06-10T00:44:54.658Z" }, + { url = "https://files.pythonhosted.org/packages/4f/7f/fa59c4c27e2a076bba0d959386e26eba77eb52ea4a0aac48e3515c186b4c/yarl-1.20.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:69ff8439d8ba832d6bed88af2c2b3445977eba9a4588b787b32945871c2444e3", size = 92700, upload-time = "2025-06-10T00:44:56.784Z" }, + { url = "https://files.pythonhosted.org/packages/2f/d4/062b2f48e7c93481e88eff97a6312dca15ea200e959f23e96d8ab898c5b8/yarl-1.20.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cf34efa60eb81dd2645a2e13e00bb98b76c35ab5061a3989c7a70f78c85006d", size = 347644, upload-time = "2025-06-10T00:44:59.071Z" }, + { url = "https://files.pythonhosted.org/packages/89/47/78b7f40d13c8f62b499cc702fdf69e090455518ae544c00a3bf4afc9fc77/yarl-1.20.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8e0fe9364ad0fddab2688ce72cb7a8e61ea42eff3c7caeeb83874a5d479c896c", size = 323452, upload-time = "2025-06-10T00:45:01.605Z" }, + { url = "https://files.pythonhosted.org/packages/eb/2b/490d3b2dc66f52987d4ee0d3090a147ea67732ce6b4d61e362c1846d0d32/yarl-1.20.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f64fbf81878ba914562c672024089e3401974a39767747691c65080a67b18c1", size = 346378, upload-time = "2025-06-10T00:45:03.946Z" }, + { url = "https://files.pythonhosted.org/packages/66/ad/775da9c8a94ce925d1537f939a4f17d782efef1f973039d821cbe4bcc211/yarl-1.20.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6342d643bf9a1de97e512e45e4b9560a043347e779a173250824f8b254bd5ce", size = 353261, upload-time = "2025-06-10T00:45:05.992Z" }, + { url = "https://files.pythonhosted.org/packages/4b/23/0ed0922b47a4f5c6eb9065d5ff1e459747226ddce5c6a4c111e728c9f701/yarl-1.20.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56dac5f452ed25eef0f6e3c6a066c6ab68971d96a9fb441791cad0efba6140d3", size = 335987, upload-time = "2025-06-10T00:45:08.227Z" }, + { url = "https://files.pythonhosted.org/packages/3e/49/bc728a7fe7d0e9336e2b78f0958a2d6b288ba89f25a1762407a222bf53c3/yarl-1.20.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7d7f497126d65e2cad8dc5f97d34c27b19199b6414a40cb36b52f41b79014be", size = 329361, upload-time = "2025-06-10T00:45:10.11Z" }, + { url = "https://files.pythonhosted.org/packages/93/8f/b811b9d1f617c83c907e7082a76e2b92b655400e61730cd61a1f67178393/yarl-1.20.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:67e708dfb8e78d8a19169818eeb5c7a80717562de9051bf2413aca8e3696bf16", size = 346460, upload-time = "2025-06-10T00:45:12.055Z" }, + { url = "https://files.pythonhosted.org/packages/70/fd/af94f04f275f95da2c3b8b5e1d49e3e79f1ed8b6ceb0f1664cbd902773ff/yarl-1.20.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:595c07bc79af2494365cc96ddeb772f76272364ef7c80fb892ef9d0649586513", size = 334486, upload-time = "2025-06-10T00:45:13.995Z" }, + { url = "https://files.pythonhosted.org/packages/84/65/04c62e82704e7dd0a9b3f61dbaa8447f8507655fd16c51da0637b39b2910/yarl-1.20.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7bdd2f80f4a7df852ab9ab49484a4dee8030023aa536df41f2d922fd57bf023f", size = 342219, upload-time = "2025-06-10T00:45:16.479Z" }, + { url = "https://files.pythonhosted.org/packages/91/95/459ca62eb958381b342d94ab9a4b6aec1ddec1f7057c487e926f03c06d30/yarl-1.20.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:c03bfebc4ae8d862f853a9757199677ab74ec25424d0ebd68a0027e9c639a390", size = 350693, upload-time = "2025-06-10T00:45:18.399Z" }, + { url = "https://files.pythonhosted.org/packages/a6/00/d393e82dd955ad20617abc546a8f1aee40534d599ff555ea053d0ec9bf03/yarl-1.20.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:344d1103e9c1523f32a5ed704d576172d2cabed3122ea90b1d4e11fe17c66458", size = 355803, upload-time = "2025-06-10T00:45:20.677Z" }, + { url = "https://files.pythonhosted.org/packages/9e/ed/c5fb04869b99b717985e244fd93029c7a8e8febdfcffa06093e32d7d44e7/yarl-1.20.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:88cab98aa4e13e1ade8c141daeedd300a4603b7132819c484841bb7af3edce9e", size = 341709, upload-time = "2025-06-10T00:45:23.221Z" }, + { url = "https://files.pythonhosted.org/packages/24/fd/725b8e73ac2a50e78a4534ac43c6addf5c1c2d65380dd48a9169cc6739a9/yarl-1.20.1-cp313-cp313t-win32.whl", hash = "sha256:b121ff6a7cbd4abc28985b6028235491941b9fe8fe226e6fdc539c977ea1739d", size = 86591, upload-time = "2025-06-10T00:45:25.793Z" }, + { url = "https://files.pythonhosted.org/packages/94/c3/b2e9f38bc3e11191981d57ea08cab2166e74ea770024a646617c9cddd9f6/yarl-1.20.1-cp313-cp313t-win_amd64.whl", hash = "sha256:541d050a355bbbc27e55d906bc91cb6fe42f96c01413dd0f4ed5a5240513874f", size = 93003, upload-time = "2025-06-10T00:45:27.752Z" }, + { url = "https://files.pythonhosted.org/packages/01/75/0d37402d208d025afa6b5b8eb80e466d267d3fd1927db8e317d29a94a4cb/yarl-1.20.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e42ba79e2efb6845ebab49c7bf20306c4edf74a0b20fc6b2ccdd1a219d12fad3", size = 134259, upload-time = "2025-06-10T00:45:29.882Z" }, + { url = "https://files.pythonhosted.org/packages/73/84/1fb6c85ae0cf9901046f07d0ac9eb162f7ce6d95db541130aa542ed377e6/yarl-1.20.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:41493b9b7c312ac448b7f0a42a089dffe1d6e6e981a2d76205801a023ed26a2b", size = 91269, upload-time = "2025-06-10T00:45:32.917Z" }, + { url = "https://files.pythonhosted.org/packages/f3/9c/eae746b24c4ea29a5accba9a06c197a70fa38a49c7df244e0d3951108861/yarl-1.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f5a5928ff5eb13408c62a968ac90d43f8322fd56d87008b8f9dabf3c0f6ee983", size = 89995, upload-time = "2025-06-10T00:45:35.066Z" }, + { url = "https://files.pythonhosted.org/packages/fb/30/693e71003ec4bc1daf2e4cf7c478c417d0985e0a8e8f00b2230d517876fc/yarl-1.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30c41ad5d717b3961b2dd785593b67d386b73feca30522048d37298fee981805", size = 325253, upload-time = "2025-06-10T00:45:37.052Z" }, + { url = "https://files.pythonhosted.org/packages/0f/a2/5264dbebf90763139aeb0b0b3154763239398400f754ae19a0518b654117/yarl-1.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:59febc3969b0781682b469d4aca1a5cab7505a4f7b85acf6db01fa500fa3f6ba", size = 320897, upload-time = "2025-06-10T00:45:39.962Z" }, + { url = "https://files.pythonhosted.org/packages/e7/17/77c7a89b3c05856489777e922f41db79ab4faf58621886df40d812c7facd/yarl-1.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d2b6fb3622b7e5bf7a6e5b679a69326b4279e805ed1699d749739a61d242449e", size = 340696, upload-time = "2025-06-10T00:45:41.915Z" }, + { url = "https://files.pythonhosted.org/packages/6d/55/28409330b8ef5f2f681f5b478150496ec9cf3309b149dab7ec8ab5cfa3f0/yarl-1.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:749d73611db8d26a6281086f859ea7ec08f9c4c56cec864e52028c8b328db723", size = 335064, upload-time = "2025-06-10T00:45:43.893Z" }, + { url = "https://files.pythonhosted.org/packages/85/58/cb0257cbd4002828ff735f44d3c5b6966c4fd1fc8cc1cd3cd8a143fbc513/yarl-1.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9427925776096e664c39e131447aa20ec738bdd77c049c48ea5200db2237e000", size = 327256, upload-time = "2025-06-10T00:45:46.393Z" }, + { url = "https://files.pythonhosted.org/packages/53/f6/c77960370cfa46f6fb3d6a5a79a49d3abfdb9ef92556badc2dcd2748bc2a/yarl-1.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff70f32aa316393eaf8222d518ce9118148eddb8a53073c2403863b41033eed5", size = 316389, upload-time = "2025-06-10T00:45:48.358Z" }, + { url = "https://files.pythonhosted.org/packages/64/ab/be0b10b8e029553c10905b6b00c64ecad3ebc8ace44b02293a62579343f6/yarl-1.20.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c7ddf7a09f38667aea38801da8b8d6bfe81df767d9dfc8c88eb45827b195cd1c", size = 340481, upload-time = "2025-06-10T00:45:50.663Z" }, + { url = "https://files.pythonhosted.org/packages/c5/c3/3f327bd3905a4916029bf5feb7f86dcf864c7704f099715f62155fb386b2/yarl-1.20.1-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:57edc88517d7fc62b174fcfb2e939fbc486a68315d648d7e74d07fac42cec240", size = 336941, upload-time = "2025-06-10T00:45:52.554Z" }, + { url = "https://files.pythonhosted.org/packages/d1/42/040bdd5d3b3bb02b4a6ace4ed4075e02f85df964d6e6cb321795d2a6496a/yarl-1.20.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:dab096ce479d5894d62c26ff4f699ec9072269d514b4edd630a393223f45a0ee", size = 339936, upload-time = "2025-06-10T00:45:54.919Z" }, + { url = "https://files.pythonhosted.org/packages/0d/1c/911867b8e8c7463b84dfdc275e0d99b04b66ad5132b503f184fe76be8ea4/yarl-1.20.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:14a85f3bd2d7bb255be7183e5d7d6e70add151a98edf56a770d6140f5d5f4010", size = 360163, upload-time = "2025-06-10T00:45:56.87Z" }, + { url = "https://files.pythonhosted.org/packages/e2/31/8c389f6c6ca0379b57b2da87f1f126c834777b4931c5ee8427dd65d0ff6b/yarl-1.20.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:2c89b5c792685dd9cd3fa9761c1b9f46fc240c2a3265483acc1565769996a3f8", size = 359108, upload-time = "2025-06-10T00:45:58.869Z" }, + { url = "https://files.pythonhosted.org/packages/7f/09/ae4a649fb3964324c70a3e2b61f45e566d9ffc0affd2b974cbf628957673/yarl-1.20.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:69e9b141de5511021942a6866990aea6d111c9042235de90e08f94cf972ca03d", size = 351875, upload-time = "2025-06-10T00:46:01.45Z" }, + { url = "https://files.pythonhosted.org/packages/8d/43/bbb4ed4c34d5bb62b48bf957f68cd43f736f79059d4f85225ab1ef80f4b9/yarl-1.20.1-cp39-cp39-win32.whl", hash = "sha256:b5f307337819cdfdbb40193cad84978a029f847b0a357fbe49f712063cfc4f06", size = 82293, upload-time = "2025-06-10T00:46:03.763Z" }, + { url = "https://files.pythonhosted.org/packages/d7/cd/ce185848a7dba68ea69e932674b5c1a42a1852123584bccc5443120f857c/yarl-1.20.1-cp39-cp39-win_amd64.whl", hash = "sha256:eae7bfe2069f9c1c5b05fc7fe5d612e5bbc089a39309904ee8b829e322dcad00", size = 87385, upload-time = "2025-06-10T00:46:05.655Z" }, + { url = "https://files.pythonhosted.org/packages/b4/2d/2345fce04cfd4bee161bf1e7d9cdc702e3e16109021035dbb24db654a622/yarl-1.20.1-py3-none-any.whl", hash = "sha256:83b8eb083fe4683c6115795d9fc1cfaf2cbbefb19b3a1cb68f6527460f483a77", size = 46542, upload-time = "2025-06-10T00:46:07.521Z" }, +] From 0063c4f45f2df776dca8d2678f5311e88deb7981 Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Sun, 10 Aug 2025 15:59:24 +0000 Subject: [PATCH 03/21] fix: use timeout as async context manager --- dingz/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dingz/__init__.py b/dingz/__init__.py index 821deac..ef370f8 100644 --- a/dingz/__init__.py +++ b/dingz/__init__.py @@ -38,7 +38,7 @@ async def make_call( self._close_session = True try: - with async_timeout.timeout(TIMEOUT): + async with async_timeout.timeout(TIMEOUT): response = await self._session.request( method, uri, data=data, json=json_data, params=parameters, headers=headers, ) From da8a4ffb3dc4b3982e11a74863e2907b0bbfca3b Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Sun, 10 Aug 2025 16:04:32 +0000 Subject: [PATCH 04/21] feat: use ruff for formatting and linting --- .github/workflows/python.yml | 16 +++++++--------- pyproject.toml | 5 +++++ uv.lock | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index e057911..ae6a14c 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -2,9 +2,9 @@ name: Python lint and packages on: push: - branches: [ master ] + branches: [ master, dev ] pull_request: - branches: [ master ] + branches: [ master, dev ] jobs: build: @@ -15,17 +15,15 @@ jobs: python-version: [ 3.9, "3.10", "3.11" ] steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - python setup.py install + - uses: astral-sh/ruff-action@v3 - - name: Black Code Formatter - uses: jpetrucciani/black-check@22.12.0 + - uses: astral-sh/ruff-action@v3 + with: + args: "format --check --diff" diff --git a/pyproject.toml b/pyproject.toml index 38903f2..2413ad4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,3 +41,8 @@ build-backend = "uv_build" [tool.uv.build-backend] module-name = "dingz" module-root = "" + +[dependency-groups] +dev = [ + "ruff>=0.12.8", +] diff --git a/uv.lock b/uv.lock index 511f20f..f4883c5 100644 --- a/uv.lock +++ b/uv.lock @@ -200,6 +200,11 @@ dependencies = [ { name = "setuptools" }, ] +[package.dev-dependencies] +dev = [ + { name = "ruff" }, +] + [package.metadata] requires-dist = [ { name = "aiohttp", specifier = "<4" }, @@ -208,6 +213,9 @@ requires-dist = [ { name = "setuptools", specifier = ">=80.9.0" }, ] +[package.metadata.requires-dev] +dev = [{ name = "ruff", specifier = ">=0.12.8" }] + [[package]] name = "frozenlist" version = "1.7.0" @@ -553,6 +561,31 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cc/35/cc0aaecf278bb4575b8555f2b137de5ab821595ddae9da9d3cd1da4072c7/propcache-0.3.2-py3-none-any.whl", hash = "sha256:98f1ec44fb675f5052cccc8e609c46ed23a35a1cfd18545ad4e29002d858a43f", size = 12663, upload-time = "2025-06-09T22:56:04.484Z" }, ] +[[package]] +name = "ruff" +version = "0.12.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4b/da/5bd7565be729e86e1442dad2c9a364ceeff82227c2dece7c29697a9795eb/ruff-0.12.8.tar.gz", hash = "sha256:4cb3a45525176e1009b2b64126acf5f9444ea59066262791febf55e40493a033", size = 5242373, upload-time = "2025-08-07T19:05:47.268Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c9/1e/c843bfa8ad1114fab3eb2b78235dda76acd66384c663a4e0415ecc13aa1e/ruff-0.12.8-py3-none-linux_armv6l.whl", hash = "sha256:63cb5a5e933fc913e5823a0dfdc3c99add73f52d139d6cd5cc8639d0e0465513", size = 11675315, upload-time = "2025-08-07T19:05:06.15Z" }, + { url = "https://files.pythonhosted.org/packages/24/ee/af6e5c2a8ca3a81676d5480a1025494fd104b8896266502bb4de2a0e8388/ruff-0.12.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9a9bbe28f9f551accf84a24c366c1aa8774d6748438b47174f8e8565ab9dedbc", size = 12456653, upload-time = "2025-08-07T19:05:09.759Z" }, + { url = "https://files.pythonhosted.org/packages/99/9d/e91f84dfe3866fa648c10512904991ecc326fd0b66578b324ee6ecb8f725/ruff-0.12.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2fae54e752a3150f7ee0e09bce2e133caf10ce9d971510a9b925392dc98d2fec", size = 11659690, upload-time = "2025-08-07T19:05:12.551Z" }, + { url = "https://files.pythonhosted.org/packages/fe/ac/a363d25ec53040408ebdd4efcee929d48547665858ede0505d1d8041b2e5/ruff-0.12.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0acbcf01206df963d9331b5838fb31f3b44fa979ee7fa368b9b9057d89f4a53", size = 11896923, upload-time = "2025-08-07T19:05:14.821Z" }, + { url = "https://files.pythonhosted.org/packages/58/9f/ea356cd87c395f6ade9bb81365bd909ff60860975ca1bc39f0e59de3da37/ruff-0.12.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ae3e7504666ad4c62f9ac8eedb52a93f9ebdeb34742b8b71cd3cccd24912719f", size = 11477612, upload-time = "2025-08-07T19:05:16.712Z" }, + { url = "https://files.pythonhosted.org/packages/1a/46/92e8fa3c9dcfd49175225c09053916cb97bb7204f9f899c2f2baca69e450/ruff-0.12.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb82efb5d35d07497813a1c5647867390a7d83304562607f3579602fa3d7d46f", size = 13182745, upload-time = "2025-08-07T19:05:18.709Z" }, + { url = "https://files.pythonhosted.org/packages/5e/c4/f2176a310f26e6160deaf661ef60db6c3bb62b7a35e57ae28f27a09a7d63/ruff-0.12.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:dbea798fc0065ad0b84a2947b0aff4233f0cb30f226f00a2c5850ca4393de609", size = 14206885, upload-time = "2025-08-07T19:05:21.025Z" }, + { url = "https://files.pythonhosted.org/packages/87/9d/98e162f3eeeb6689acbedbae5050b4b3220754554526c50c292b611d3a63/ruff-0.12.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:49ebcaccc2bdad86fd51b7864e3d808aad404aab8df33d469b6e65584656263a", size = 13639381, upload-time = "2025-08-07T19:05:23.423Z" }, + { url = "https://files.pythonhosted.org/packages/81/4e/1b7478b072fcde5161b48f64774d6edd59d6d198e4ba8918d9f4702b8043/ruff-0.12.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ac9c570634b98c71c88cb17badd90f13fc076a472ba6ef1d113d8ed3df109fb", size = 12613271, upload-time = "2025-08-07T19:05:25.507Z" }, + { url = "https://files.pythonhosted.org/packages/e8/67/0c3c9179a3ad19791ef1b8f7138aa27d4578c78700551c60d9260b2c660d/ruff-0.12.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:560e0cd641e45591a3e42cb50ef61ce07162b9c233786663fdce2d8557d99818", size = 12847783, upload-time = "2025-08-07T19:05:28.14Z" }, + { url = "https://files.pythonhosted.org/packages/4e/2a/0b6ac3dd045acf8aa229b12c9c17bb35508191b71a14904baf99573a21bd/ruff-0.12.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:71c83121512e7743fba5a8848c261dcc454cafb3ef2934a43f1b7a4eb5a447ea", size = 11702672, upload-time = "2025-08-07T19:05:30.413Z" }, + { url = "https://files.pythonhosted.org/packages/9d/ee/f9fdc9f341b0430110de8b39a6ee5fa68c5706dc7c0aa940817947d6937e/ruff-0.12.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:de4429ef2ba091ecddedd300f4c3f24bca875d3d8b23340728c3cb0da81072c3", size = 11440626, upload-time = "2025-08-07T19:05:32.492Z" }, + { url = "https://files.pythonhosted.org/packages/89/fb/b3aa2d482d05f44e4d197d1de5e3863feb13067b22c571b9561085c999dc/ruff-0.12.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a2cab5f60d5b65b50fba39a8950c8746df1627d54ba1197f970763917184b161", size = 12462162, upload-time = "2025-08-07T19:05:34.449Z" }, + { url = "https://files.pythonhosted.org/packages/18/9f/5c5d93e1d00d854d5013c96e1a92c33b703a0332707a7cdbd0a4880a84fb/ruff-0.12.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:45c32487e14f60b88aad6be9fd5da5093dbefb0e3e1224131cb1d441d7cb7d46", size = 12913212, upload-time = "2025-08-07T19:05:36.541Z" }, + { url = "https://files.pythonhosted.org/packages/71/13/ab9120add1c0e4604c71bfc2e4ef7d63bebece0cfe617013da289539cef8/ruff-0.12.8-py3-none-win32.whl", hash = "sha256:daf3475060a617fd5bc80638aeaf2f5937f10af3ec44464e280a9d2218e720d3", size = 11694382, upload-time = "2025-08-07T19:05:38.468Z" }, + { url = "https://files.pythonhosted.org/packages/f6/dc/a2873b7c5001c62f46266685863bee2888caf469d1edac84bf3242074be2/ruff-0.12.8-py3-none-win_amd64.whl", hash = "sha256:7209531f1a1fcfbe8e46bcd7ab30e2f43604d8ba1c49029bb420b103d0b5f76e", size = 12740482, upload-time = "2025-08-07T19:05:40.391Z" }, + { url = "https://files.pythonhosted.org/packages/cb/5c/799a1efb8b5abab56e8a9f2a0b72d12bd64bb55815e9476c7d0a2887d2f7/ruff-0.12.8-py3-none-win_arm64.whl", hash = "sha256:c90e1a334683ce41b0e7a04f41790c429bf5073b62c1ae701c9dc5b3d14f0749", size = 11884718, upload-time = "2025-08-07T19:05:42.866Z" }, +] + [[package]] name = "setuptools" version = "80.9.0" From 691ba2dc8d12a7fb2769e4a8e23718c000127e8d Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Sun, 10 Aug 2025 16:05:47 +0000 Subject: [PATCH 05/21] chore: apply formatting --- dingz/__init__.py | 25 +++++++++++++++++++++---- dingz/cli.py | 1 + dingz/constants.py | 1 + dingz/dimmer.py | 40 +++++++++++++++++++++++----------------- dingz/dingz.py | 14 ++++++++------ dingz/discovery.py | 8 ++++++-- dingz/registry.py | 3 ++- dingz/shade.py | 31 ++++++++++++++----------------- example.py | 2 +- 9 files changed, 77 insertions(+), 48 deletions(-) diff --git a/dingz/__init__.py b/dingz/__init__.py index ef370f8..8340a42 100644 --- a/dingz/__init__.py +++ b/dingz/__init__.py @@ -1,16 +1,24 @@ """Base details for the dingz Python bindings.""" + import asyncio import socket from typing import Any, Mapping, Optional import aiohttp import sys + if sys.version_info >= (3, 11): import asyncio as async_timeout else: import async_timeout -from .constants import TIMEOUT, USER_AGENT, CONTENT_TYPE_JSON, CONTENT_TYPE, CONTENT_TYPE_TEXT_PLAIN +from .constants import ( + TIMEOUT, + USER_AGENT, + CONTENT_TYPE_JSON, + CONTENT_TYPE, + CONTENT_TYPE_TEXT_PLAIN, +) from .exceptions import DingzConnectionError @@ -40,12 +48,21 @@ async def make_call( try: async with async_timeout.timeout(TIMEOUT): response = await self._session.request( - method, uri, data=data, json=json_data, params=parameters, headers=headers, + method, + uri, + data=data, + json=json_data, + params=parameters, + headers=headers, ) except asyncio.TimeoutError as exception: - raise DingzConnectionError("Timeout occurred while connecting to dingz unit") from exception + raise DingzConnectionError( + "Timeout occurred while connecting to dingz unit" + ) from exception except (aiohttp.ClientError, socket.gaierror) as exception: - raise DingzConnectionError("Error occurred while communicating with dingz") from exception + raise DingzConnectionError( + "Error occurred while communicating with dingz" + ) from exception if CONTENT_TYPE_JSON in response.headers.get(CONTENT_TYPE, ""): response_json = await response.json() diff --git a/dingz/cli.py b/dingz/cli.py index aa27b1a..394d72e 100644 --- a/dingz/cli.py +++ b/dingz/cli.py @@ -1,4 +1,5 @@ """Command-line interface to interact with dingz devices.""" + import asyncio from functools import wraps diff --git a/dingz/constants.py b/dingz/constants.py index 53f4e12..b038630 100644 --- a/dingz/constants.py +++ b/dingz/constants.py @@ -1,4 +1,5 @@ """Constants used by the Python API for interacting with dingz units.""" + import pkg_resources try: diff --git a/dingz/dimmer.py b/dingz/dimmer.py index dab1996..0b7e0b0 100644 --- a/dingz/dimmer.py +++ b/dingz/dimmer.py @@ -27,16 +27,16 @@ async def toggle(self, brightness_pct=100): await self.operate_light(action, brightness_pct) async def turn_on(self, brightness_pct=100): - """ Turn light on. + """Turn light on. :param brightness_pct: brightness in percent, or None. """ await self.operate_light("on", brightness_pct) async def turn_off(self): - """ Rurn light off.""" + """Rurn light off.""" await self.operate_light("off") - VALID_OPERATIONS = ('on', 'off') + VALID_OPERATIONS = ("on", "off") async def operate_light(self, action, brightness_pct=None): """ @@ -46,14 +46,20 @@ async def operate_light(self, action, brightness_pct=None): :return: """ if action not in Dimmer.VALID_OPERATIONS: - raise ValueError("invalid action %s, expected one of %s" % - (repr(action), repr(Dimmer.VALID_OPERATIONS))) + raise ValueError( + "invalid action %s, expected one of %s" + % (repr(action), repr(Dimmer.VALID_OPERATIONS)) + ) if brightness_pct is not None and (brightness_pct > 100 or brightness_pct < 0): - raise ValueError("invalid brightness_pct %s, expected value between 0 and 100" % - (repr(brightness_pct))) - - url = URL(self.dingz.uri).join(URL("%s/%s/%s" % (DIMMER, self.index_relative, action))) + raise ValueError( + "invalid brightness_pct %s, expected value between 0 and 100" + % (repr(brightness_pct)) + ) + + url = URL(self.dingz.uri).join( + URL("%s/%s/%s" % (DIMMER, self.index_relative, action)) + ) params = {} if brightness_pct is not None: params["value"] = str(brightness_pct) @@ -73,18 +79,18 @@ def _consume_state(self, state_details): :param state_details: :return: """ - assert self.absolute_index == state_details['index']['absolute'] + assert self.absolute_index == state_details["index"]["absolute"] self.seen_state = True - self.index_relative = state_details['index']['relative'] - self.on = state_details['on'] - self.brightness_pct = state_details['output'] + self.index_relative = state_details["index"]["relative"] + self.on = state_details["on"] + self.brightness_pct = state_details["output"] def _consume_config(self, config): # "output": "halogen", "name": "Dimmable 3", "feedback": null, "feedback_intensity": 10 - self.output = config['output'] - self.enabled = config['output'] != 'not_connected' - self.dimmable = config['output'] != 'non_dimmable' - self.name = config['name'] + self.output = config["output"] + self.enabled = config["output"] != "not_connected" + self.dimmable = config["output"] != "non_dimmable" + self.name = config["name"] class DimmerRegistry(BaseRegistry[Dimmer]): diff --git a/dingz/dingz.py b/dingz/dingz.py index d1cb0bf..21a5f18 100644 --- a/dingz/dingz.py +++ b/dingz/dingz.py @@ -1,4 +1,5 @@ """Python client/wrapper to interact with dingz devices.""" + import logging import aiohttp @@ -25,7 +26,8 @@ STATE, SYSTEM_CONFIG, BLIND_CONFIGURATION, - DIMMER_CONFIGURATION, SHADE, + DIMMER_CONFIGURATION, + SHADE, ) from .dimmer import DimmerRegistry from .shade import ShadeRegistry @@ -154,9 +156,9 @@ async def get_state(self) -> None: # first fetch the device state url = URL(self.uri).join(URL(STATE)) device_state = await make_call(self, uri=url) - self._consume_sensor_state(device_state['sensors']) - self._dimmers._consume_dimmer_state(device_state['dimmers']) - self._shades._consume_device_state(device_state['blinds']) + self._consume_sensor_state(device_state["sensors"]) + self._dimmers._consume_dimmer_state(device_state["dimmers"]) + self._shades._consume_device_state(device_state["blinds"]) self._state = device_state if len(self._shades.all()) > 0: @@ -169,13 +171,13 @@ async def get_blind_config(self) -> None: """Get the configuration of the blinds.""" url = URL(self.uri).join(URL(BLIND_CONFIGURATION)) response = await make_call(self, uri=url) - self._blind_config = response['blinds'] + self._blind_config = response["blinds"] async def get_dimmer_config(self) -> None: """Get the configuration of the dimmer/lights.""" url = URL(self.uri).join(URL(DIMMER_CONFIGURATION)) response = await make_call(self, uri=url) - self._dimmer_config = response['dimmers'] + self._dimmer_config = response["dimmers"] async def get_system_config(self) -> None: """Get the system configuration of a dingz.""" diff --git a/dingz/discovery.py b/dingz/discovery.py index 6326848..a8e828e 100644 --- a/dingz/discovery.py +++ b/dingz/discovery.py @@ -1,4 +1,5 @@ """Discover dingz devices in a network.""" + import asyncio import logging from typing import Optional, List @@ -66,7 +67,7 @@ class DiscoveryProtocol(asyncio.DatagramProtocol): """Representation of the discovery protocol.""" def __init__(self, registry: DeviceRegistry): - """"Initialize the discovery protocol.""" + """ "Initialize the discovery protocol.""" super().__init__() self.registry = registry @@ -108,6 +109,9 @@ async def discover_dingz_devices(timeout: int = 7) -> List[DiscoveredDevice]: devices = registry.devices() for device in devices: _LOGGER.debug( - "Discovered dingz %s (%s) (MAC address: %s)", device.host, device.type, device.mac + "Discovered dingz %s (%s) (MAC address: %s)", + device.host, + device.type, + device.mac, ) return devices diff --git a/dingz/registry.py b/dingz/registry.py index 284473b..805a165 100644 --- a/dingz/registry.py +++ b/dingz/registry.py @@ -4,7 +4,7 @@ def organize_by_absolute_index(items): result = [] for item in items: - result.append((item['index']['absolute'], item)) + result.append((item["index"]["absolute"], item)) return result @@ -21,6 +21,7 @@ class BaseRegistry(Generic[T]): Note, the absolute index remains the same, regardless of deactivation by the dip switch. So shade 1 is always the shade operated by output 2&3, even if it is the only shade. """ + _registry: Dict[int, T] def __init__(self, factory): diff --git a/dingz/shade.py b/dingz/shade.py index d9036a1..0ee6faf 100644 --- a/dingz/shade.py +++ b/dingz/shade.py @@ -2,9 +2,7 @@ from dingz import make_call -from .constants import ( - SHADE -) +from .constants import SHADE from .registry import BaseRegistry, organize_by_absolute_index @@ -19,7 +17,7 @@ def __init__(self, absolute_index, dingz): self.lamella = None def _consume_config(self, config): - self.name = config['name'] + self.name = config["name"] def _consume_device_state(self, state_details): """ @@ -29,12 +27,12 @@ def _consume_device_state(self, state_details): 'index': { 'relative': 0, 'absolute': 0 } } """ - assert self.absolute_index == state_details['index']['absolute'] - self.index_relative = state_details['index']['relative'] + assert self.absolute_index == state_details["index"]["absolute"] + self.index_relative = state_details["index"]["relative"] self.seen_state = True - self.moving = state_details['moving'] - self.position = state_details['position'] - self.lamella = state_details['lamella'] + self.moving = state_details["moving"] + self.position = state_details["position"] + self.lamella = state_details["lamella"] def _consume_shade_state(self, state_details): """ @@ -48,9 +46,9 @@ def _consume_shade_state(self, state_details): "index": { "relative": 1, "absolute": 1 } } """ - assert self.absolute_index == state_details['index']['absolute'] - self.position = state_details['current']['blind'] - self.lamella = state_details['current']['lamella'] + assert self.absolute_index == state_details["index"]["absolute"] + self.position = state_details["current"]["blind"] + self.lamella = state_details["current"]["lamella"] async def operate_shade(self, blind=None, lamella=None) -> None: """ @@ -112,7 +110,9 @@ async def lamella_stop(self) -> None: async def shade_command(self, verb): """Create a command for the shade.""" - url = URL(self.dingz.uri).join(URL("%s/%s/%s" % (SHADE, self.absolute_index, verb))) + url = URL(self.dingz.uri).join( + URL("%s/%s/%s" % (SHADE, self.absolute_index, verb)) + ) await make_call(self.dingz, uri=url, method="POST") def current_blind_level(self): @@ -126,10 +126,7 @@ def current_lamella_level(self): def is_shade_closed(self): """Get the closed state of a shade.""" # When closed, we care if the lamellas are opened or not - return ( - self.current_blind_level() == 0 - and self.current_lamella_level() == 0 - ) + return self.current_blind_level() == 0 and self.current_lamella_level() == 0 def is_shade_opened(self): """Get the open state of a shade.""" diff --git a/example.py b/example.py index e0d5411..152bbb8 100644 --- a/example.py +++ b/example.py @@ -1,4 +1,5 @@ """Sample code to use the wrapper for interacting with the dingz device.""" + import asyncio import logging @@ -22,7 +23,6 @@ async def main(): # Work with one dingz unit async with Dingz(IP_ADDRESS) as dingz: - # Collect the data of the current state await dingz.get_device_info() print("Device details:", dingz.device_details) From c6cf689c1b9f906b4557e8dd026f482e3848f61e Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Sun, 10 Aug 2025 16:06:40 +0000 Subject: [PATCH 06/21] feat: add Python 3.12 and 3.13 --- .github/workflows/python.yml | 2 +- pyproject.toml | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index ae6a14c..6c0c598 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -12,7 +12,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [ 3.9, "3.10", "3.11" ] + python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13" ] steps: - uses: actions/checkout@v4 diff --git a/pyproject.toml b/pyproject.toml index 2413ad4..334f89e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -19,6 +19,8 @@ classifiers = [ "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Topic :: Utilities", ] dependencies = [ From 09a9cce2209b4f1bd29b4ac4974f3dd505305ffb Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Sun, 10 Aug 2025 16:20:13 +0000 Subject: [PATCH 07/21] fix: DeprecationWarning: There is no current event loop --- example.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/example.py b/example.py index 152bbb8..c8db811 100644 --- a/example.py +++ b/example.py @@ -63,5 +63,4 @@ async def main(): if __name__ == "__main__": logging.basicConfig(level=logging.DEBUG) - loop = asyncio.get_event_loop() - loop.run_until_complete(main()) + asyncio.run(main()) From 959dbbcac860080903d9b4b39def565207493161 Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Sun, 10 Aug 2025 16:20:28 +0000 Subject: [PATCH 08/21] feat: drop setuptools dependency --- dingz/constants.py | 4 ++-- pyproject.toml | 1 - uv.lock | 11 ----------- 3 files changed, 2 insertions(+), 14 deletions(-) diff --git a/dingz/constants.py b/dingz/constants.py index b038630..6e4eb64 100644 --- a/dingz/constants.py +++ b/dingz/constants.py @@ -1,9 +1,9 @@ """Constants used by the Python API for interacting with dingz units.""" -import pkg_resources +import importlib.metadata try: - __version__ = pkg_resources.get_distribution("setuptools").version + __version__ = importlib.metadata.version("dingz") except Exception: __version__ = "unknown" diff --git a/pyproject.toml b/pyproject.toml index 334f89e..de7a5bc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,6 @@ dependencies = [ "aiohttp<4", "async-timeout>=5.0.1 ; python_full_version < '3.11'", "click>=8.1.8", - "setuptools>=80.9.0", ] [project.urls] diff --git a/uv.lock b/uv.lock index f4883c5..5a78818 100644 --- a/uv.lock +++ b/uv.lock @@ -197,7 +197,6 @@ dependencies = [ { name = "async-timeout", marker = "python_full_version < '3.11'" }, { name = "click", version = "8.1.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "click", version = "8.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, - { name = "setuptools" }, ] [package.dev-dependencies] @@ -210,7 +209,6 @@ requires-dist = [ { name = "aiohttp", specifier = "<4" }, { name = "async-timeout", marker = "python_full_version < '3.11'", specifier = ">=5.0.1" }, { name = "click", specifier = ">=8.1.8" }, - { name = "setuptools", specifier = ">=80.9.0" }, ] [package.metadata.requires-dev] @@ -586,15 +584,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/5c/799a1efb8b5abab56e8a9f2a0b72d12bd64bb55815e9476c7d0a2887d2f7/ruff-0.12.8-py3-none-win_arm64.whl", hash = "sha256:c90e1a334683ce41b0e7a04f41790c429bf5073b62c1ae701c9dc5b3d14f0749", size = 11884718, upload-time = "2025-08-07T19:05:42.866Z" }, ] -[[package]] -name = "setuptools" -version = "80.9.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, -] - [[package]] name = "typing-extensions" version = "4.14.1" From 0d10a704bb01aa83bf0d6ce12ba3aca6770f3433 Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Sun, 10 Aug 2025 19:50:27 +0000 Subject: [PATCH 09/21] feat: configure strict ruff linter rules --- pyproject.toml | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index de7a5bc..5628944 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,6 +44,28 @@ module-name = "dingz" module-root = "" [dependency-groups] -dev = [ - "ruff>=0.12.8", +dev = ["ruff>=0.12.8"] + +[tool.ruff] +line-length = 100 + +[tool.ruff.lint] +# See: +select = ["ALL"] +ignore = [ + "D203", # Use 'no-blank-line-before-class' instead of 'incorrect-blank-line-before-class' + "D213", # Use 'multi-line-summary-second-line' instead of 'multi-line-summary-first-line' + "COM812", # Formatter already enforces trailing commas + "S101", # Allow assert +] + +[tool.ruff.lint.pydocstyle] +convention = "pep257" + +[tool.ruff.lint.per-file-ignores] +"example.py" = [ + "T201", # Allow 'print' in example +] +"cli.py" = [ + "T201", # Allow 'print' in cli ] From 0748c4072ecc0090138fed90fe96b7ef1d267deb Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Mon, 11 Aug 2025 15:18:42 +0000 Subject: [PATCH 10/21] chore: apply automatic ruff fixes --- dingz/__init__.py | 37 +++++++++++++++++++------------------ dingz/cli.py | 38 ++++++++++++++------------------------ dingz/dimmer.py | 40 +++++++++++++++++----------------------- dingz/dingz.py | 30 ++++++++++++++---------------- dingz/discovery.py | 28 +++++++++++++++------------- dingz/exceptions.py | 6 ------ dingz/registry.py | 19 +++++++++---------- dingz/shade.py | 35 ++++++++++++++++------------------- example.py | 7 ++----- 9 files changed, 106 insertions(+), 134 deletions(-) diff --git a/dingz/__init__.py b/dingz/__init__.py index 8340a42..a45eabe 100644 --- a/dingz/__init__.py +++ b/dingz/__init__.py @@ -1,11 +1,13 @@ """Base details for the dingz Python bindings.""" +from __future__ import annotations + import asyncio import socket -from typing import Any, Mapping, Optional +import sys +from typing import TYPE_CHECKING, Any import aiohttp -import sys if sys.version_info >= (3, 11): import asyncio as async_timeout @@ -13,26 +15,28 @@ import async_timeout from .constants import ( - TIMEOUT, - USER_AGENT, - CONTENT_TYPE_JSON, CONTENT_TYPE, + CONTENT_TYPE_JSON, CONTENT_TYPE_TEXT_PLAIN, + TIMEOUT, + USER_AGENT, ) from .exceptions import DingzConnectionError +if TYPE_CHECKING: + from collections.abc import Mapping + async def make_call( self, uri: str, method: str = "GET", - data: Optional[Any] = None, - json_data: Optional[dict] = None, - parameters: Optional[Mapping[str, str]] = None, - token: str = None, + data: Any | None = None, + json_data: dict | None = None, + parameters: Mapping[str, str] | None = None, + token: str | None = None, ) -> Any: """Handle the requests to the dingz unit.""" - headers = { "User-Agent": USER_AGENT, "Accept": f"{CONTENT_TYPE_JSON}, {CONTENT_TYPE_TEXT_PLAIN}, */*", @@ -56,16 +60,13 @@ async def make_call( headers=headers, ) except asyncio.TimeoutError as exception: - raise DingzConnectionError( - "Timeout occurred while connecting to dingz unit" - ) from exception + msg = "Timeout occurred while connecting to dingz unit" + raise DingzConnectionError(msg) from exception except (aiohttp.ClientError, socket.gaierror) as exception: - raise DingzConnectionError( - "Error occurred while communicating with dingz" - ) from exception + msg = "Error occurred while communicating with dingz" + raise DingzConnectionError(msg) from exception if CONTENT_TYPE_JSON in response.headers.get(CONTENT_TYPE, ""): - response_json = await response.json() - return response_json + return await response.json() return response.text diff --git a/dingz/cli.py b/dingz/cli.py index 394d72e..c86c352 100644 --- a/dingz/cli.py +++ b/dingz/cli.py @@ -23,53 +23,47 @@ def wrapper(*args, **kwargs): @click.group() @click.version_option() -def main(): +def main() -> None: """Simple command-line tool to interact with dingz devices.""" @main.command("discover") @coro -async def discover(): +async def discover() -> None: """Read the current configuration of a myStrom device.""" click.echo("Waiting for UDP broadcast packages...") devices = await discover_dingz_devices() print(f"Found {len(devices)} devices") for device in devices: - print( - f" MAC address: {device.mac}, IP address: {device.host}, HW: {device.hardware}" - ) + print(f" MAC address: {device.mac}, IP address: {device.host}, HW: {device.hardware}") @main.group("info") -def info(): +def info() -> None: """Get the information of a dingz device.""" @info.command("config") @coro -@click.option( - "--ip", prompt="IP address of the device", help="IP address of the device." -) -async def get_config(ip): +@click.option("--ip", prompt="IP address of the device", help="IP address of the device.") +async def get_config(ip) -> None: """Read the current configuration of a myStrom device.""" - click.echo("Read configuration from %s" % ip) + click.echo(f"Read configuration from {ip}") async with Dingz(ip) as dingz: await dingz.get_device_info() click.echo(dingz.device_details) @main.group("front_led") -def front_led(): +def front_led() -> None: """Handle the front LED of dingz.""" @front_led.command("on") @coro -@click.option( - "--ip", prompt="IP address of the device", help="IP address of the device." -) -async def set_on(ip): +@click.option("--ip", prompt="IP address of the device", help="IP address of the device.") +async def set_on(ip) -> None: """Turn the front LED on.""" async with Dingz(ip) as dingz: await dingz.turn_on() @@ -77,10 +71,8 @@ async def set_on(ip): @front_led.command("off") @coro -@click.option( - "--ip", prompt="IP address of the device", help="IP address of the device." -) -async def set_off(ip): +@click.option("--ip", prompt="IP address of the device", help="IP address of the device.") +async def set_off(ip) -> None: """Turn the front LED off.""" async with Dingz(ip) as dingz: await dingz.turn_off() @@ -88,10 +80,8 @@ async def set_off(ip): @front_led.command("status") @coro -@click.option( - "--ip", prompt="IP address of the device", help="IP address of the device." -) -async def get_status(ip): +@click.option("--ip", prompt="IP address of the device", help="IP address of the device.") +async def get_status(ip) -> None: """Get the status of the front LED off.""" async with Dingz(ip) as dingz: click.echo(await dingz.enabled()) diff --git a/dingz/dimmer.py b/dingz/dimmer.py index 0b7e0b0..cbb89ae 100644 --- a/dingz/dimmer.py +++ b/dingz/dimmer.py @@ -5,8 +5,8 @@ from dingz.registry import BaseRegistry, organize_by_absolute_index -class Dimmer(object): - def __init__(self, absolute_index, dingz): +class Dimmer: + def __init__(self, absolute_index, dingz) -> None: self.dingz = dingz self.absolute_index = absolute_index self.on = None @@ -17,7 +17,7 @@ def __init__(self, absolute_index, dingz): self.name = None self.seen_state = False - async def toggle(self, brightness_pct=100): + async def toggle(self, brightness_pct=100) -> None: """ Toggle light (based on internal state). :param brightness_pct: brightness in percent, or None @@ -26,19 +26,19 @@ async def toggle(self, brightness_pct=100): action = "off" if self.on else "on" await self.operate_light(action, brightness_pct) - async def turn_on(self, brightness_pct=100): + async def turn_on(self, brightness_pct=100) -> None: """Turn light on. :param brightness_pct: brightness in percent, or None. """ await self.operate_light("on", brightness_pct) - async def turn_off(self): + async def turn_off(self) -> None: """Rurn light off.""" await self.operate_light("off") VALID_OPERATIONS = ("on", "off") - async def operate_light(self, action, brightness_pct=None): + async def operate_light(self, action, brightness_pct=None) -> None: """ Operate the light (turn it on or off). :param action: 'on' or 'off' @@ -46,20 +46,14 @@ async def operate_light(self, action, brightness_pct=None): :return: """ if action not in Dimmer.VALID_OPERATIONS: - raise ValueError( - "invalid action %s, expected one of %s" - % (repr(action), repr(Dimmer.VALID_OPERATIONS)) - ) + msg = f"invalid action {action!r}, expected one of {Dimmer.VALID_OPERATIONS!r}" + raise ValueError(msg) if brightness_pct is not None and (brightness_pct > 100 or brightness_pct < 0): - raise ValueError( - "invalid brightness_pct %s, expected value between 0 and 100" - % (repr(brightness_pct)) - ) - - url = URL(self.dingz.uri).join( - URL("%s/%s/%s" % (DIMMER, self.index_relative, action)) - ) + msg = f"invalid brightness_pct {brightness_pct!r}, expected value between 0 and 100" + raise ValueError(msg) + + url = URL(self.dingz.uri).join(URL(f"{DIMMER}/{self.index_relative}/{action}")) params = {} if brightness_pct is not None: params["value"] = str(brightness_pct) @@ -69,7 +63,7 @@ async def operate_light(self, action, brightness_pct=None): if brightness_pct is not None: self.brightness_pct = brightness_pct - def _consume_state(self, state_details): + def _consume_state(self, state_details) -> None: """ Example for state_details: { @@ -85,7 +79,7 @@ def _consume_state(self, state_details): self.on = state_details["on"] self.brightness_pct = state_details["output"] - def _consume_config(self, config): + def _consume_config(self, config) -> None: # "output": "halogen", "name": "Dimmable 3", "feedback": null, "feedback_intensity": 10 self.output = config["output"] self.enabled = config["output"] != "not_connected" @@ -94,15 +88,15 @@ def _consume_config(self, config): class DimmerRegistry(BaseRegistry[Dimmer]): - def __init__(self, dingz): + def __init__(self, dingz) -> None: super().__init__(factory=lambda absolute_index: Dimmer(absolute_index, dingz)) - def _consume_config(self, dimmer_configs): + def _consume_config(self, dimmer_configs) -> None: for absolute_index, dimmer_config in enumerate(dimmer_configs): dimmer = self._get_or_create(absolute_index) dimmer._consume_config(dimmer_config) - def _consume_dimmer_state(self, dimmer_states): + def _consume_dimmer_state(self, dimmer_states) -> None: for absolute_index, dimmer_state in organize_by_absolute_index(dimmer_states): dimmer = self._get_or_create(absolute_index) dimmer._consume_state(dimmer_state) diff --git a/dingz/dingz.py b/dingz/dingz.py index 21a5f18..4628076 100644 --- a/dingz/dingz.py +++ b/dingz/dingz.py @@ -8,26 +8,26 @@ from . import make_call from .constants import ( API, + BLIND_CONFIGURATION, BUTTON_ACTIONS, DEVICE_INFO, + DIMMER_CONFIGURATION, FRONT_LED_GET, FRONT_LED_SET, + INFO, INPUT_CONFIGURATION, LIGHT, PIR_CONFIGURATION, PUCK, + SCHEDULE, SETTINGS, + SHADE, + STATE, + SYSTEM_CONFIG, TEMPERATURE, THERMOSTAT_CONFIGURATION, - WIFI_SCAN, TIMER, - SCHEDULE, - INFO, - STATE, - SYSTEM_CONFIG, - BLIND_CONFIGURATION, - DIMMER_CONFIGURATION, - SHADE, + WIFI_SCAN, ) from .dimmer import DimmerRegistry from .shade import ShadeRegistry @@ -122,7 +122,7 @@ async def get_configuration(self, part) -> None: "thermostat": THERMOSTAT_CONFIGURATION, "input": INPUT_CONFIGURATION, } - url_part = [value for key, value in urls.items() if part in key][0] + url_part = next(value for key, value in urls.items() if part in key) url = URL(self.uri).join(URL(url_part)) self._configuration = await make_call(self, uri=url) @@ -144,7 +144,7 @@ async def get_light(self) -> None: self._intensity = response["intensity"] self._hour_of_day = response["state"] - def _consume_sensor_state(self, response): + def _consume_sensor_state(self, response) -> None: self._intensity = response["brightness"] self._hour_of_day = response["light_state"] self._temperature = response["room_temperature"] @@ -152,7 +152,6 @@ def _consume_sensor_state(self, response): async def get_state(self) -> None: """Fetch the current state and update the different internal representations.""" - # first fetch the device state url = URL(self.uri).join(URL(STATE)) device_state = await make_call(self, uri=url) @@ -222,7 +221,6 @@ async def turn_off(self) -> None: async def set_timer(self, data) -> None: """Set a timer.""" - print(data) url = URL(self.uri).join(URL(TIMER)) await make_call(self, uri=url, method="POST", json_data=data) @@ -234,8 +232,8 @@ async def stop_timer(self, data) -> None: @property def shades(self) -> ShadeRegistry: """ - test - :return: a ShadeRegistry + Test + :return: a ShadeRegistry. """ return self._shades @@ -301,12 +299,12 @@ def motion(self) -> bool: @property def day(self) -> bool: """Return true if the sensor thinks it's day.""" - return True if self._hour_of_day == "day" else False + return self._hour_of_day == "day" @property def night(self) -> bool: """Return true if the sensor thinks it's night.""" - return True if self._hour_of_day == "night" else False + return self._hour_of_day == "night" @property def intensity(self) -> float: diff --git a/dingz/discovery.py b/dingz/discovery.py index a8e828e..26c2a74 100644 --- a/dingz/discovery.py +++ b/dingz/discovery.py @@ -1,15 +1,16 @@ """Discover dingz devices in a network.""" +from __future__ import annotations + import asyncio import logging -from typing import Optional, List from .constants import DEVICE_MAPPING _LOGGER = logging.getLogger(__name__) -class DiscoveredDevice(object): +class DiscoveredDevice: """Representation of discovered device.""" mac: str @@ -24,7 +25,8 @@ def create_from_announce_msg(raw_addr, announce_msg): """Create announce message.""" _LOGGER.debug("Received announce message '%s' from %s ", announce_msg, raw_addr) if len(announce_msg) != 8: - raise RuntimeError("Unexpected announcement, '%s'" % announce_msg) + msg = f"Unexpected announcement, '{announce_msg}'" + raise RuntimeError(msg) device = DiscoveredDevice(host=raw_addr[0], mac=announce_msg[0:6].hex(":")) device.type = announce_msg[6] @@ -41,53 +43,53 @@ def create_from_announce_msg(raw_addr, announce_msg): device.restarted = status & 8 != 0 return device - def __init__(self, host, mac): + def __init__(self, host, mac) -> None: """Initialize the discovery.""" self.host = host self.mac = mac -class DeviceRegistry(object): +class DeviceRegistry: """Representation of the device registry.""" - def __init__(self): + def __init__(self) -> None: """Initialize the device registry.""" self.devices_by_mac = {} - def register(self, device): + def register(self, device) -> None: """Register a device.""" self.devices_by_mac[device.mac] = device def devices(self): - """Get all present devices""" + """Get all present devices.""" return list(self.devices_by_mac.values()) class DiscoveryProtocol(asyncio.DatagramProtocol): """Representation of the discovery protocol.""" - def __init__(self, registry: DeviceRegistry): + def __init__(self, registry: DeviceRegistry) -> None: """ "Initialize the discovery protocol.""" super().__init__() self.registry = registry - def connection_made(self, transport): + def connection_made(self, transport) -> None: """Create an UDP listener.""" _LOGGER.debug("Starting up UDP listener") self.transport = transport - def datagram_received(self, data, addr): + def datagram_received(self, data, addr) -> None: """Handle a datagram.""" device = DiscoveredDevice.create_from_announce_msg(addr, data) self.registry.register(device) - def connection_lost(self, exc: Optional[Exception]) -> None: + def connection_lost(self, exc: Exception | None) -> None: """Stop if connection is lost.""" _LOGGER.debug("Shutting down UDP listener") super().connection_lost(exc) -async def discover_dingz_devices(timeout: int = 7) -> List[DiscoveredDevice]: +async def discover_dingz_devices(timeout: int = 7) -> list[DiscoveredDevice]: """ Try to discover all local dingz instances. All dingz instances report their presence every ~5 seconds in an UDP broadcast to port 7979. diff --git a/dingz/exceptions.py b/dingz/exceptions.py index 7054801..e9ad442 100644 --- a/dingz/exceptions.py +++ b/dingz/exceptions.py @@ -4,16 +4,10 @@ class DingzError(Exception): """General dingz exception occurred.""" - pass - class DingzConnectionError(DingzError): """When a connection error is encountered.""" - pass - class DingzNoDataAvailable(DingzError): """When no data is available.""" - - pass diff --git a/dingz/registry.py b/dingz/registry.py index 805a165..2a907cf 100644 --- a/dingz/registry.py +++ b/dingz/registry.py @@ -1,4 +1,6 @@ -from typing import Generic, TypeVar, List, Dict, Optional +from __future__ import annotations + +from typing import Generic, TypeVar def organize_by_absolute_index(items): @@ -22,9 +24,9 @@ class BaseRegistry(Generic[T]): So shade 1 is always the shade operated by output 2&3, even if it is the only shade. """ - _registry: Dict[int, T] + _registry: dict[int, T] - def __init__(self, factory): + def __init__(self, factory) -> None: """ :param factory: call that is being used to create new instances, will be given the key as argument: @@ -36,7 +38,7 @@ def __init__(self, factory): self._registry = {} self._factory = factory - def get(self, absolute_index) -> Optional[T]: + def get(self, absolute_index) -> T | None: """ Get object in this registry by absolute_index. :param absolute_index: see BaseRegistry class docstring a for a definition of the absolute index @@ -46,13 +48,10 @@ def get(self, absolute_index) -> Optional[T]: obj = self._get_or_create(absolute_index) if obj.seen_state: return obj - else: - return None + return None - def all(self) -> List[T]: - """ - Return all known dimmers/shades. - """ + def all(self) -> list[T]: + """Return all known dimmers/shades.""" return [o for o in self._registry.values() if o.seen_state] def _get_or_create(self, absolute_index) -> T: diff --git a/dingz/shade.py b/dingz/shade.py index 0ee6faf..c3b6d63 100644 --- a/dingz/shade.py +++ b/dingz/shade.py @@ -6,8 +6,8 @@ from .registry import BaseRegistry, organize_by_absolute_index -class Shade(object): - def __init__(self, absolute_index, dingz): +class Shade: + def __init__(self, absolute_index, dingz) -> None: self.absolute_index = absolute_index self.dingz = dingz self.name = None @@ -16,16 +16,16 @@ def __init__(self, absolute_index, dingz): self.position = None self.lamella = None - def _consume_config(self, config): + def _consume_config(self, config) -> None: self.name = config["name"] - def _consume_device_state(self, state_details): + def _consume_device_state(self, state_details) -> None: """ Update internal state based on server respnose. Eaxmple for state_details: { 'moving': 'stop', 'position': 0, 'lamella': 0, 'readonly': False, 'index': { 'relative': 0, 'absolute': 0 } - } + }. """ assert self.absolute_index == state_details["index"]["absolute"] self.index_relative = state_details["index"]["relative"] @@ -34,7 +34,7 @@ def _consume_device_state(self, state_details): self.position = state_details["position"] self.lamella = state_details["lamella"] - def _consume_shade_state(self, state_details): + def _consume_shade_state(self, state_details) -> None: """ We consume the shade state to get the current position of the shade during movement. @@ -44,7 +44,7 @@ def _consume_shade_state(self, state_details): "current": { "blind": 18, "lamella": 100 }, "disabled": false, "index": { "relative": 1, "absolute": 1 } - } + }. """ assert self.absolute_index == state_details["index"]["absolute"] self.position = state_details["current"]["blind"] @@ -57,13 +57,12 @@ async def operate_shade(self, blind=None, lamella=None) -> None: blind: 0 fully closed, 100 fully open lamella: 0 lamellas closed, 100 lamellas open """ - # With newer versions of dingz, we can just leave # either lamella or blind None (i.e. do not chang) # but currently we need to lookup the current state # of the shade first. if blind is None or lamella is None: - # todo check v1.2 + # TODO check v1.2 await self.dingz.get_state() if blind is None: @@ -80,7 +79,7 @@ async def operate_shade(self, blind=None, lamella=None) -> None: else: lamella = self.current_lamella_level() - url = URL(self.dingz.uri).join(URL("%s/%s" % (SHADE, self.absolute_index))) + url = URL(self.dingz.uri).join(URL(f"{SHADE}/{self.absolute_index}")) params = {"blind": str(blind), "lamella": str(lamella)} await make_call(self.dingz, uri=url, method="POST", parameters=params) @@ -108,11 +107,9 @@ async def lamella_stop(self) -> None: """Stop the lamella.""" await self.shade_stop() - async def shade_command(self, verb): + async def shade_command(self, verb) -> None: """Create a command for the shade.""" - url = URL(self.dingz.uri).join( - URL("%s/%s/%s" % (SHADE, self.absolute_index, verb)) - ) + url = URL(self.dingz.uri).join(URL(f"{SHADE}/{self.absolute_index}/{verb}")) await make_call(self.dingz, uri=url, method="POST") def current_blind_level(self): @@ -149,7 +146,7 @@ def is_shade_closing(self): return self.moving == "down" def is_moving(self): - """Get whether the shade is moving""" + """Get whether the shade is moving.""" return self.is_shade_opening() or self.is_shade_closing() def shade_name(self, shade_no): @@ -158,20 +155,20 @@ def shade_name(self, shade_no): class ShadeRegistry(BaseRegistry[Shade]): - def __init__(self, dingz): + def __init__(self, dingz) -> None: super().__init__(factory=lambda absolute_index: Shade(absolute_index, dingz)) - def _consume_config(self, blind_configs): + def _consume_config(self, blind_configs) -> None: for absolute_index, shade_config in enumerate(blind_configs): shade = self._get_or_create(absolute_index) shade._consume_config(shade_config) - def _consume_device_state(self, device_states): + def _consume_device_state(self, device_states) -> None: for absolute_index, state in organize_by_absolute_index(device_states): shade = self._get_or_create(absolute_index) shade._consume_device_state(state) - def _consume_shade_state(self, shade_states): + def _consume_shade_state(self, shade_states) -> None: for absolute_index, shade_state in organize_by_absolute_index(shade_states): shade = self._get_or_create(absolute_index) shade._consume_shade_state(shade_state) diff --git a/example.py b/example.py index c8db811..b0f3226 100644 --- a/example.py +++ b/example.py @@ -6,20 +6,17 @@ from dingz.dingz import Dingz from dingz.discovery import discover_dingz_devices - IP_ADDRESS = "192.168.0.103" -async def main(): +async def main() -> None: """Sample code to work with a dingz unit.""" # Discover dingz devices devices = await discover_dingz_devices() print(f"Found {len(devices)} devices") for device in devices: - print( - f" MAC address: {device.mac}, IP address: {device.host}, HW: {device.hardware}" - ) + print(f" MAC address: {device.mac}, IP address: {device.host}, HW: {device.hardware}") # Work with one dingz unit async with Dingz(IP_ADDRESS) as dingz: From b48c23db5e2b737a49ebe5150d55d0591616dc8e Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Mon, 11 Aug 2025 15:21:58 +0000 Subject: [PATCH 11/21] feat: add low level rest client --- dingz/py.typed | 0 dingz/rest/__init__.py | 33 +++++ dingz/rest/_client.py | 143 ++++++++++++++++++++++ dingz/rest/_types.py | 266 +++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 1 + 5 files changed, 443 insertions(+) create mode 100644 dingz/py.typed create mode 100644 dingz/rest/__init__.py create mode 100644 dingz/rest/_client.py create mode 100644 dingz/rest/_types.py diff --git a/dingz/py.typed b/dingz/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/dingz/rest/__init__.py b/dingz/rest/__init__.py new file mode 100644 index 0000000..1223ad1 --- /dev/null +++ b/dingz/rest/__init__.py @@ -0,0 +1,33 @@ +"""Low-level REST client for the dingz API.""" + +from ._client import RestClient +from ._types import ( + Date, + Device, + DynLightState, + LedState, + LightState, + NetworkInfo, + PirSensorState, + PowerOutputSensorState, + SensorsState, + State, + ThermostatState, + WifiState, +) + +__all__ = [ + "Date", + "Device", + "DynLightState", + "LedState", + "LightState", + "NetworkInfo", + "PirSensorState", + "PowerOutputSensorState", + "RestClient", + "SensorsState", + "State", + "ThermostatState", + "WifiState", +] diff --git a/dingz/rest/_client.py b/dingz/rest/_client.py new file mode 100644 index 0000000..233686c --- /dev/null +++ b/dingz/rest/_client.py @@ -0,0 +1,143 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING, Any, Literal + +import aiohttp +from typing_extensions import Self +from yarl import URL + +from dingz.constants import CONTENT_TYPE_JSON, CONTENT_TYPE_TEXT_PLAIN, USER_AGENT + +if TYPE_CHECKING: + from types import TracebackType + + from ._types import Device, NetworkInfo, State + + +class RestClient: + """Low-level REST client for the dingz API. + + This class can be used as a context manager. + """ + + def __init__( + self, + /, + host: str | URL, + *, + session: aiohttp.ClientSession | None = None, + session_owner: bool = False, + ) -> None: + """Initialize the REST client. + + Args: + host: The hostname or base URL for the API. + session: An existing aiohttp ClientSession to use. If None, a new session will be + created. Defaults to None. + session_owner: Indicates whether this client owns the session and is responsible for + closing it. Ignored if no session is provided. Defaults to False. + + """ + if session is None: + self._session = aiohttp.ClientSession( + connector=aiohttp.TCPConnector( + ssl=False, + ) + ) + self._session_owner = True + else: + self._session = session + self._session_owner = session_owner + + self._base_url = host if isinstance(host, URL) else URL.build(scheme="http", host=host) + self._headers = { + "User-Agent": USER_AGENT, + "Accept": f"{CONTENT_TYPE_JSON}, {CONTENT_TYPE_TEXT_PLAIN}, */*", + } + self._timeout = aiohttp.ClientTimeout(total=10.0) + + def __str__(self) -> str: + return f"{self.__class__.__name__}(host={self._base_url!r})" + + async def __aenter__(self) -> Self: + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + await self.close() + + async def close(self) -> None: + """Close the REST client. + + If the underlying session is owned by this client, it will be closed. + """ + if self._session_owner: + await self._session.close() + + async def _request(self, method: Literal["GET"], endpoint: URL) -> Any: # noqa: ANN401 The return value really could be anything! + async with self._session.request( + method, + self._base_url.join(endpoint), + headers=self._headers, + timeout=self._timeout, + ) as resp: + resp.raise_for_status() + return await resp.json() + + async def get_firmware_version(self) -> str: + """Get the firmware version of the dingz device. + + This function is designed to be robust against version changes. + It attempts to get the firmware version from several sources. + """ + + async def from_network_info() -> str: + nw_info = await self.get_network_info() + return nw_info["version"] + + async def from_device() -> str: + device = await self.get_device() + return device["fw_version"] + + exc: Exception | None = None + for fn in [from_network_info, from_device]: + try: + return await fn() + # We want to be robust against any kind of error in this function + except Exception as err: # noqa: BLE001, PERF203 + if exc is not None: + exc.__cause__ = err + exc = err + + assert exc is not None, "We always make at least one attempt" + raise exc + + async def get_device(self) -> Device: + """Get device information. + + This includes device configuration, hardware / software version, manufacturing dates and + other details. + """ + # The endpoint actually returns a map of -> Device. + # The id isn't the mac or either of the serial numbers. + devices: dict[str, Device] = await self._request("GET", URL("/api/v1/device")) + assert len(devices) == 1, "Expected exactly one device in the response" + device_id, device = next(iter(devices.items())) + device["device_id"] = device_id # Add the device id to the device data + return device + + async def get_network_info(self) -> NetworkInfo: + """Get general network settings.""" + return await self._request("GET", URL("/api/v1/info")) + + async def get_state(self) -> State: + """Get the full dingz status. + + Includes the following modules: dimmer, led, sensors, dynamic light, thermostat, wifi and + cloud. + """ + return await self._request("GET", URL("/api/v1/state")) diff --git a/dingz/rest/_types.py b/dingz/rest/_types.py new file mode 100644 index 0000000..39a7aa4 --- /dev/null +++ b/dingz/rest/_types.py @@ -0,0 +1,266 @@ +from __future__ import annotations + +from typing import Literal + +from typing_extensions import NotRequired, TypedDict + + +class Index(TypedDict, total=True): + """Index information of a dingz sub-component.""" + + relative: int + """The relative index of dimmer (depending on DIP switch configuration). + + Use this index to refer to component for actions. + """ + absolute: int + """The absolute index. Refers to hardware output number.""" + + +LightState = Literal["day", "twilight", "night"] + + +class Date(TypedDict, total=True): + """Split date information part of `Device`.""" + + year: int + month: int + day: int + + +class Device(TypedDict, total=True): + """Device information returned by the `/api/v1/device` endpoint.""" + + type: Literal["dingz"] + device_id: str + """User-settable identifier of the device. + + This field isn't present in the API model itself. The actual API response is a + `dict[str, Device]` with a single entry. The key is the device id. + """ + battery: bool + reachable: bool + meshroot: bool + fw_version: str + hw_version: str + fw_version_puck: str + bl_version_puck: str + hw_version_puck: str + hw_id_puck: int + puck_sn: str + puck_production_date: Date + ddi_base: bool + dip_config: int + dip_static: bool + dip_misconf: bool + puck_hw_model: Literal["DZ1B-4CH", ""] # TODO: incomplete + """Puck hardware model. + + Can be an empty string if unknown. + """ + front_hw_model: NotRequired[Literal["dz1f-pir", "dz1f-4b"]] # TODO: incomplete + """Front hardware model. + + Can be missing. + """ + front_production_date: NotRequired[str] + """Front production date. + + Format: `DD/MM/YY` + + Can be missing. + """ + front_sn: NotRequired[str] + """Front serial number. + + Can be missing. + """ + front_color: str + has_pir: bool + first_boot: bool + hash: str + + +class NetworkInfo(TypedDict, total=True): + """Network information returned by the `/api/v1/info` endpoint.""" + + version: str + """Version of the front.""" + mac: str + """MAC Address""" + type: Literal[108] # TODO: incomplete? + ssid: str + ip: str + mask: str + gw: str + dns: str + static: bool + connected: bool + + +class DimmerState(TypedDict, total=True): + """Dimmer status part of `State`.""" + + on: bool + """Dimmer status, on/off""" + output: int + """The dim value set on dimmer. This value is "0" if `on` is false.""" + ramp: int + """The ramp (how quickly change dim value) set on dimmer. + + The ramp is always 0 for non dimmable outputs. + """ + readonly: bool + """Whether the dimmer is disabled or not.""" + off_timer_type: Literal["none", "pir"] # TODO: incomplete + off_timer_id: int + off_timer_value: int + index: Index + + +# TODO CHECK +class BlindState(TypedDict, total=True): + """Blind status part of `State`.""" + + moving: Literal["up", "down", "stop"] + position: int + """closed = 0, open = 100""" + lamella: int + """closed = 0, open = 100""" + readonly: bool + index: Index + + +# TODO CHECK +class DdiChannelState(TypedDict, total=True): + """DDI Channel status part of `State`.""" + + name: str + en: bool + on: bool + brightness: int + ct_enabled: bool + colour_temperature: int + colour_temperature_k: int + off_timer_type: str + off_timer_id: int + off_timer_value: int + + +class LedState(TypedDict, total=True): + """LED status part of `State`.""" + + on: bool + """Whether or not the LED is on.""" + hsv: str + rgb: str + mode: Literal["hsv", "rgb"] + """Color format used by LED.""" + ramp: int + """Defines ramp/fade speed of color change (change from previous to new value). + + Range: `[0, 102375]` + """ + override_level: int + + +class PirSensorState(TypedDict, total=True): + """PIR sensor status part of `SensorsState`.""" + + enabled: bool + motion: bool + mode: Literal["idle"] # TODO: INCOMPLETE + light_off_timer: int + suspend_timer: int + + +class PowerOutputSensorState(TypedDict, total=True): + """Power output sensor status part of `SensorsState`.""" + + value: float + + +class SensorsState(TypedDict, total=True): + """Sensors status part of `State`.""" + + brightness: int + light_state: LightState + light_state_lpf: LightState + room_temperature: float + uncompensated_temperature: float + temp_offset: float + cpu_temperature: float + puck_temperature: float + fet_temperature: float + input_state: bool | None + pirs: list[PirSensorState | None] + """PIR sensor states. + + Only the first value seems to be relevant. + The first value will be `None` if the device does not have a PIR sensor. + """ + power_outputs: list[PowerOutputSensorState] + + +class DynLightState(TypedDict, total=True): + """Dyn light status part of `State`.""" + + mode: LightState + + +class ThermostatState(TypedDict, total=True): + """Thermostat status part of `State`.""" + + active: bool + state: Literal["off"] # TODO: incomplete + mode: Literal["off"] # TODO: incomplete + user_mode: Literal["comfort"] # TODO: incomplete + enabled: bool + target_temp: int + min_target_temp: int + max_target_temp: int + cooling: bool + free_cooling: bool + temp: float + + +class WifiState(TypedDict, total=True): + """Wifi status part of `State`.""" + + version: str + mac: str + ssid: str + ip: str + mask: str + gateway: str + dns: str + static: bool + connected: bool + + +class CloudState(TypedDict, total=True): + """Cloud status part of `State`.""" + + aws: Literal["connected", "disconnected"] # TODO: incomplete + + +class ConfigState(TypedDict, total=True): + """Config status part of `State`.""" + + timestamp: int + + +class State(TypedDict, total=True): + """Full device status returned by the `/api/v1/state` endpoint.""" + + dimmers: list[DimmerState] + blinds: list[BlindState] + ddi_channels: list[DdiChannelState] + led: LedState + sensors: SensorsState + dyn_light: DynLightState + thermostat: ThermostatState + wifi: WifiState + cloud: CloudState + time: str + config: ConfigState diff --git a/pyproject.toml b/pyproject.toml index 5628944..fd191f7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,6 +3,7 @@ name = "dingz" version = "0.6.0.dev0" authors = [ { name = "Fabian Affolter", email = "fabian@affolter-engineering.ch" }, + { name = "Simon Berger", email = "simon@siku2.io" }, ] description = "Python API for interacting with Dingz devices" readme = "README.rst" From eaafcf919f0b3f8c452e80c16ca67fd3a75b74ae Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Mon, 11 Aug 2025 17:19:55 +0000 Subject: [PATCH 12/21] feat: update discovery to use zeroconf --- dingz/discovery.py | 301 +++++++++++++++++++++++++++++++-------------- pyproject.toml | 2 + 2 files changed, 213 insertions(+), 90 deletions(-) diff --git a/dingz/discovery.py b/dingz/discovery.py index 26c2a74..9e296e4 100644 --- a/dingz/discovery.py +++ b/dingz/discovery.py @@ -1,119 +1,240 @@ -"""Discover dingz devices in a network.""" +"""Dingz discovery. + +The discovery is based on mDNS. +dingz devices announce a HTTP local TXT service on port 80 over mDNS. Hostname is always in +the form of `DINGZ--`. +Eg.: `DINGZ-dz1f-4b-30C6F72355C4.local TXT` +""" from __future__ import annotations import asyncio +import dataclasses import logging - -from .constants import DEVICE_MAPPING +from contextlib import AbstractAsyncContextManager, asynccontextmanager +from typing import TYPE_CHECKING + +from typing_extensions import Self +from zeroconf import ServiceInfo, ServiceListener, Zeroconf +from zeroconf.asyncio import ( + AsyncServiceBrowser, + AsyncServiceInfo, + AsyncZeroconf, +) + +if TYPE_CHECKING: + from collections.abc import AsyncIterator, Callable, Mapping + from types import TracebackType + +__all__ = [ + "Discovery", + "Properties", + "discover", + "discover_list", +] _LOGGER = logging.getLogger(__name__) +_DINGZ_NAME_PREFIX = "DINGZ " +_DEFAULT_HTTP_PORT = 80 + -class DiscoveredDevice: - """Representation of discovered device.""" +@dataclasses.dataclass(frozen=True) +class Properties: + """Properties of a discovered dingz device.""" + fw_version: str + """The firmware version of the device.""" + protected: bool + """Whether the device is protected.""" + pir: bool + """Whether the device has a PIR.""" + id: str + """Dingz ID. + + This is different from the serial number and can be set by the user. + """ + home_name: str + """User provided home name.""" + room_name: str + """User provided room name.""" + device_name: str + """User provided device name.""" mac: str - type: int - is_child: bool - mystrom_registered: bool - mystrom_online: bool - restarted: bool - - @staticmethod - def create_from_announce_msg(raw_addr, announce_msg): - """Create announce message.""" - _LOGGER.debug("Received announce message '%s' from %s ", announce_msg, raw_addr) - if len(announce_msg) != 8: - msg = f"Unexpected announcement, '{announce_msg}'" - raise RuntimeError(msg) - - device = DiscoveredDevice(host=raw_addr[0], mac=announce_msg[0:6].hex(":")) - device.type = announce_msg[6] - try: - device.hardware = DEVICE_MAPPING[str(announce_msg[6])] - except KeyError: - device.hardware = "unknown" - status = announce_msg[7] + """Mac address of the device.""" + + @classmethod + def from_zeroconf_properties(cls, props: Mapping[str, str | None]) -> Self: + """Read the properties from a zeroconf discovery.""" + return cls( + fw_version=str(props["fw"]), + protected=props["protected"] == "true", + pir=props["pir"] == "true", + id=str(props["id"]), + home_name=str(props["home"]), + room_name=str(props["room"]), + device_name=str(props["name"]), + mac=str(props["mac"]), + ) - # Parse status field - device.is_child = status & 1 != 0 - device.mystrom_registered = status & 2 != 0 - device.mystrom_online = status & 4 != 0 - device.restarted = status & 8 != 0 - return device - def __init__(self, host, mac) -> None: - """Initialize the discovery.""" - self.host = host - self.mac = mac +@dataclasses.dataclass(frozen=True) +class Discovery: + """A discovered dingz device.""" + host: str + """Host address of the device.""" + props: Properties + """Properties of the discovered device.""" -class DeviceRegistry: - """Representation of the device registry.""" + @classmethod + def from_service_info(cls, info: ServiceInfo) -> Self: + """Create a Discovery instance from a ServiceInfo instance.""" + props = Properties.from_zeroconf_properties(info.decoded_properties) + addresses = info.parsed_addresses() + if not addresses: + msg = "ServiceInfo has no parsed addresses" + raise ValueError(msg) + host = addresses[0] + if info.port != _DEFAULT_HTTP_PORT: + host = f"{host}:{info.port}" - def __init__(self) -> None: - """Initialize the device registry.""" - self.devices_by_mac = {} + return cls(host=host, props=props) - def register(self, device) -> None: - """Register a device.""" - self.devices_by_mac[device.mac] = device - def devices(self): - """Get all present devices.""" - return list(self.devices_by_mac.values()) +async def discover_list(duration: float = 10.0) -> list[Discovery]: + """Discover dingz devices on the network. + This is a simpler version of the more flexible `discover` function. -class DiscoveryProtocol(asyncio.DatagramProtocol): - """Representation of the discovery protocol.""" + Args: + duration: The duration to listen for devices (in seconds). - def __init__(self, registry: DeviceRegistry) -> None: - """ "Initialize the discovery protocol.""" - super().__init__() - self.registry = registry + Returns: + A list of discovered dingz devices. + """ + discoveries: list[Discovery] = [] + + def callback(discovery: Discovery) -> None: + discoveries.append(discovery) - def connection_made(self, transport) -> None: - """Create an UDP listener.""" - _LOGGER.debug("Starting up UDP listener") - self.transport = transport + async with _discover_with_callback(callback, timeout=duration) as _: + await asyncio.sleep(duration) + return discoveries - def datagram_received(self, data, addr) -> None: - """Handle a datagram.""" - device = DiscoveredDevice.create_from_announce_msg(addr, data) - self.registry.register(device) - def connection_lost(self, exc: Exception | None) -> None: - """Stop if connection is lost.""" - _LOGGER.debug("Shutting down UDP listener") - super().connection_lost(exc) +def discover( + *, + duration: float | None = None, + timeout: float = 10.0, +) -> AbstractAsyncContextManager[AsyncIterator[Discovery]]: + """Discover dingz devices on the network. + This function is an async context manager. Entering it starts the discovery process and returns + an async iterator which yields the discoveries as they are made. -async def discover_dingz_devices(timeout: int = 7) -> list[DiscoveredDevice]: + Consider using the `discover_list` function with a simpler interface if you don't need to get + discoveries in real-time. + + Args: + duration: The time in seconds to perform discovery. `None` means forever (or until the + context manager is exited). Any pending discoveries will still be yielded. + timeout: Timeout for requesting service info from a discovered device. This is an advanced + parameter and likely doesn't need to be changed. + + Example: + async with discover() as discoveries: + async for discovery in discoveries: + print(discovery) """ - Try to discover all local dingz instances. All dingz instances - report their presence every ~5 seconds in an UDP broadcast to port 7979. + loop = asyncio.get_running_loop() + queue: asyncio.Queue[Discovery | None] = asyncio.Queue() + + async def reader() -> AsyncIterator[Discovery]: + while True: + item = await queue.get() + # 'None' signals the end of discovery + if item is None: + break + yield item + + @asynccontextmanager + async def _discover() -> AsyncIterator[AsyncIterator[Discovery]]: + handle: asyncio.TimerHandle | None = None + if duration is not None: + # Add 'None' to the queue to signal the end of discovery + handle = loop.call_later(duration, queue.put_nowait, None) + + try: + async with _discover_with_callback(queue.put_nowait, timeout=timeout): + yield reader() + finally: + # Clean up timer handle if we started one + if handle is not None: + handle.cancel() + + return _discover() - :param timeout: timeout in seconds for discover. - :return: list of discovered devices + +class _Listener(ServiceListener): + def __init__(self, callback: Callable[[Discovery], None], timeout: float) -> None: + super().__init__() + self._loop = asyncio.get_running_loop() + self._timeout_ms = 1000 * timeout + self._callback = callback + self._tasks: list[asyncio.Task[None]] = [] + + async def __aenter__(self) -> Self: + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None, + exc_val: BaseException | None, + exc_tb: TracebackType | None, + ) -> None: + try: + for task in self._tasks: + await task + self._tasks.clear() + finally: + # Any tasks still pending (which could happen if we get here because of an exception) + # are cancelled. + for task in self._tasks: + task.cancel() + + def add_service(self, zc: Zeroconf, type_: str, name: str) -> None: + if not name.startswith(_DINGZ_NAME_PREFIX): + return + task = self._loop.create_task(self._add_service(zc, type_, name)) + self._tasks.append(task) + + async def _add_service(self, zc: Zeroconf, type_: str, name: str) -> None: + info = AsyncServiceInfo(type_, name) + await info.async_request(zc, self._timeout_ms) + if not info: + _LOGGER.debug("Failed to discover %s", name) + return + discovery = Discovery.from_service_info(info) + _LOGGER.debug("Discovered %s (%s)", discovery, info) + self._callback(discovery) + + +@asynccontextmanager +async def _discover_with_callback( + callback: Callable[[Discovery], None], + *, + timeout: float, +) -> AsyncIterator[None]: + """Discover dingz devices with a callback. + + This function is a async context manager. While entered, it will handle zeroconf announcements + and call the provided function with every device discovered. The callback will not be called + again as soon as as the context manager is exited. """ - registry = DeviceRegistry() - loop = asyncio.get_event_loop() - (transport, protocol) = await loop.create_datagram_endpoint( - lambda: DiscoveryProtocol(registry), local_addr=("0.0.0.0", 7979) - ) - # Server runs in the background, meanwhile wait until timeout expires - await asyncio.sleep(timeout) - - # Shutdown server - transport.close() - - devices = registry.devices() - for device in devices: - _LOGGER.debug( - "Discovered dingz %s (%s) (MAC address: %s)", - device.host, - device.type, - device.mac, - ) - return devices + async with ( + AsyncZeroconf() as zc, + _Listener(callback, timeout=timeout) as listener, + AsyncServiceBrowser(zc.zeroconf, "_http._tcp.local.", listener=listener), + ): + yield diff --git a/pyproject.toml b/pyproject.toml index fd191f7..23b0181 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,6 +28,8 @@ dependencies = [ "aiohttp<4", "async-timeout>=5.0.1 ; python_full_version < '3.11'", "click>=8.1.8", + "typing-extensions>=4.14.1", + "zeroconf>=0.147.0", ] [project.urls] From 7909d2785ed9bf192ac78860e06dc104a2940526 Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Mon, 11 Aug 2025 21:08:29 +0000 Subject: [PATCH 13/21] chore: improve wording in README --- README.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.rst b/README.rst index 7d29269..70bde4c 100644 --- a/README.rst +++ b/README.rst @@ -3,15 +3,15 @@ python-dingz Python API for interacting with `Dingz `_ devices. -This module is not official, developed, supported or endorsed by iolo AG or -myStrom AG. For questions and other inquiries, use the issue tracker in this -repository please. +This module is not official, developed, supported or endorsed by iolo AG. +For questions and other inquiries, please use the issue tracker in this +repository. Without the support of iolo AG and myStrom AG it would have taken much longer -to create this module which is the base for the integration into +to create this module, which is the base for the integration into `Home Assistant `_. Both companies have provided and are still providing hardware, valuable feedback and advice. Their -continuous support make further development of this module possible. +continuous support makes further development of this module possible. See `api.dingz.ch `_ for the API details. @@ -20,7 +20,7 @@ Limitations This module is at the moment limited to consuming sensor data, device details, device configurations and states. -The front LED can be controlled but buttons requires you to programm them by +The front LED can be controlled but buttons require you to program them by yourself. No support for setting timers and schedules. @@ -30,7 +30,7 @@ Requirements You need to have `Python 3 `_ installed. -- `dingz `_ device +- `dingz `_ device with firmware version 2.4.3 or newer. - Network connection - Devices connected to your network @@ -52,7 +52,7 @@ On a Fedora-based system or on a CentOS/RHEL machine which has EPEL enabled. $ sudo dnf -y install python3-dingz -For Nix or NixOS users is a package available. Keep in mind that the lastest releases might only +For Nix or NixOS users is a package available. Keep in mind that the latest releases might only be present in the ``unstable`` channel. .. code:: bash From 88111b99ce0a7c6e2e2093e597704251212cc76e Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Mon, 11 Aug 2025 22:29:48 +0000 Subject: [PATCH 14/21] feat: add unit tests to verify rest client types --- pyproject.toml | 26 +- scripts/gather.py | 184 +++++++++++++ tests/__init__.py | 0 tests/conftest.py | 36 +++ tests/snapshot.py | 95 +++++++ tests/snapshots/07f40e76ee72.json | 203 +++++++++++++++ tests/snapshots/1b148b4bc772.json | 203 +++++++++++++++ tests/snapshots/336a87b7ddcc.json | 206 +++++++++++++++ tests/snapshots/4dfaa25d449e.json | 209 +++++++++++++++ tests/snapshots/687e682a7db1.json | 209 +++++++++++++++ tests/snapshots/a1cbf24095e8.json | 203 +++++++++++++++ tests/snapshots/b6dbe5948d2f.json | 209 +++++++++++++++ tests/test_rest_types.py | 30 +++ uv.lock | 411 +++++++++++++++++++++++++++++- 14 files changed, 2219 insertions(+), 5 deletions(-) create mode 100755 scripts/gather.py create mode 100644 tests/__init__.py create mode 100644 tests/conftest.py create mode 100644 tests/snapshot.py create mode 100644 tests/snapshots/07f40e76ee72.json create mode 100644 tests/snapshots/1b148b4bc772.json create mode 100644 tests/snapshots/336a87b7ddcc.json create mode 100644 tests/snapshots/4dfaa25d449e.json create mode 100644 tests/snapshots/687e682a7db1.json create mode 100644 tests/snapshots/a1cbf24095e8.json create mode 100644 tests/snapshots/b6dbe5948d2f.json create mode 100644 tests/test_rest_types.py diff --git a/pyproject.toml b/pyproject.toml index 23b0181..93b2120 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,14 @@ module-name = "dingz" module-root = "" [dependency-groups] -dev = ["ruff>=0.12.8"] +dev = [ + "colorlog>=6.9.0", + "eval-type-backport>=0.2.2", # Required by pydantic to support Python 3.9 + "pydantic>=2.11.7", + "pytest>=8.4.1", + "pytest-asyncio>=1.1.0", + "ruff>=0.12.8", +] [tool.ruff] line-length = 100 @@ -66,9 +73,20 @@ ignore = [ convention = "pep257" [tool.ruff.lint.per-file-ignores] -"example.py" = [ - "T201", # Allow 'print' in example +# Special rules for non-library code +"!dingz/**.py" = [ + "D", # Don't need full documentation + "T201", # Allow 'print' + "ANN401", # Allow 'Any' ] -"cli.py" = [ +# Special rules for the cli +"dingz/cli.py" = [ "T201", # Allow 'print' in cli ] +# Special rules for tests +"tests/**.py" = [ + "SLF001", # Allow access to private members +] + +[tool.pytest.ini_options] +asyncio_mode = "auto" diff --git a/scripts/gather.py b/scripts/gather.py new file mode 100755 index 0000000..9cd7771 --- /dev/null +++ b/scripts/gather.py @@ -0,0 +1,184 @@ +#!/usr/bin/env -S uv run +"""Gather snapshot data from a dingz device. + +This data is then used for the unit tests. + +Snapshots are placed in the `tests/snapshots` directory. +""" + +from __future__ import annotations + +import argparse +import asyncio +import dataclasses +import hashlib +import logging +from pathlib import Path +from typing import TYPE_CHECKING, Any, Callable, Protocol, TypeVar, cast + +import dingz.discovery +from dingz.rest import Device, RestClient +from tests.snapshot import Endpoint, Error, Snapshot + +if TYPE_CHECKING: + from collections.abc import Awaitable, Iterable + +_LOGGER = logging.getLogger(__name__) + +_PROJECT_ROOT = Path(__file__).parent.parent +_REDACTED_VALUE = "[redacted]" + + +class _Args(Protocol): + host: str | None + scan: bool + + +def _parse_args() -> _Args: + parser = argparse.ArgumentParser(description="Gather information from a dingz device.") + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument( + "--host", + type=str, + help="Hostname or IP of the device", + ) + group.add_argument( + "--scan", + action="store_true", + help="Scan for devices on the network", + ) + args = parser.parse_args() + return cast("_Args", args) + + +async def main() -> None: + args = _parse_args() + + try: + import colorlog # noqa: PLC0415 + + colorlog.basicConfig(level=logging.DEBUG) # pyright: ignore[reportUnknownMemberType] + except ImportError: + logging.basicConfig(level=logging.DEBUG) + + hosts: set[str] = set() + if args.scan: + devices = await dingz.discovery.discover_list() + hosts.update(device.host for device in devices) + if args.host is not None: + hosts.add(args.host) + + for host in hosts: + async with RestClient(host) as client: + _LOGGER.info("Gathering data from %s", host) + snapshot = await gather_snapshot(client) + _LOGGER.info("Done with %s. Writing to %s", host, snapshot.path()) + snapshot.save() + + +T = TypeVar("T") + + +async def gather_endpoint( + fn: Callable[[], Awaitable[T]], + *, + name: str, + redact_paths: Iterable[str] | None = None, +) -> Endpoint[T]: + _LOGGER.debug("Gathering endpoint %s", name) + try: + value = await fn() + except Exception as e: # noqa: BLE001 + _LOGGER.warning("Error gathering endpoint: %s", e) + return Endpoint(value=None, error=Error(type=str(e))) + + if redact_paths is not None: + _redact_paths(value, redact_paths) + + return Endpoint(value=value, error=None) + + +def _redact_path(container: Any, path: str) -> bool: + segments = path.split(".") + for segment in segments[:-1]: + if not isinstance(container, dict) or segment not in container: + return False + container = cast("dict[str, Any]", container) + container = container[segment] + key = segments[-1] + if not (isinstance(container, dict) and key in container): + return False + container[key] = _REDACTED_VALUE + return True + + +def _redact_paths(container: Any, paths: Iterable[str]) -> None: + for path in paths: + if not _redact_path(container, path): + _LOGGER.warning("Unable to redact path %s", path) + + +async def gather_snapshot(client: RestClient) -> Snapshot: + # Don't redact yet so we can generate the device hash + device = await gather_endpoint( + lambda: client.get_device(), + name="device", + ) + if device.value is None: + device_hash = "unknown" + else: + device_hash = _generate_device_hash(device.value) + _redact_paths(device.value, ["puck_sn", "front_sn"]) + + # The `get_device` method contains a bit of magic that we need to revert here. + device_data = device.value.copy() + device_id = device_data.pop("device_id") + device = dataclasses.replace(device, value={device_id: device_data}) + + return Snapshot( + device_hash=device_hash, + firmware_version=await gather_endpoint( + lambda: client.get_firmware_version(), name="firmware_version" + ), + device=device, + network_info=await gather_endpoint( + lambda: client.get_network_info(), + name="network_info", + redact_paths=["mac", "ssid", "ip", "mask", "gw", "dns"], + ), + state=await gather_endpoint( + lambda: client.get_state(), + name="state", + redact_paths=[ + "wifi.mac", + "wifi.ssid", + "wifi.ip", + "wifi.mask", + "wifi.gateway", + "wifi.dns", + ], + ), + ) + + +def _generate_device_hash(data: Device) -> str: + device_hash = hashlib.sha256(usedforsecurity=False) + try: + front_sn: str = data["front_sn"] # pyright: ignore[reportTypedDictNotRequiredAccess] + except (TypeError, KeyError): + pass + else: + device_hash.update(front_sn.encode("utf-8")) + + try: + puck_sn: str = data["puck_sn"] + except (TypeError, KeyError): + pass + else: + device_hash.update(puck_sn.encode("utf-8")) + + return device_hash.hexdigest()[:12] + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 0000000..64e1746 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,36 @@ +from collections.abc import AsyncIterator +from typing import Any, Literal +from unittest.mock import AsyncMock + +import pytest +import pytest_asyncio +from yarl import URL + +from dingz.rest import RestClient + +from .snapshot import Snapshot, load_snapshots + +_SNAPSHOTS = load_snapshots() + + +@pytest.fixture( + params=_SNAPSHOTS, + ids=lambda snapshot: snapshot.device_hash, +) +def snapshot(request: pytest.FixtureRequest) -> Snapshot: + return request.param + + +@pytest_asyncio.fixture +async def rest_client_with_snapshot(snapshot: Snapshot) -> AsyncIterator[RestClient]: + def side_effect(_method: Literal["GET"], endpoint: URL) -> Any: + endpoint_data = snapshot.endpoint_by_path(endpoint.path) + if endpoint_data.error is not None: + msg = "Error mocking is not yet implemented in test framework!" + raise NotImplementedError(msg) + return endpoint_data.value + + async with RestClient("127.0.0.1") as client: + request_mock = AsyncMock(client._request, side_effect=side_effect) + client._request = request_mock + yield client diff --git a/tests/snapshot.py b/tests/snapshot.py new file mode 100644 index 0000000..b8490f0 --- /dev/null +++ b/tests/snapshot.py @@ -0,0 +1,95 @@ +from __future__ import annotations + +import dataclasses +import json +from pathlib import Path +from typing import TYPE_CHECKING, Any, Generic, TypeVar + +from typing_extensions import Self + +if TYPE_CHECKING: + from collections.abc import Mapping + + from dingz.rest import Device, NetworkInfo, State + +__all__ = [ + "Endpoint", + "Error", + "Snapshot", +] + +_TESTS_DIR = Path(__file__).parent +_SNAPSHOTS_DIR = _TESTS_DIR / "snapshots" + + +@dataclasses.dataclass(frozen=True) +class Error: + type: str + + @classmethod + def from_dict(cls, data: Mapping[str, Any]) -> Self: + return cls( + type=data["type"], + ) + + +T = TypeVar("T") + + +@dataclasses.dataclass(frozen=True) +class Endpoint(Generic[T]): + value: T | None + error: Error | None + + @classmethod + def from_dict(cls, data: Mapping[str, Any]) -> Endpoint[Any]: + error_raw = data.get("error") + error = Error.from_dict(error_raw) if error_raw else None + return cls( + value=data.get("value"), + error=error, + ) + + +@dataclasses.dataclass(frozen=True) +class Snapshot: + device_hash: str + firmware_version: Endpoint[str] + device: Endpoint[Device] + network_info: Endpoint[NetworkInfo] + state: Endpoint[State] + + def endpoint_by_path(self, path: str) -> Endpoint[Any]: + if path == "/api/v1/device": + return self.device + if path == "/api/v1/info": + return self.network_info + if path == "/api/v1/state": + return self.state + msg = f"Unknown endpoint path: {path}" + raise LookupError(msg) + + def path(self) -> Path: + return _SNAPSHOTS_DIR / f"{self.device_hash}.json" + + def save(self) -> None: + text = json.dumps(dataclasses.asdict(self), indent=2) + self.path().write_text(text, encoding="utf-8") + + @classmethod + def from_dict(cls, data: Mapping[str, Any]) -> Self: + return cls( + device_hash=data["device_hash"], + firmware_version=Endpoint.from_dict(data["firmware_version"]), + device=Endpoint.from_dict(data["device"]), + network_info=Endpoint.from_dict(data["network_info"]), + state=Endpoint.from_dict(data["state"]), + ) + + +def load_snapshots() -> list[Snapshot]: + snapshots: list[Snapshot] = [] + for path in _SNAPSHOTS_DIR.glob("*.json"): + data = json.loads(path.read_text(encoding="utf-8")) + snapshots.append(Snapshot.from_dict(data)) + return snapshots diff --git a/tests/snapshots/07f40e76ee72.json b/tests/snapshots/07f40e76ee72.json new file mode 100644 index 0000000..1abb813 --- /dev/null +++ b/tests/snapshots/07f40e76ee72.json @@ -0,0 +1,203 @@ +{ + "device_hash": "07f40e76ee72", + "firmware_version": { + "value": "2.4.3", + "error": null + }, + "device": { + "value": { + "246F28AEDE10": { + "type": "dingz", + "battery": false, + "reachable": true, + "meshroot": true, + "fw_version": "2.4.3", + "hw_version": "1.1.2", + "fw_version_puck": "2.1.4", + "bl_version_puck": "1.0.0", + "hw_version_puck": "1.1.2", + "hw_id_puck": 65535, + "puck_sn": "[redacted]", + "puck_production_date": { + "year": 20, + "month": 4, + "day": 28 + }, + "ddi_base": false, + "dip_config": 3, + "dip_static": false, + "dip_misconf": false, + "puck_hw_model": "DZ1B-4CH", + "front_hw_model": "dz1f-4b", + "front_production_date": "20/4/26", + "front_sn": "[redacted]", + "front_color": "WH", + "has_pir": false, + "first_boot": false, + "hash": "629b155c" + } + }, + "error": null + }, + "network_info": { + "value": { + "version": "2.4.3", + "mac": "[redacted]", + "type": 108, + "ssid": "[redacted]", + "ip": "[redacted]", + "mask": "[redacted]", + "gw": "[redacted]", + "dns": "[redacted]", + "static": false, + "connected": true + }, + "error": null + }, + "state": { + "value": { + "dimmers": [ + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": true, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 0, + "absolute": 0 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": true, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 1, + "absolute": 1 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": false, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 2, + "absolute": 2 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": true, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 3, + "absolute": 3 + } + } + ], + "blinds": [], + "ddi_channels": [], + "led": { + "on": false, + "hsv": "0;0;100", + "rgb": "FFFFFF", + "mode": "hsv", + "ramp": 25, + "override_level": 0 + }, + "sensors": { + "brightness": 0, + "light_state": "night", + "light_state_lpf": "night", + "room_temperature": 22, + "uncompensated_temperature": 33.0625, + "temp_offset": 7, + "cpu_temperature": 67.78, + "puck_temperature": 33, + "fet_temperature": 33.4, + "input_state": null, + "pirs": [ + null, + { + "enabled": true, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + }, + { + "enabled": false, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + } + ], + "power_outputs": [ + { + "value": 0 + }, + { + "value": 0 + }, + { + "value": 0 + }, + { + "value": 0 + } + ] + }, + "dyn_light": { + "mode": "night" + }, + "thermostat": { + "active": false, + "state": "off", + "mode": "off", + "user_mode": "comfort", + "enabled": false, + "target_temp": 21, + "min_target_temp": 17, + "max_target_temp": 31, + "cooling": false, + "free_cooling": false, + "temp": 22 + }, + "wifi": { + "version": "2.4.3", + "mac": "[redacted]", + "ssid": "[redacted]", + "ip": "[redacted]", + "mask": "[redacted]", + "gateway": "[redacted]", + "dns": "[redacted]", + "static": false, + "connected": true + }, + "cloud": { + "aws": "connected" + }, + "time": "2025-08-12 00:05:00", + "config": { + "timestamp": 1754853495 + } + }, + "error": null + } +} \ No newline at end of file diff --git a/tests/snapshots/1b148b4bc772.json b/tests/snapshots/1b148b4bc772.json new file mode 100644 index 0000000..1cde4e5 --- /dev/null +++ b/tests/snapshots/1b148b4bc772.json @@ -0,0 +1,203 @@ +{ + "device_hash": "1b148b4bc772", + "firmware_version": { + "value": "2.4.3", + "error": null + }, + "device": { + "value": { + "F008D1C46700": { + "type": "dingz", + "battery": false, + "reachable": true, + "meshroot": true, + "fw_version": "2.4.3", + "hw_version": "1.1.2", + "fw_version_puck": "2.1.4", + "bl_version_puck": "1.0.0", + "hw_version_puck": "1.1.2", + "hw_id_puck": 65535, + "puck_sn": "[redacted]", + "puck_production_date": { + "year": 20, + "month": 5, + "day": 3 + }, + "ddi_base": false, + "dip_config": 3, + "dip_static": false, + "dip_misconf": false, + "puck_hw_model": "DZ1B-4CH", + "front_hw_model": "dz1f-4b", + "front_production_date": "20/10/21", + "front_sn": "[redacted]", + "front_color": "WH", + "has_pir": false, + "first_boot": false, + "hash": "629b155c" + } + }, + "error": null + }, + "network_info": { + "value": { + "version": "2.4.3", + "mac": "[redacted]", + "type": 108, + "ssid": "[redacted]", + "ip": "[redacted]", + "mask": "[redacted]", + "gw": "[redacted]", + "dns": "[redacted]", + "static": false, + "connected": true + }, + "error": null + }, + "state": { + "value": { + "dimmers": [ + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": true, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 0, + "absolute": 0 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": true, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 1, + "absolute": 1 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": false, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 2, + "absolute": 2 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": false, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 3, + "absolute": 3 + } + } + ], + "blinds": [], + "ddi_channels": [], + "led": { + "on": false, + "hsv": "0;0;0", + "rgb": "FFFFFF", + "mode": "hsv", + "ramp": 25, + "override_level": 0 + }, + "sensors": { + "brightness": 0, + "light_state": "night", + "light_state_lpf": "night", + "room_temperature": 23.5, + "uncompensated_temperature": 35.5625, + "temp_offset": 6, + "cpu_temperature": 59.44, + "puck_temperature": 38, + "fet_temperature": 38.2, + "input_state": false, + "pirs": [ + null, + { + "enabled": true, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + }, + { + "enabled": false, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + } + ], + "power_outputs": [ + { + "value": 0 + }, + { + "value": 0 + }, + { + "value": 0 + }, + { + "value": 0 + } + ] + }, + "dyn_light": { + "mode": "night" + }, + "thermostat": { + "active": false, + "state": "off", + "mode": "off", + "user_mode": "comfort", + "enabled": false, + "target_temp": 22, + "min_target_temp": 17, + "max_target_temp": 31, + "cooling": false, + "free_cooling": false, + "temp": 23.5 + }, + "wifi": { + "version": "2.4.3", + "mac": "[redacted]", + "ssid": "[redacted]", + "ip": "[redacted]", + "mask": "[redacted]", + "gateway": "[redacted]", + "dns": "[redacted]", + "static": false, + "connected": true + }, + "cloud": { + "aws": "connected" + }, + "time": "2025-08-12 00:05:01", + "config": { + "timestamp": 1754123331 + } + }, + "error": null + } +} \ No newline at end of file diff --git a/tests/snapshots/336a87b7ddcc.json b/tests/snapshots/336a87b7ddcc.json new file mode 100644 index 0000000..c330e8b --- /dev/null +++ b/tests/snapshots/336a87b7ddcc.json @@ -0,0 +1,206 @@ +{ + "device_hash": "336a87b7ddcc", + "firmware_version": { + "value": "2.4.3", + "error": null + }, + "device": { + "value": { + "840D8E030A94": { + "type": "dingz", + "battery": false, + "reachable": true, + "meshroot": true, + "fw_version": "2.4.3", + "hw_version": "1.0", + "fw_version_puck": "2.1.4", + "bl_version_puck": "1.0.0", + "hw_version_puck": "1.1.2", + "hw_id_puck": 65535, + "puck_sn": "[redacted]", + "puck_production_date": { + "year": 20, + "month": 9, + "day": 15 + }, + "ddi_base": false, + "dip_config": 3, + "dip_static": false, + "dip_misconf": false, + "puck_hw_model": "DZ1B-4CH", + "front_color": "WH", + "has_pir": true, + "first_boot": false, + "hash": "629b155c" + } + }, + "error": null + }, + "network_info": { + "value": { + "version": "2.4.3", + "mac": "[redacted]", + "type": 108, + "ssid": "[redacted]", + "ip": "[redacted]", + "mask": "[redacted]", + "gw": "[redacted]", + "dns": "[redacted]", + "static": false, + "connected": true + }, + "error": null + }, + "state": { + "value": { + "dimmers": [ + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": true, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 0, + "absolute": 0 + } + }, + { + "on": true, + "output": 100, + "ramp": 0, + "readonly": false, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 1, + "absolute": 1 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": false, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 2, + "absolute": 2 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": false, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 3, + "absolute": 3 + } + } + ], + "blinds": [], + "ddi_channels": [], + "led": { + "on": false, + "hsv": "0;0;100", + "rgb": "FFFFFF", + "mode": "hsv", + "ramp": 1023, + "override_level": 0 + }, + "sensors": { + "brightness": 10, + "light_state": "twilight", + "light_state_lpf": "twilight", + "room_temperature": 23.5, + "uncompensated_temperature": 35.375, + "temp_offset": 6, + "cpu_temperature": 35, + "puck_temperature": 37, + "fet_temperature": 36.7, + "input_state": null, + "pirs": [ + { + "enabled": true, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + }, + { + "enabled": false, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + }, + { + "enabled": false, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + } + ], + "power_outputs": [ + { + "value": 0 + }, + { + "value": 18.79 + }, + { + "value": 0 + }, + { + "value": 0 + } + ] + }, + "dyn_light": { + "mode": "twilight" + }, + "thermostat": { + "active": false, + "state": "off", + "mode": "off", + "user_mode": "comfort", + "enabled": false, + "target_temp": 21, + "min_target_temp": 17, + "max_target_temp": 31, + "cooling": false, + "free_cooling": false, + "temp": 23.5 + }, + "wifi": { + "version": "2.4.3", + "mac": "[redacted]", + "ssid": "[redacted]", + "ip": "[redacted]", + "mask": "[redacted]", + "gateway": "[redacted]", + "dns": "[redacted]", + "static": false, + "connected": true + }, + "cloud": { + "aws": "disconnected" + }, + "time": "2025-08-12 00:05:01", + "config": { + "timestamp": 1754939922 + } + }, + "error": null + } +} \ No newline at end of file diff --git a/tests/snapshots/4dfaa25d449e.json b/tests/snapshots/4dfaa25d449e.json new file mode 100644 index 0000000..773557c --- /dev/null +++ b/tests/snapshots/4dfaa25d449e.json @@ -0,0 +1,209 @@ +{ + "device_hash": "4dfaa25d449e", + "firmware_version": { + "value": "2.4.3", + "error": null + }, + "device": { + "value": { + "246F28A81A10": { + "type": "dingz", + "battery": false, + "reachable": true, + "meshroot": true, + "fw_version": "2.4.3", + "hw_version": "1.1.2", + "fw_version_puck": "2.1.4", + "bl_version_puck": "1.0.0", + "hw_version_puck": "1.1.2", + "hw_id_puck": 65535, + "puck_sn": "[redacted]", + "puck_production_date": { + "year": 20, + "month": 4, + "day": 29 + }, + "ddi_base": false, + "dip_config": 3, + "dip_static": false, + "dip_misconf": false, + "puck_hw_model": "DZ1B-4CH", + "front_hw_model": "dz1f-pir", + "front_production_date": "20/4/29", + "front_sn": "[redacted]", + "front_color": "WH", + "has_pir": true, + "first_boot": false, + "hash": "629b155c" + } + }, + "error": null + }, + "network_info": { + "value": { + "version": "2.4.3", + "mac": "[redacted]", + "type": 108, + "ssid": "[redacted]", + "ip": "[redacted]", + "mask": "[redacted]", + "gw": "[redacted]", + "dns": "[redacted]", + "static": false, + "connected": true + }, + "error": null + }, + "state": { + "value": { + "dimmers": [ + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": true, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 0, + "absolute": 0 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": true, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 1, + "absolute": 1 + } + }, + { + "on": false, + "output": 0, + "ramp": 10, + "readonly": false, + "off_timer_type": "pir", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 2, + "absolute": 2 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": true, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 3, + "absolute": 3 + } + } + ], + "blinds": [], + "ddi_channels": [], + "led": { + "on": false, + "hsv": "0;0;100", + "rgb": "FFFFFF", + "mode": "hsv", + "ramp": 1023, + "override_level": 0 + }, + "sensors": { + "brightness": 1, + "light_state": "night", + "light_state_lpf": "night", + "room_temperature": 21.5, + "uncompensated_temperature": 33.9375, + "temp_offset": 6, + "cpu_temperature": 49.44, + "puck_temperature": 37, + "fet_temperature": 39, + "input_state": false, + "pirs": [ + { + "enabled": true, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + }, + { + "enabled": false, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + }, + { + "enabled": false, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + } + ], + "power_outputs": [ + { + "value": 0 + }, + { + "value": 0 + }, + { + "value": 0 + }, + { + "value": 0 + } + ] + }, + "dyn_light": { + "mode": "night" + }, + "thermostat": { + "active": false, + "state": "off", + "mode": "off", + "user_mode": "comfort", + "enabled": false, + "target_temp": 21, + "min_target_temp": 17, + "max_target_temp": 31, + "cooling": false, + "free_cooling": false, + "temp": 21.5 + }, + "wifi": { + "version": "2.4.3", + "mac": "[redacted]", + "ssid": "[redacted]", + "ip": "[redacted]", + "mask": "[redacted]", + "gateway": "[redacted]", + "dns": "[redacted]", + "static": false, + "connected": true + }, + "cloud": { + "aws": "connected" + }, + "time": "2025-08-12 00:05:00", + "config": { + "timestamp": 1754925299 + } + }, + "error": null + } +} \ No newline at end of file diff --git a/tests/snapshots/687e682a7db1.json b/tests/snapshots/687e682a7db1.json new file mode 100644 index 0000000..db78e2c --- /dev/null +++ b/tests/snapshots/687e682a7db1.json @@ -0,0 +1,209 @@ +{ + "device_hash": "687e682a7db1", + "firmware_version": { + "value": "2.4.3", + "error": null + }, + "device": { + "value": { + "F008D1C533D0": { + "type": "dingz", + "battery": false, + "reachable": true, + "meshroot": true, + "fw_version": "2.4.3", + "hw_version": "1.1.2", + "fw_version_puck": "2.1.4", + "bl_version_puck": "1.0.0", + "hw_version_puck": "1.1.2", + "hw_id_puck": 65535, + "puck_sn": "[redacted]", + "puck_production_date": { + "year": 20, + "month": 9, + "day": 16 + }, + "ddi_base": false, + "dip_config": 3, + "dip_static": false, + "dip_misconf": false, + "puck_hw_model": "DZ1B-4CH", + "front_hw_model": "dz1f-pir", + "front_production_date": "20/12/26", + "front_sn": "[redacted]", + "front_color": "MC", + "has_pir": true, + "first_boot": false, + "hash": "629b155c" + } + }, + "error": null + }, + "network_info": { + "value": { + "version": "2.4.3", + "mac": "[redacted]", + "type": 108, + "ssid": "[redacted]", + "ip": "[redacted]", + "mask": "[redacted]", + "gw": "[redacted]", + "dns": "[redacted]", + "static": false, + "connected": true + }, + "error": null + }, + "state": { + "value": { + "dimmers": [ + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": true, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 0, + "absolute": 0 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": false, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 1, + "absolute": 1 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": true, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 2, + "absolute": 2 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": true, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 3, + "absolute": 3 + } + } + ], + "blinds": [], + "ddi_channels": [], + "led": { + "on": false, + "hsv": "0;0;100", + "rgb": "FFFFFF", + "mode": "hsv", + "ramp": 1023, + "override_level": 0 + }, + "sensors": { + "brightness": 28, + "light_state": "day", + "light_state_lpf": "day", + "room_temperature": 23.5, + "uncompensated_temperature": 35.4375, + "temp_offset": 6, + "cpu_temperature": 53.33, + "puck_temperature": 35, + "fet_temperature": 34.9, + "input_state": null, + "pirs": [ + { + "enabled": true, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + }, + { + "enabled": true, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + }, + { + "enabled": false, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + } + ], + "power_outputs": [ + { + "value": 0 + }, + { + "value": 0 + }, + { + "value": 0 + }, + { + "value": 0 + } + ] + }, + "dyn_light": { + "mode": "day" + }, + "thermostat": { + "active": false, + "state": "off", + "mode": "off", + "user_mode": "comfort", + "enabled": false, + "target_temp": 22, + "min_target_temp": 17, + "max_target_temp": 31, + "cooling": false, + "free_cooling": false, + "temp": 23.5 + }, + "wifi": { + "version": "2.4.3", + "mac": "[redacted]", + "ssid": "[redacted]", + "ip": "[redacted]", + "mask": "[redacted]", + "gateway": "[redacted]", + "dns": "[redacted]", + "static": false, + "connected": true + }, + "cloud": { + "aws": "connected" + }, + "time": "2025-08-12 00:04:59", + "config": { + "timestamp": 1754939857 + } + }, + "error": null + } +} \ No newline at end of file diff --git a/tests/snapshots/a1cbf24095e8.json b/tests/snapshots/a1cbf24095e8.json new file mode 100644 index 0000000..74e5574 --- /dev/null +++ b/tests/snapshots/a1cbf24095e8.json @@ -0,0 +1,203 @@ +{ + "device_hash": "a1cbf24095e8", + "firmware_version": { + "value": "2.4.3", + "error": null + }, + "device": { + "value": { + "246F28A81710": { + "type": "dingz", + "battery": false, + "reachable": true, + "meshroot": true, + "fw_version": "2.4.3", + "hw_version": "1.1.2", + "fw_version_puck": "2.1.4", + "bl_version_puck": "1.0.0", + "hw_version_puck": "1.1.2", + "hw_id_puck": 65535, + "puck_sn": "[redacted]", + "puck_production_date": { + "year": 20, + "month": 5, + "day": 3 + }, + "ddi_base": false, + "dip_config": 3, + "dip_static": false, + "dip_misconf": false, + "puck_hw_model": "DZ1B-4CH", + "front_hw_model": "dz1f-4b", + "front_production_date": "20/4/28", + "front_sn": "[redacted]", + "front_color": "WH", + "has_pir": false, + "first_boot": true, + "hash": "629b155c" + } + }, + "error": null + }, + "network_info": { + "value": { + "version": "2.4.3", + "mac": "[redacted]", + "type": 108, + "ssid": "[redacted]", + "ip": "[redacted]", + "mask": "[redacted]", + "gw": "[redacted]", + "dns": "[redacted]", + "static": false, + "connected": true + }, + "error": null + }, + "state": { + "value": { + "dimmers": [ + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": true, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 0, + "absolute": 0 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": false, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 1, + "absolute": 1 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": false, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 2, + "absolute": 2 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": false, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 3, + "absolute": 3 + } + } + ], + "blinds": [], + "ddi_channels": [], + "led": { + "on": false, + "hsv": "0;0;100", + "rgb": "FFFFFF", + "mode": "hsv", + "ramp": 1023, + "override_level": 0 + }, + "sensors": { + "brightness": 0, + "light_state": "night", + "light_state_lpf": "night", + "room_temperature": 23.5, + "uncompensated_temperature": 34.3125, + "temp_offset": 7.5, + "cpu_temperature": 50, + "puck_temperature": 37, + "fet_temperature": 38.1, + "input_state": false, + "pirs": [ + null, + { + "enabled": true, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + }, + { + "enabled": false, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + } + ], + "power_outputs": [ + { + "value": 0 + }, + { + "value": 0 + }, + { + "value": 0 + }, + { + "value": 0 + } + ] + }, + "dyn_light": { + "mode": "night" + }, + "thermostat": { + "active": false, + "state": "off", + "mode": "off", + "user_mode": "comfort", + "enabled": false, + "target_temp": 21, + "min_target_temp": 17, + "max_target_temp": 31, + "cooling": false, + "free_cooling": false, + "temp": 23.5 + }, + "wifi": { + "version": "2.4.3", + "mac": "[redacted]", + "ssid": "[redacted]", + "ip": "[redacted]", + "mask": "[redacted]", + "gateway": "[redacted]", + "dns": "[redacted]", + "static": false, + "connected": true + }, + "cloud": { + "aws": "connected" + }, + "time": "2025-08-12 00:05:00", + "config": { + "timestamp": 1754831728 + } + }, + "error": null + } +} \ No newline at end of file diff --git a/tests/snapshots/b6dbe5948d2f.json b/tests/snapshots/b6dbe5948d2f.json new file mode 100644 index 0000000..66bf248 --- /dev/null +++ b/tests/snapshots/b6dbe5948d2f.json @@ -0,0 +1,209 @@ +{ + "device_hash": "b6dbe5948d2f", + "firmware_version": { + "value": "2.4.3", + "error": null + }, + "device": { + "value": { + "F008D1C52DA4": { + "type": "dingz", + "battery": false, + "reachable": true, + "meshroot": true, + "fw_version": "2.4.3", + "hw_version": "1.1.2", + "fw_version_puck": "2.1.4", + "bl_version_puck": "1.0.0", + "hw_version_puck": "1.1.1", + "hw_id_puck": 1, + "puck_sn": "[redacted]", + "puck_production_date": { + "year": 20, + "month": 1, + "day": 3 + }, + "ddi_base": false, + "dip_config": 3, + "dip_static": false, + "dip_misconf": false, + "puck_hw_model": "", + "front_hw_model": "dz1f-pir", + "front_production_date": "21/3/4", + "front_sn": "[redacted]", + "front_color": "WH", + "has_pir": true, + "first_boot": false, + "hash": "629b155c" + } + }, + "error": null + }, + "network_info": { + "value": { + "version": "2.4.3", + "mac": "[redacted]", + "type": 108, + "ssid": "[redacted]", + "ip": "[redacted]", + "mask": "[redacted]", + "gw": "[redacted]", + "dns": "[redacted]", + "static": false, + "connected": true + }, + "error": null + }, + "state": { + "value": { + "dimmers": [ + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": false, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 0, + "absolute": 0 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": false, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 1, + "absolute": 1 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": false, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 2, + "absolute": 2 + } + }, + { + "on": false, + "output": 0, + "ramp": 0, + "readonly": true, + "off_timer_type": "none", + "off_timer_id": 0, + "off_timer_value": 0, + "index": { + "relative": 3, + "absolute": 3 + } + } + ], + "blinds": [], + "ddi_channels": [], + "led": { + "on": false, + "hsv": "0;0;100", + "rgb": "FFFFFF", + "mode": "hsv", + "ramp": 1023, + "override_level": 0 + }, + "sensors": { + "brightness": 0, + "light_state": "night", + "light_state_lpf": "night", + "room_temperature": 23.5, + "uncompensated_temperature": 35.9375, + "temp_offset": 6, + "cpu_temperature": 59.44, + "puck_temperature": 64, + "fet_temperature": 40.5, + "input_state": null, + "pirs": [ + { + "enabled": true, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + }, + { + "enabled": true, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + }, + { + "enabled": false, + "motion": false, + "mode": "idle", + "light_off_timer": 0, + "suspend_timer": 0 + } + ], + "power_outputs": [ + { + "value": 0 + }, + { + "value": 0 + }, + { + "value": 0 + }, + { + "value": 0 + } + ] + }, + "dyn_light": { + "mode": "night" + }, + "thermostat": { + "active": false, + "state": "off", + "mode": "off", + "user_mode": "comfort", + "enabled": false, + "target_temp": 22, + "min_target_temp": 17, + "max_target_temp": 31, + "cooling": false, + "free_cooling": false, + "temp": 23.5 + }, + "wifi": { + "version": "2.4.3", + "mac": "[redacted]", + "ssid": "[redacted]", + "ip": "[redacted]", + "mask": "[redacted]", + "gateway": "[redacted]", + "dns": "[redacted]", + "static": false, + "connected": true + }, + "cloud": { + "aws": "connected" + }, + "time": "2025-08-12 00:04:59", + "config": { + "timestamp": 1754592527 + } + }, + "error": null + } +} \ No newline at end of file diff --git a/tests/test_rest_types.py b/tests/test_rest_types.py new file mode 100644 index 0000000..109c34c --- /dev/null +++ b/tests/test_rest_types.py @@ -0,0 +1,30 @@ +""" +This test ensures that the type definitions used by `dingz.rest` actually match observed API +responses. +""" + +from typing import Any + +from pydantic import TypeAdapter + +from dingz.rest import Device, NetworkInfo, RestClient, State + + +def _validate_strict(ty: Any, value: Any) -> None: + adapter = TypeAdapter(ty) + adapter.validate_python(value) + + +async def test_device_type(rest_client_with_snapshot: RestClient) -> None: + device = await rest_client_with_snapshot.get_device() + _validate_strict(Device, device) + + +async def test_network_info(rest_client_with_snapshot: RestClient) -> None: + nw_info = await rest_client_with_snapshot.get_network_info() + _validate_strict(NetworkInfo, nw_info) + + +async def test_state(rest_client_with_snapshot: RestClient) -> None: + state = await rest_client_with_snapshot.get_state() + _validate_strict(State, state) diff --git a/uv.lock b/uv.lock index 5a78818..468ebe8 100644 --- a/uv.lock +++ b/uv.lock @@ -131,6 +131,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, ] +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, +] + [[package]] name = "async-timeout" version = "5.0.1" @@ -149,6 +158,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, ] +[[package]] +name = "backports-asyncio-runner" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/ff/70dca7d7cb1cbc0edb2c6cc0c38b65cba36cccc491eca64cabd5fe7f8670/backports_asyncio_runner-1.2.0.tar.gz", hash = "sha256:a5aa7b2b7d8f8bfcaa2b57313f70792df84e32a2a746f585213373f900b42162", size = 69893, upload-time = "2025-07-02T02:27:15.685Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/59/76ab57e3fe74484f48a53f8e337171b4a2349e506eabe136d7e01d059086/backports_asyncio_runner-1.2.0-py3-none-any.whl", hash = "sha256:0da0a936a8aeb554eccb426dc55af3ba63bcdc69fa1a600b5bb305413a4477b5", size = 12313, upload-time = "2025-07-02T02:27:14.263Z" }, +] + [[package]] name = "click" version = "8.1.8" @@ -188,6 +206,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] +[[package]] +name = "colorlog" +version = "6.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d3/7a/359f4d5df2353f26172b3cc39ea32daa39af8de522205f512f458923e677/colorlog-6.9.0.tar.gz", hash = "sha256:bfba54a1b93b94f54e1f4fe48395725a3d92fd2a4af702f6bd70946bdc0c6ac2", size = 16624, upload-time = "2024-10-29T18:34:51.011Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/51/9b208e85196941db2f0654ad0357ca6388ab3ed67efdbfc799f35d1f83aa/colorlog-6.9.0-py3-none-any.whl", hash = "sha256:5906e71acd67cb07a71e779c47c4bcb45fb8c2993eebe9e5adcd6a6f1b283eff", size = 11424, upload-time = "2024-10-29T18:34:49.815Z" }, +] + [[package]] name = "dingz" version = "0.6.0.dev0" @@ -197,10 +227,17 @@ dependencies = [ { name = "async-timeout", marker = "python_full_version < '3.11'" }, { name = "click", version = "8.1.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, { name = "click", version = "8.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "typing-extensions" }, + { name = "zeroconf" }, ] [package.dev-dependencies] dev = [ + { name = "colorlog" }, + { name = "eval-type-backport" }, + { name = "pydantic" }, + { name = "pytest" }, + { name = "pytest-asyncio" }, { name = "ruff" }, ] @@ -209,10 +246,40 @@ requires-dist = [ { name = "aiohttp", specifier = "<4" }, { name = "async-timeout", marker = "python_full_version < '3.11'", specifier = ">=5.0.1" }, { name = "click", specifier = ">=8.1.8" }, + { name = "typing-extensions", specifier = ">=4.14.1" }, + { name = "zeroconf", specifier = ">=0.147.0" }, ] [package.metadata.requires-dev] -dev = [{ name = "ruff", specifier = ">=0.12.8" }] +dev = [ + { name = "colorlog", specifier = ">=6.9.0" }, + { name = "eval-type-backport", specifier = ">=0.2.2" }, + { name = "pydantic", specifier = ">=2.11.7" }, + { name = "pytest", specifier = ">=8.4.1" }, + { name = "pytest-asyncio", specifier = ">=1.1.0" }, + { name = "ruff", specifier = ">=0.12.8" }, +] + +[[package]] +name = "eval-type-backport" +version = "0.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/ea/8b0ac4469d4c347c6a385ff09dc3c048c2d021696664e26c7ee6791631b5/eval_type_backport-0.2.2.tar.gz", hash = "sha256:f0576b4cf01ebb5bd358d02314d31846af5e07678387486e2c798af0e7d849c1", size = 9079, upload-time = "2024-12-21T20:09:46.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/31/55cd413eaccd39125368be33c46de24a1f639f2e12349b0361b4678f3915/eval_type_backport-0.2.2-py3-none-any.whl", hash = "sha256:cb6ad7c393517f476f96d456d0412ea80f0a8cf96f6892834cd9340149111b0a", size = 5830, upload-time = "2024-12-21T20:09:44.175Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674, upload-time = "2025-05-10T17:42:49.33Z" }, +] [[package]] name = "frozenlist" @@ -334,6 +401,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, ] +[[package]] +name = "ifaddr" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/ac/fb4c578f4a3256561548cd825646680edcadb9440f3f68add95ade1eb791/ifaddr-0.2.0.tar.gz", hash = "sha256:cc0cbfcaabf765d44595825fb96a99bb12c79716b73b44330ea38ee2b0c4aed4", size = 10485, upload-time = "2022-06-15T21:40:27.561Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9c/1f/19ebc343cc71a7ffa78f17018535adc5cbdd87afb31d7c34874680148b32/ifaddr-0.2.0-py3-none-any.whl", hash = "sha256:085e0305cfe6f16ab12d72e2024030f5d52674afad6911bb1eee207177b8a748", size = 12314, upload-time = "2022-06-15T21:40:25.756Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, +] + [[package]] name = "multidict" version = "6.6.3" @@ -454,6 +539,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d8/30/9aec301e9772b098c1f5c0ca0279237c9766d94b97802e9888010c64b0ed/multidict-6.6.3-py3-none-any.whl", hash = "sha256:8db10f29c7541fc5da4defd8cd697e1ca429db743fa716325f236079b96f775a", size = 12313, upload-time = "2025-06-30T15:53:45.437Z" }, ] +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + [[package]] name = "propcache" version = "0.3.2" @@ -559,6 +662,171 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cc/35/cc0aaecf278bb4575b8555f2b137de5ab821595ddae9da9d3cd1da4072c7/propcache-0.3.2-py3-none-any.whl", hash = "sha256:98f1ec44fb675f5052cccc8e609c46ed23a35a1cfd18545ad4e29002d858a43f", size = 12663, upload-time = "2025-06-09T22:56:04.484Z" }, ] +[[package]] +name = "pydantic" +version = "2.11.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/00/dd/4325abf92c39ba8623b5af936ddb36ffcfe0beae70405d456ab1fb2f5b8c/pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db", size = 788350, upload-time = "2025-06-14T08:33:17.137Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/c0/ec2b1c8712ca690e5d61979dee872603e92b8a32f94cc1b72d53beab008a/pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b", size = 444782, upload-time = "2025-06-14T08:33:14.905Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.33.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ad/88/5f2260bdfae97aabf98f1778d43f69574390ad787afb646292a638c923d4/pydantic_core-2.33.2.tar.gz", hash = "sha256:7cb8bc3605c29176e1b105350d2e6474142d7c1bd1d9327c4a9bdb46bf827acc", size = 435195, upload-time = "2025-04-23T18:33:52.104Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/92/b31726561b5dae176c2d2c2dc43a9c5bfba5d32f96f8b4c0a600dd492447/pydantic_core-2.33.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2b3d326aaef0c0399d9afffeb6367d5e26ddc24d351dbc9c636840ac355dc5d8", size = 2028817, upload-time = "2025-04-23T18:30:43.919Z" }, + { url = "https://files.pythonhosted.org/packages/a3/44/3f0b95fafdaca04a483c4e685fe437c6891001bf3ce8b2fded82b9ea3aa1/pydantic_core-2.33.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e5b2671f05ba48b94cb90ce55d8bdcaaedb8ba00cc5359f6810fc918713983d", size = 1861357, upload-time = "2025-04-23T18:30:46.372Z" }, + { url = "https://files.pythonhosted.org/packages/30/97/e8f13b55766234caae05372826e8e4b3b96e7b248be3157f53237682e43c/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0069c9acc3f3981b9ff4cdfaf088e98d83440a4c7ea1bc07460af3d4dc22e72d", size = 1898011, upload-time = "2025-04-23T18:30:47.591Z" }, + { url = "https://files.pythonhosted.org/packages/9b/a3/99c48cf7bafc991cc3ee66fd544c0aae8dc907b752f1dad2d79b1b5a471f/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d53b22f2032c42eaaf025f7c40c2e3b94568ae077a606f006d206a463bc69572", size = 1982730, upload-time = "2025-04-23T18:30:49.328Z" }, + { url = "https://files.pythonhosted.org/packages/de/8e/a5b882ec4307010a840fb8b58bd9bf65d1840c92eae7534c7441709bf54b/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0405262705a123b7ce9f0b92f123334d67b70fd1f20a9372b907ce1080c7ba02", size = 2136178, upload-time = "2025-04-23T18:30:50.907Z" }, + { url = "https://files.pythonhosted.org/packages/e4/bb/71e35fc3ed05af6834e890edb75968e2802fe98778971ab5cba20a162315/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b25d91e288e2c4e0662b8038a28c6a07eaac3e196cfc4ff69de4ea3db992a1b", size = 2736462, upload-time = "2025-04-23T18:30:52.083Z" }, + { url = "https://files.pythonhosted.org/packages/31/0d/c8f7593e6bc7066289bbc366f2235701dcbebcd1ff0ef8e64f6f239fb47d/pydantic_core-2.33.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bdfe4b3789761f3bcb4b1ddf33355a71079858958e3a552f16d5af19768fef2", size = 2005652, upload-time = "2025-04-23T18:30:53.389Z" }, + { url = "https://files.pythonhosted.org/packages/d2/7a/996d8bd75f3eda405e3dd219ff5ff0a283cd8e34add39d8ef9157e722867/pydantic_core-2.33.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:efec8db3266b76ef9607c2c4c419bdb06bf335ae433b80816089ea7585816f6a", size = 2113306, upload-time = "2025-04-23T18:30:54.661Z" }, + { url = "https://files.pythonhosted.org/packages/ff/84/daf2a6fb2db40ffda6578a7e8c5a6e9c8affb251a05c233ae37098118788/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:031c57d67ca86902726e0fae2214ce6770bbe2f710dc33063187a68744a5ecac", size = 2073720, upload-time = "2025-04-23T18:30:56.11Z" }, + { url = "https://files.pythonhosted.org/packages/77/fb/2258da019f4825128445ae79456a5499c032b55849dbd5bed78c95ccf163/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:f8de619080e944347f5f20de29a975c2d815d9ddd8be9b9b7268e2e3ef68605a", size = 2244915, upload-time = "2025-04-23T18:30:57.501Z" }, + { url = "https://files.pythonhosted.org/packages/d8/7a/925ff73756031289468326e355b6fa8316960d0d65f8b5d6b3a3e7866de7/pydantic_core-2.33.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:73662edf539e72a9440129f231ed3757faab89630d291b784ca99237fb94db2b", size = 2241884, upload-time = "2025-04-23T18:30:58.867Z" }, + { url = "https://files.pythonhosted.org/packages/0b/b0/249ee6d2646f1cdadcb813805fe76265745c4010cf20a8eba7b0e639d9b2/pydantic_core-2.33.2-cp310-cp310-win32.whl", hash = "sha256:0a39979dcbb70998b0e505fb1556a1d550a0781463ce84ebf915ba293ccb7e22", size = 1910496, upload-time = "2025-04-23T18:31:00.078Z" }, + { url = "https://files.pythonhosted.org/packages/66/ff/172ba8f12a42d4b552917aa65d1f2328990d3ccfc01d5b7c943ec084299f/pydantic_core-2.33.2-cp310-cp310-win_amd64.whl", hash = "sha256:b0379a2b24882fef529ec3b4987cb5d003b9cda32256024e6fe1586ac45fc640", size = 1955019, upload-time = "2025-04-23T18:31:01.335Z" }, + { url = "https://files.pythonhosted.org/packages/3f/8d/71db63483d518cbbf290261a1fc2839d17ff89fce7089e08cad07ccfce67/pydantic_core-2.33.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4c5b0a576fb381edd6d27f0a85915c6daf2f8138dc5c267a57c08a62900758c7", size = 2028584, upload-time = "2025-04-23T18:31:03.106Z" }, + { url = "https://files.pythonhosted.org/packages/24/2f/3cfa7244ae292dd850989f328722d2aef313f74ffc471184dc509e1e4e5a/pydantic_core-2.33.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e799c050df38a639db758c617ec771fd8fb7a5f8eaaa4b27b101f266b216a246", size = 1855071, upload-time = "2025-04-23T18:31:04.621Z" }, + { url = "https://files.pythonhosted.org/packages/b3/d3/4ae42d33f5e3f50dd467761304be2fa0a9417fbf09735bc2cce003480f2a/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc46a01bf8d62f227d5ecee74178ffc448ff4e5197c756331f71efcc66dc980f", size = 1897823, upload-time = "2025-04-23T18:31:06.377Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f3/aa5976e8352b7695ff808599794b1fba2a9ae2ee954a3426855935799488/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a144d4f717285c6d9234a66778059f33a89096dfb9b39117663fd8413d582dcc", size = 1983792, upload-time = "2025-04-23T18:31:07.93Z" }, + { url = "https://files.pythonhosted.org/packages/d5/7a/cda9b5a23c552037717f2b2a5257e9b2bfe45e687386df9591eff7b46d28/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:73cf6373c21bc80b2e0dc88444f41ae60b2f070ed02095754eb5a01df12256de", size = 2136338, upload-time = "2025-04-23T18:31:09.283Z" }, + { url = "https://files.pythonhosted.org/packages/2b/9f/b8f9ec8dd1417eb9da784e91e1667d58a2a4a7b7b34cf4af765ef663a7e5/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dc625f4aa79713512d1976fe9f0bc99f706a9dee21dfd1810b4bbbf228d0e8a", size = 2730998, upload-time = "2025-04-23T18:31:11.7Z" }, + { url = "https://files.pythonhosted.org/packages/47/bc/cd720e078576bdb8255d5032c5d63ee5c0bf4b7173dd955185a1d658c456/pydantic_core-2.33.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b21b5549499972441da4758d662aeea93f1923f953e9cbaff14b8b9565aef", size = 2003200, upload-time = "2025-04-23T18:31:13.536Z" }, + { url = "https://files.pythonhosted.org/packages/ca/22/3602b895ee2cd29d11a2b349372446ae9727c32e78a94b3d588a40fdf187/pydantic_core-2.33.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bdc25f3681f7b78572699569514036afe3c243bc3059d3942624e936ec93450e", size = 2113890, upload-time = "2025-04-23T18:31:15.011Z" }, + { url = "https://files.pythonhosted.org/packages/ff/e6/e3c5908c03cf00d629eb38393a98fccc38ee0ce8ecce32f69fc7d7b558a7/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fe5b32187cbc0c862ee201ad66c30cf218e5ed468ec8dc1cf49dec66e160cc4d", size = 2073359, upload-time = "2025-04-23T18:31:16.393Z" }, + { url = "https://files.pythonhosted.org/packages/12/e7/6a36a07c59ebefc8777d1ffdaf5ae71b06b21952582e4b07eba88a421c79/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:bc7aee6f634a6f4a95676fcb5d6559a2c2a390330098dba5e5a5f28a2e4ada30", size = 2245883, upload-time = "2025-04-23T18:31:17.892Z" }, + { url = "https://files.pythonhosted.org/packages/16/3f/59b3187aaa6cc0c1e6616e8045b284de2b6a87b027cce2ffcea073adf1d2/pydantic_core-2.33.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:235f45e5dbcccf6bd99f9f472858849f73d11120d76ea8707115415f8e5ebebf", size = 2241074, upload-time = "2025-04-23T18:31:19.205Z" }, + { url = "https://files.pythonhosted.org/packages/e0/ed/55532bb88f674d5d8f67ab121a2a13c385df382de2a1677f30ad385f7438/pydantic_core-2.33.2-cp311-cp311-win32.whl", hash = "sha256:6368900c2d3ef09b69cb0b913f9f8263b03786e5b2a387706c5afb66800efd51", size = 1910538, upload-time = "2025-04-23T18:31:20.541Z" }, + { url = "https://files.pythonhosted.org/packages/fe/1b/25b7cccd4519c0b23c2dd636ad39d381abf113085ce4f7bec2b0dc755eb1/pydantic_core-2.33.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e063337ef9e9820c77acc768546325ebe04ee38b08703244c1309cccc4f1bab", size = 1952909, upload-time = "2025-04-23T18:31:22.371Z" }, + { url = "https://files.pythonhosted.org/packages/49/a9/d809358e49126438055884c4366a1f6227f0f84f635a9014e2deb9b9de54/pydantic_core-2.33.2-cp311-cp311-win_arm64.whl", hash = "sha256:6b99022f1d19bc32a4c2a0d544fc9a76e3be90f0b3f4af413f87d38749300e65", size = 1897786, upload-time = "2025-04-23T18:31:24.161Z" }, + { url = "https://files.pythonhosted.org/packages/18/8a/2b41c97f554ec8c71f2a8a5f85cb56a8b0956addfe8b0efb5b3d77e8bdc3/pydantic_core-2.33.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:a7ec89dc587667f22b6a0b6579c249fca9026ce7c333fc142ba42411fa243cdc", size = 2009000, upload-time = "2025-04-23T18:31:25.863Z" }, + { url = "https://files.pythonhosted.org/packages/a1/02/6224312aacb3c8ecbaa959897af57181fb6cf3a3d7917fd44d0f2917e6f2/pydantic_core-2.33.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3c6db6e52c6d70aa0d00d45cdb9b40f0433b96380071ea80b09277dba021ddf7", size = 1847996, upload-time = "2025-04-23T18:31:27.341Z" }, + { url = "https://files.pythonhosted.org/packages/d6/46/6dcdf084a523dbe0a0be59d054734b86a981726f221f4562aed313dbcb49/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e61206137cbc65e6d5256e1166f88331d3b6238e082d9f74613b9b765fb9025", size = 1880957, upload-time = "2025-04-23T18:31:28.956Z" }, + { url = "https://files.pythonhosted.org/packages/ec/6b/1ec2c03837ac00886ba8160ce041ce4e325b41d06a034adbef11339ae422/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eb8c529b2819c37140eb51b914153063d27ed88e3bdc31b71198a198e921e011", size = 1964199, upload-time = "2025-04-23T18:31:31.025Z" }, + { url = "https://files.pythonhosted.org/packages/2d/1d/6bf34d6adb9debd9136bd197ca72642203ce9aaaa85cfcbfcf20f9696e83/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c52b02ad8b4e2cf14ca7b3d918f3eb0ee91e63b3167c32591e57c4317e134f8f", size = 2120296, upload-time = "2025-04-23T18:31:32.514Z" }, + { url = "https://files.pythonhosted.org/packages/e0/94/2bd0aaf5a591e974b32a9f7123f16637776c304471a0ab33cf263cf5591a/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:96081f1605125ba0855dfda83f6f3df5ec90c61195421ba72223de35ccfb2f88", size = 2676109, upload-time = "2025-04-23T18:31:33.958Z" }, + { url = "https://files.pythonhosted.org/packages/f9/41/4b043778cf9c4285d59742281a769eac371b9e47e35f98ad321349cc5d61/pydantic_core-2.33.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f57a69461af2a5fa6e6bbd7a5f60d3b7e6cebb687f55106933188e79ad155c1", size = 2002028, upload-time = "2025-04-23T18:31:39.095Z" }, + { url = "https://files.pythonhosted.org/packages/cb/d5/7bb781bf2748ce3d03af04d5c969fa1308880e1dca35a9bd94e1a96a922e/pydantic_core-2.33.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:572c7e6c8bb4774d2ac88929e3d1f12bc45714ae5ee6d9a788a9fb35e60bb04b", size = 2100044, upload-time = "2025-04-23T18:31:41.034Z" }, + { url = "https://files.pythonhosted.org/packages/fe/36/def5e53e1eb0ad896785702a5bbfd25eed546cdcf4087ad285021a90ed53/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:db4b41f9bd95fbe5acd76d89920336ba96f03e149097365afe1cb092fceb89a1", size = 2058881, upload-time = "2025-04-23T18:31:42.757Z" }, + { url = "https://files.pythonhosted.org/packages/01/6c/57f8d70b2ee57fc3dc8b9610315949837fa8c11d86927b9bb044f8705419/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:fa854f5cf7e33842a892e5c73f45327760bc7bc516339fda888c75ae60edaeb6", size = 2227034, upload-time = "2025-04-23T18:31:44.304Z" }, + { url = "https://files.pythonhosted.org/packages/27/b9/9c17f0396a82b3d5cbea4c24d742083422639e7bb1d5bf600e12cb176a13/pydantic_core-2.33.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5f483cfb75ff703095c59e365360cb73e00185e01aaea067cd19acffd2ab20ea", size = 2234187, upload-time = "2025-04-23T18:31:45.891Z" }, + { url = "https://files.pythonhosted.org/packages/b0/6a/adf5734ffd52bf86d865093ad70b2ce543415e0e356f6cacabbc0d9ad910/pydantic_core-2.33.2-cp312-cp312-win32.whl", hash = "sha256:9cb1da0f5a471435a7bc7e439b8a728e8b61e59784b2af70d7c169f8dd8ae290", size = 1892628, upload-time = "2025-04-23T18:31:47.819Z" }, + { url = "https://files.pythonhosted.org/packages/43/e4/5479fecb3606c1368d496a825d8411e126133c41224c1e7238be58b87d7e/pydantic_core-2.33.2-cp312-cp312-win_amd64.whl", hash = "sha256:f941635f2a3d96b2973e867144fde513665c87f13fe0e193c158ac51bfaaa7b2", size = 1955866, upload-time = "2025-04-23T18:31:49.635Z" }, + { url = "https://files.pythonhosted.org/packages/0d/24/8b11e8b3e2be9dd82df4b11408a67c61bb4dc4f8e11b5b0fc888b38118b5/pydantic_core-2.33.2-cp312-cp312-win_arm64.whl", hash = "sha256:cca3868ddfaccfbc4bfb1d608e2ccaaebe0ae628e1416aeb9c4d88c001bb45ab", size = 1888894, upload-time = "2025-04-23T18:31:51.609Z" }, + { url = "https://files.pythonhosted.org/packages/46/8c/99040727b41f56616573a28771b1bfa08a3d3fe74d3d513f01251f79f172/pydantic_core-2.33.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:1082dd3e2d7109ad8b7da48e1d4710c8d06c253cbc4a27c1cff4fbcaa97a9e3f", size = 2015688, upload-time = "2025-04-23T18:31:53.175Z" }, + { url = "https://files.pythonhosted.org/packages/3a/cc/5999d1eb705a6cefc31f0b4a90e9f7fc400539b1a1030529700cc1b51838/pydantic_core-2.33.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f517ca031dfc037a9c07e748cefd8d96235088b83b4f4ba8939105d20fa1dcd6", size = 1844808, upload-time = "2025-04-23T18:31:54.79Z" }, + { url = "https://files.pythonhosted.org/packages/6f/5e/a0a7b8885c98889a18b6e376f344da1ef323d270b44edf8174d6bce4d622/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a9f2c9dd19656823cb8250b0724ee9c60a82f3cdf68a080979d13092a3b0fef", size = 1885580, upload-time = "2025-04-23T18:31:57.393Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2a/953581f343c7d11a304581156618c3f592435523dd9d79865903272c256a/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b0a451c263b01acebe51895bfb0e1cc842a5c666efe06cdf13846c7418caa9a", size = 1973859, upload-time = "2025-04-23T18:31:59.065Z" }, + { url = "https://files.pythonhosted.org/packages/e6/55/f1a813904771c03a3f97f676c62cca0c0a4138654107c1b61f19c644868b/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ea40a64d23faa25e62a70ad163571c0b342b8bf66d5fa612ac0dec4f069d916", size = 2120810, upload-time = "2025-04-23T18:32:00.78Z" }, + { url = "https://files.pythonhosted.org/packages/aa/c3/053389835a996e18853ba107a63caae0b9deb4a276c6b472931ea9ae6e48/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb2d542b4d66f9470e8065c5469ec676978d625a8b7a363f07d9a501a9cb36a", size = 2676498, upload-time = "2025-04-23T18:32:02.418Z" }, + { url = "https://files.pythonhosted.org/packages/eb/3c/f4abd740877a35abade05e437245b192f9d0ffb48bbbbd708df33d3cda37/pydantic_core-2.33.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fdac5d6ffa1b5a83bca06ffe7583f5576555e6c8b3a91fbd25ea7780f825f7d", size = 2000611, upload-time = "2025-04-23T18:32:04.152Z" }, + { url = "https://files.pythonhosted.org/packages/59/a7/63ef2fed1837d1121a894d0ce88439fe3e3b3e48c7543b2a4479eb99c2bd/pydantic_core-2.33.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:04a1a413977ab517154eebb2d326da71638271477d6ad87a769102f7c2488c56", size = 2107924, upload-time = "2025-04-23T18:32:06.129Z" }, + { url = "https://files.pythonhosted.org/packages/04/8f/2551964ef045669801675f1cfc3b0d74147f4901c3ffa42be2ddb1f0efc4/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c8e7af2f4e0194c22b5b37205bfb293d166a7344a5b0d0eaccebc376546d77d5", size = 2063196, upload-time = "2025-04-23T18:32:08.178Z" }, + { url = "https://files.pythonhosted.org/packages/26/bd/d9602777e77fc6dbb0c7db9ad356e9a985825547dce5ad1d30ee04903918/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:5c92edd15cd58b3c2d34873597a1e20f13094f59cf88068adb18947df5455b4e", size = 2236389, upload-time = "2025-04-23T18:32:10.242Z" }, + { url = "https://files.pythonhosted.org/packages/42/db/0e950daa7e2230423ab342ae918a794964b053bec24ba8af013fc7c94846/pydantic_core-2.33.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:65132b7b4a1c0beded5e057324b7e16e10910c106d43675d9bd87d4f38dde162", size = 2239223, upload-time = "2025-04-23T18:32:12.382Z" }, + { url = "https://files.pythonhosted.org/packages/58/4d/4f937099c545a8a17eb52cb67fe0447fd9a373b348ccfa9a87f141eeb00f/pydantic_core-2.33.2-cp313-cp313-win32.whl", hash = "sha256:52fb90784e0a242bb96ec53f42196a17278855b0f31ac7c3cc6f5c1ec4811849", size = 1900473, upload-time = "2025-04-23T18:32:14.034Z" }, + { url = "https://files.pythonhosted.org/packages/a0/75/4a0a9bac998d78d889def5e4ef2b065acba8cae8c93696906c3a91f310ca/pydantic_core-2.33.2-cp313-cp313-win_amd64.whl", hash = "sha256:c083a3bdd5a93dfe480f1125926afcdbf2917ae714bdb80b36d34318b2bec5d9", size = 1955269, upload-time = "2025-04-23T18:32:15.783Z" }, + { url = "https://files.pythonhosted.org/packages/f9/86/1beda0576969592f1497b4ce8e7bc8cbdf614c352426271b1b10d5f0aa64/pydantic_core-2.33.2-cp313-cp313-win_arm64.whl", hash = "sha256:e80b087132752f6b3d714f041ccf74403799d3b23a72722ea2e6ba2e892555b9", size = 1893921, upload-time = "2025-04-23T18:32:18.473Z" }, + { url = "https://files.pythonhosted.org/packages/a4/7d/e09391c2eebeab681df2b74bfe6c43422fffede8dc74187b2b0bf6fd7571/pydantic_core-2.33.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61c18fba8e5e9db3ab908620af374db0ac1baa69f0f32df4f61ae23f15e586ac", size = 1806162, upload-time = "2025-04-23T18:32:20.188Z" }, + { url = "https://files.pythonhosted.org/packages/f1/3d/847b6b1fed9f8ed3bb95a9ad04fbd0b212e832d4f0f50ff4d9ee5a9f15cf/pydantic_core-2.33.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95237e53bb015f67b63c91af7518a62a8660376a6a0db19b89acc77a4d6199f5", size = 1981560, upload-time = "2025-04-23T18:32:22.354Z" }, + { url = "https://files.pythonhosted.org/packages/6f/9a/e73262f6c6656262b5fdd723ad90f518f579b7bc8622e43a942eec53c938/pydantic_core-2.33.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c2fc0a768ef76c15ab9238afa6da7f69895bb5d1ee83aeea2e3509af4472d0b9", size = 1935777, upload-time = "2025-04-23T18:32:25.088Z" }, + { url = "https://files.pythonhosted.org/packages/53/ea/bbe9095cdd771987d13c82d104a9c8559ae9aec1e29f139e286fd2e9256e/pydantic_core-2.33.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:a2b911a5b90e0374d03813674bf0a5fbbb7741570dcd4b4e85a2e48d17def29d", size = 2028677, upload-time = "2025-04-23T18:32:27.227Z" }, + { url = "https://files.pythonhosted.org/packages/49/1d/4ac5ed228078737d457a609013e8f7edc64adc37b91d619ea965758369e5/pydantic_core-2.33.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6fa6dfc3e4d1f734a34710f391ae822e0a8eb8559a85c6979e14e65ee6ba2954", size = 1864735, upload-time = "2025-04-23T18:32:29.019Z" }, + { url = "https://files.pythonhosted.org/packages/23/9a/2e70d6388d7cda488ae38f57bc2f7b03ee442fbcf0d75d848304ac7e405b/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c54c939ee22dc8e2d545da79fc5381f1c020d6d3141d3bd747eab59164dc89fb", size = 1898467, upload-time = "2025-04-23T18:32:31.119Z" }, + { url = "https://files.pythonhosted.org/packages/ff/2e/1568934feb43370c1ffb78a77f0baaa5a8b6897513e7a91051af707ffdc4/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53a57d2ed685940a504248187d5685e49eb5eef0f696853647bf37c418c538f7", size = 1983041, upload-time = "2025-04-23T18:32:33.655Z" }, + { url = "https://files.pythonhosted.org/packages/01/1a/1a1118f38ab64eac2f6269eb8c120ab915be30e387bb561e3af904b12499/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09fb9dd6571aacd023fe6aaca316bd01cf60ab27240d7eb39ebd66a3a15293b4", size = 2136503, upload-time = "2025-04-23T18:32:35.519Z" }, + { url = "https://files.pythonhosted.org/packages/5c/da/44754d1d7ae0f22d6d3ce6c6b1486fc07ac2c524ed8f6eca636e2e1ee49b/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0e6116757f7959a712db11f3e9c0a99ade00a5bbedae83cb801985aa154f071b", size = 2736079, upload-time = "2025-04-23T18:32:37.659Z" }, + { url = "https://files.pythonhosted.org/packages/4d/98/f43cd89172220ec5aa86654967b22d862146bc4d736b1350b4c41e7c9c03/pydantic_core-2.33.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d55ab81c57b8ff8548c3e4947f119551253f4e3787a7bbc0b6b3ca47498a9d3", size = 2006508, upload-time = "2025-04-23T18:32:39.637Z" }, + { url = "https://files.pythonhosted.org/packages/2b/cc/f77e8e242171d2158309f830f7d5d07e0531b756106f36bc18712dc439df/pydantic_core-2.33.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c20c462aa4434b33a2661701b861604913f912254e441ab8d78d30485736115a", size = 2113693, upload-time = "2025-04-23T18:32:41.818Z" }, + { url = "https://files.pythonhosted.org/packages/54/7a/7be6a7bd43e0a47c147ba7fbf124fe8aaf1200bc587da925509641113b2d/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:44857c3227d3fb5e753d5fe4a3420d6376fa594b07b621e220cd93703fe21782", size = 2074224, upload-time = "2025-04-23T18:32:44.033Z" }, + { url = "https://files.pythonhosted.org/packages/2a/07/31cf8fadffbb03be1cb520850e00a8490c0927ec456e8293cafda0726184/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:eb9b459ca4df0e5c87deb59d37377461a538852765293f9e6ee834f0435a93b9", size = 2245403, upload-time = "2025-04-23T18:32:45.836Z" }, + { url = "https://files.pythonhosted.org/packages/b6/8d/bbaf4c6721b668d44f01861f297eb01c9b35f612f6b8e14173cb204e6240/pydantic_core-2.33.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9fcd347d2cc5c23b06de6d3b7b8275be558a0c90549495c699e379a80bf8379e", size = 2242331, upload-time = "2025-04-23T18:32:47.618Z" }, + { url = "https://files.pythonhosted.org/packages/bb/93/3cc157026bca8f5006250e74515119fcaa6d6858aceee8f67ab6dc548c16/pydantic_core-2.33.2-cp39-cp39-win32.whl", hash = "sha256:83aa99b1285bc8f038941ddf598501a86f1536789740991d7d8756e34f1e74d9", size = 1910571, upload-time = "2025-04-23T18:32:49.401Z" }, + { url = "https://files.pythonhosted.org/packages/5b/90/7edc3b2a0d9f0dda8806c04e511a67b0b7a41d2187e2003673a996fb4310/pydantic_core-2.33.2-cp39-cp39-win_amd64.whl", hash = "sha256:f481959862f57f29601ccced557cc2e817bce7533ab8e01a797a48b49c9692b3", size = 1956504, upload-time = "2025-04-23T18:32:51.287Z" }, + { url = "https://files.pythonhosted.org/packages/30/68/373d55e58b7e83ce371691f6eaa7175e3a24b956c44628eb25d7da007917/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c4aa4e82353f65e548c476b37e64189783aa5384903bfea4f41580f255fddfa", size = 2023982, upload-time = "2025-04-23T18:32:53.14Z" }, + { url = "https://files.pythonhosted.org/packages/a4/16/145f54ac08c96a63d8ed6442f9dec17b2773d19920b627b18d4f10a061ea/pydantic_core-2.33.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d946c8bf0d5c24bf4fe333af284c59a19358aa3ec18cb3dc4370080da1e8ad29", size = 1858412, upload-time = "2025-04-23T18:32:55.52Z" }, + { url = "https://files.pythonhosted.org/packages/41/b1/c6dc6c3e2de4516c0bb2c46f6a373b91b5660312342a0cf5826e38ad82fa/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87b31b6846e361ef83fedb187bb5b4372d0da3f7e28d85415efa92d6125d6e6d", size = 1892749, upload-time = "2025-04-23T18:32:57.546Z" }, + { url = "https://files.pythonhosted.org/packages/12/73/8cd57e20afba760b21b742106f9dbdfa6697f1570b189c7457a1af4cd8a0/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa9d91b338f2df0508606f7009fde642391425189bba6d8c653afd80fd6bb64e", size = 2067527, upload-time = "2025-04-23T18:32:59.771Z" }, + { url = "https://files.pythonhosted.org/packages/e3/d5/0bb5d988cc019b3cba4a78f2d4b3854427fc47ee8ec8e9eaabf787da239c/pydantic_core-2.33.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2058a32994f1fde4ca0480ab9d1e75a0e8c87c22b53a3ae66554f9af78f2fe8c", size = 2108225, upload-time = "2025-04-23T18:33:04.51Z" }, + { url = "https://files.pythonhosted.org/packages/f1/c5/00c02d1571913d496aabf146106ad8239dc132485ee22efe08085084ff7c/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0e03262ab796d986f978f79c943fc5f620381be7287148b8010b4097f79a39ec", size = 2069490, upload-time = "2025-04-23T18:33:06.391Z" }, + { url = "https://files.pythonhosted.org/packages/22/a8/dccc38768274d3ed3a59b5d06f59ccb845778687652daa71df0cab4040d7/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:1a8695a8d00c73e50bff9dfda4d540b7dee29ff9b8053e38380426a85ef10052", size = 2237525, upload-time = "2025-04-23T18:33:08.44Z" }, + { url = "https://files.pythonhosted.org/packages/d4/e7/4f98c0b125dda7cf7ccd14ba936218397b44f50a56dd8c16a3091df116c3/pydantic_core-2.33.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fa754d1850735a0b0e03bcffd9d4b4343eb417e47196e4485d9cca326073a42c", size = 2238446, upload-time = "2025-04-23T18:33:10.313Z" }, + { url = "https://files.pythonhosted.org/packages/ce/91/2ec36480fdb0b783cd9ef6795753c1dea13882f2e68e73bce76ae8c21e6a/pydantic_core-2.33.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a11c8d26a50bfab49002947d3d237abe4d9e4b5bdc8846a63537b6488e197808", size = 2066678, upload-time = "2025-04-23T18:33:12.224Z" }, + { url = "https://files.pythonhosted.org/packages/7b/27/d4ae6487d73948d6f20dddcd94be4ea43e74349b56eba82e9bdee2d7494c/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:dd14041875d09cc0f9308e37a6f8b65f5585cf2598a53aa0123df8b129d481f8", size = 2025200, upload-time = "2025-04-23T18:33:14.199Z" }, + { url = "https://files.pythonhosted.org/packages/f1/b8/b3cb95375f05d33801024079b9392a5ab45267a63400bf1866e7ce0f0de4/pydantic_core-2.33.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d87c561733f66531dced0da6e864f44ebf89a8fba55f31407b00c2f7f9449593", size = 1859123, upload-time = "2025-04-23T18:33:16.555Z" }, + { url = "https://files.pythonhosted.org/packages/05/bc/0d0b5adeda59a261cd30a1235a445bf55c7e46ae44aea28f7bd6ed46e091/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f82865531efd18d6e07a04a17331af02cb7a651583c418df8266f17a63c6612", size = 1892852, upload-time = "2025-04-23T18:33:18.513Z" }, + { url = "https://files.pythonhosted.org/packages/3e/11/d37bdebbda2e449cb3f519f6ce950927b56d62f0b84fd9cb9e372a26a3d5/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bfb5112df54209d820d7bf9317c7a6c9025ea52e49f46b6a2060104bba37de7", size = 2067484, upload-time = "2025-04-23T18:33:20.475Z" }, + { url = "https://files.pythonhosted.org/packages/8c/55/1f95f0a05ce72ecb02a8a8a1c3be0579bbc29b1d5ab68f1378b7bebc5057/pydantic_core-2.33.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:64632ff9d614e5eecfb495796ad51b0ed98c453e447a76bcbeeb69615079fc7e", size = 2108896, upload-time = "2025-04-23T18:33:22.501Z" }, + { url = "https://files.pythonhosted.org/packages/53/89/2b2de6c81fa131f423246a9109d7b2a375e83968ad0800d6e57d0574629b/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f889f7a40498cc077332c7ab6b4608d296d852182211787d4f3ee377aaae66e8", size = 2069475, upload-time = "2025-04-23T18:33:24.528Z" }, + { url = "https://files.pythonhosted.org/packages/b8/e9/1f7efbe20d0b2b10f6718944b5d8ece9152390904f29a78e68d4e7961159/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:de4b83bb311557e439b9e186f733f6c645b9417c84e2eb8203f3f820a4b988bf", size = 2239013, upload-time = "2025-04-23T18:33:26.621Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b2/5309c905a93811524a49b4e031e9851a6b00ff0fb668794472ea7746b448/pydantic_core-2.33.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:82f68293f055f51b51ea42fafc74b6aad03e70e191799430b90c13d643059ebb", size = 2238715, upload-time = "2025-04-23T18:33:28.656Z" }, + { url = "https://files.pythonhosted.org/packages/32/56/8a7ca5d2cd2cda1d245d34b1c9a942920a718082ae8e54e5f3e5a58b7add/pydantic_core-2.33.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:329467cecfb529c925cf2bbd4d60d2c509bc2fb52a20c1045bf09bb70971a9c1", size = 2066757, upload-time = "2025-04-23T18:33:30.645Z" }, + { url = "https://files.pythonhosted.org/packages/08/98/dbf3fdfabaf81cda5622154fda78ea9965ac467e3239078e0dcd6df159e7/pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:87acbfcf8e90ca885206e98359d7dca4bcbb35abdc0ff66672a293e1d7a19101", size = 2024034, upload-time = "2025-04-23T18:33:32.843Z" }, + { url = "https://files.pythonhosted.org/packages/8d/99/7810aa9256e7f2ccd492590f86b79d370df1e9292f1f80b000b6a75bd2fb/pydantic_core-2.33.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f92c15cd1e97d4b12acd1cc9004fa092578acfa57b67ad5e43a197175d01a64", size = 1858578, upload-time = "2025-04-23T18:33:34.912Z" }, + { url = "https://files.pythonhosted.org/packages/d8/60/bc06fa9027c7006cc6dd21e48dbf39076dc39d9abbaf718a1604973a9670/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3f26877a748dc4251cfcfda9dfb5f13fcb034f5308388066bcfe9031b63ae7d", size = 1892858, upload-time = "2025-04-23T18:33:36.933Z" }, + { url = "https://files.pythonhosted.org/packages/f2/40/9d03997d9518816c68b4dfccb88969756b9146031b61cd37f781c74c9b6a/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac89aea9af8cd672fa7b510e7b8c33b0bba9a43186680550ccf23020f32d535", size = 2068498, upload-time = "2025-04-23T18:33:38.997Z" }, + { url = "https://files.pythonhosted.org/packages/d8/62/d490198d05d2d86672dc269f52579cad7261ced64c2df213d5c16e0aecb1/pydantic_core-2.33.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:970919794d126ba8645f3837ab6046fb4e72bbc057b3709144066204c19a455d", size = 2108428, upload-time = "2025-04-23T18:33:41.18Z" }, + { url = "https://files.pythonhosted.org/packages/9a/ec/4cd215534fd10b8549015f12ea650a1a973da20ce46430b68fc3185573e8/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3eb3fe62804e8f859c49ed20a8451342de53ed764150cb14ca71357c765dc2a6", size = 2069854, upload-time = "2025-04-23T18:33:43.446Z" }, + { url = "https://files.pythonhosted.org/packages/1a/1a/abbd63d47e1d9b0d632fee6bb15785d0889c8a6e0a6c3b5a8e28ac1ec5d2/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:3abcd9392a36025e3bd55f9bd38d908bd17962cc49bc6da8e7e96285336e2bca", size = 2237859, upload-time = "2025-04-23T18:33:45.56Z" }, + { url = "https://files.pythonhosted.org/packages/80/1c/fa883643429908b1c90598fd2642af8839efd1d835b65af1f75fba4d94fe/pydantic_core-2.33.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:3a1c81334778f9e3af2f8aeb7a960736e5cab1dfebfb26aabca09afd2906c039", size = 2239059, upload-time = "2025-04-23T18:33:47.735Z" }, + { url = "https://files.pythonhosted.org/packages/d4/29/3cade8a924a61f60ccfa10842f75eb12787e1440e2b8660ceffeb26685e7/pydantic_core-2.33.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2807668ba86cb38c6817ad9bc66215ab8584d1d304030ce4f0887336f28a5e27", size = 2066661, upload-time = "2025-04-23T18:33:49.995Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pytest" +version = "8.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, +] + +[[package]] +name = "pytest-asyncio" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "backports-asyncio-runner", marker = "python_full_version < '3.11'" }, + { name = "pytest" }, + { name = "typing-extensions", marker = "python_full_version < '3.10'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4e/51/f8794af39eeb870e87a8c8068642fc07bce0c854d6865d7dd0f2a9d338c2/pytest_asyncio-1.1.0.tar.gz", hash = "sha256:796aa822981e01b68c12e4827b8697108f7205020f24b5793b3c41555dab68ea", size = 46652, upload-time = "2025-07-16T04:29:26.393Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/9d/bf86eddabf8c6c9cb1ea9a869d6873b46f105a5d292d3a6f7071f5b07935/pytest_asyncio-1.1.0-py3-none-any.whl", hash = "sha256:5fe2d69607b0bd75c656d1211f969cadba035030156745ee09e7d71740e58ecf", size = 15157, upload-time = "2025-07-16T04:29:24.929Z" }, +] + [[package]] name = "ruff" version = "0.12.8" @@ -584,6 +852,45 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cb/5c/799a1efb8b5abab56e8a9f2a0b72d12bd64bb55815e9476c7d0a2887d2f7/ruff-0.12.8-py3-none-win_arm64.whl", hash = "sha256:c90e1a334683ce41b0e7a04f41790c429bf5073b62c1ae701c9dc5b3d14f0749", size = 11884718, upload-time = "2025-08-07T19:05:42.866Z" }, ] +[[package]] +name = "tomli" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077, upload-time = "2024-11-27T22:37:54.956Z" }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429, upload-time = "2024-11-27T22:37:56.698Z" }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067, upload-time = "2024-11-27T22:37:57.63Z" }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030, upload-time = "2024-11-27T22:37:59.344Z" }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898, upload-time = "2024-11-27T22:38:00.429Z" }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894, upload-time = "2024-11-27T22:38:02.094Z" }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319, upload-time = "2024-11-27T22:38:03.206Z" }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273, upload-time = "2024-11-27T22:38:04.217Z" }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310, upload-time = "2024-11-27T22:38:05.908Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309, upload-time = "2024-11-27T22:38:06.812Z" }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload-time = "2024-11-27T22:38:07.731Z" }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload-time = "2024-11-27T22:38:09.384Z" }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload-time = "2024-11-27T22:38:10.329Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload-time = "2024-11-27T22:38:11.443Z" }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload-time = "2024-11-27T22:38:13.099Z" }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload-time = "2024-11-27T22:38:14.766Z" }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload-time = "2024-11-27T22:38:15.843Z" }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload-time = "2024-11-27T22:38:17.645Z" }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload-time = "2024-11-27T22:38:19.159Z" }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload-time = "2024-11-27T22:38:20.064Z" }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708, upload-time = "2024-11-27T22:38:21.659Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582, upload-time = "2024-11-27T22:38:22.693Z" }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543, upload-time = "2024-11-27T22:38:24.367Z" }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691, upload-time = "2024-11-27T22:38:26.081Z" }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170, upload-time = "2024-11-27T22:38:27.921Z" }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530, upload-time = "2024-11-27T22:38:29.591Z" }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666, upload-time = "2024-11-27T22:38:30.639Z" }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954, upload-time = "2024-11-27T22:38:31.702Z" }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724, upload-time = "2024-11-27T22:38:32.837Z" }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383, upload-time = "2024-11-27T22:38:34.455Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" }, +] + [[package]] name = "typing-extensions" version = "4.14.1" @@ -593,6 +900,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/b5/00/d631e67a838026495268c2f6884f3711a15a9a2a96cd244fdaea53b823fb/typing_extensions-4.14.1-py3-none-any.whl", hash = "sha256:d1e1e3b58374dc93031d6eda2420a48ea44a36c2b4766a4fdeb3710755731d76", size = 43906, upload-time = "2025-07-04T13:28:32.743Z" }, ] +[[package]] +name = "typing-inspection" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, +] + [[package]] name = "yarl" version = "1.20.1" @@ -708,3 +1027,93 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d7/cd/ce185848a7dba68ea69e932674b5c1a42a1852123584bccc5443120f857c/yarl-1.20.1-cp39-cp39-win_amd64.whl", hash = "sha256:eae7bfe2069f9c1c5b05fc7fe5d612e5bbc089a39309904ee8b829e322dcad00", size = 87385, upload-time = "2025-06-10T00:46:05.655Z" }, { url = "https://files.pythonhosted.org/packages/b4/2d/2345fce04cfd4bee161bf1e7d9cdc702e3e16109021035dbb24db654a622/yarl-1.20.1-py3-none-any.whl", hash = "sha256:83b8eb083fe4683c6115795d9fc1cfaf2cbbefb19b3a1cb68f6527460f483a77", size = 46542, upload-time = "2025-06-10T00:46:07.521Z" }, ] + +[[package]] +name = "zeroconf" +version = "0.147.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ifaddr" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e2/78/f681afade2a4e7a9ade696cf3d3dcd9905e28720d74c16cafb83b5dd5c0a/zeroconf-0.147.0.tar.gz", hash = "sha256:f517375de6bf2041df826130da41dc7a3e8772176d3076a5da58854c7d2e8d7a", size = 163958, upload-time = "2025-05-03T16:24:54.207Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/a2/eca16ae55b22e76c819950917ce523a87e4fb77e9e915bb0188fd3e47b3f/zeroconf-0.147.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:de0e1439c90df08fbb59d07445904aa9cb0ed3c548bb2f89a8a7bb3fa50071cd", size = 1837544, upload-time = "2025-05-03T16:58:09.796Z" }, + { url = "https://files.pythonhosted.org/packages/83/d6/080c8059b1b624c6654ef6373b620118c41fae935d76ac7b10582a2b41e2/zeroconf-0.147.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2b8776e5e3ba7f19578a6baffa231f148390156a231eb17924c30e192ec9b00", size = 1697541, upload-time = "2025-05-03T16:58:11.344Z" }, + { url = "https://files.pythonhosted.org/packages/c0/66/0fd2a20271b3dd6f0013b22ec72375fd0b088e7e4bec4da1e0e3cfd3fb0d/zeroconf-0.147.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a80cf348e8a1c597a427b500cf5327adf1a1402b010c84ba78b39ea7d3d7598", size = 2249406, upload-time = "2025-05-03T16:58:13.366Z" }, + { url = "https://files.pythonhosted.org/packages/db/a3/3aa509c8e844f8d35e73a4aa2cd6578fa2ba2ee2355f2e547a598fda4bf7/zeroconf-0.147.0-cp310-cp310-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:8014da8e9d1efa04df8091c60bc8e23a25d6374b2f99f2ba515ca8d7d6d9b271", size = 2420345, upload-time = "2025-05-03T16:58:15.179Z" }, + { url = "https://files.pythonhosted.org/packages/d1/fa/32e8522efe13053dabb61ea6f42e9b7de362c8cd4cc16b6c3a8d80220ef4/zeroconf-0.147.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a6c359af0ff3ac50812c9bdbeb006279bb4c401d721f1f22651522f73237295", size = 2369104, upload-time = "2025-05-03T16:58:17.131Z" }, + { url = "https://files.pythonhosted.org/packages/c5/42/629a1f7819e3ad474ca25c5d85b5da1e6bbd6ca2d5b3c96c2556a1802beb/zeroconf-0.147.0-cp310-cp310-manylinux_2_31_armv7l.manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8d6e3d598bff4c07b61e7be89a56aa75ef3e2e2a6622881b76a0d06ef527fc39", size = 2154137, upload-time = "2025-05-03T16:58:18.703Z" }, + { url = "https://files.pythonhosted.org/packages/4b/34/23f00b3b9ed879c946c838d39bf340ab79c62bbc60b67e286ab9ee30d0f2/zeroconf-0.147.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ecb83e1b27eb8a9f14bc5458b4f87594d24d5f206dbaefae93021a702a311905", size = 2384547, upload-time = "2025-05-03T16:58:20.469Z" }, + { url = "https://files.pythonhosted.org/packages/4e/16/8a8a425a929809e5077fa6bfb02ffc99c504714af232616dd9d15f191c52/zeroconf-0.147.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:f8cb0b47eb18f2340505f5106adc2dc698a131785c6e0e6ca56f9f5c09ef6469", size = 2181289, upload-time = "2025-05-03T16:58:22.175Z" }, + { url = "https://files.pythonhosted.org/packages/c3/fa/b3ab8ce519ec62b8e083942c4a7a3b6a29c9696bc34cc711af8fe542ef9b/zeroconf-0.147.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:7204d4d41ef95021acc3ff7a7d3266558ea2032a167a3591c4fb570cc64b522c", size = 2571559, upload-time = "2025-05-03T16:58:23.665Z" }, + { url = "https://files.pythonhosted.org/packages/42/c3/6aba15defcee211aa4ab6d2f29920ee2b377fa3495f4366047fec05073fa/zeroconf-0.147.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:a37e54a991e9e7203650f7884a44097616bed9c050f19db50316abda409ab208", size = 2524876, upload-time = "2025-05-03T16:58:25.311Z" }, + { url = "https://files.pythonhosted.org/packages/84/49/52a0817d08c3ca8dcffc7e98e99d4931e5086139f79d002ff23c2f81f64a/zeroconf-0.147.0-cp310-cp310-win32.whl", hash = "sha256:df1dfdf49fcff8bacc7d490eeafeb3d74aea5588f78a459b76994b7acf3fe513", size = 1431122, upload-time = "2025-05-03T16:58:27.319Z" }, + { url = "https://files.pythonhosted.org/packages/2d/30/46d073e5e17f2e27f7a19809359df9bda19d713d1aac3e3ee1f5d5d77a8d/zeroconf-0.147.0-cp310-cp310-win_amd64.whl", hash = "sha256:1f0d3c119e77ec960d03ad5b92e651e5cc8c49d5521cbd58a561f8db709c79cc", size = 1660340, upload-time = "2025-05-03T16:58:29.363Z" }, + { url = "https://files.pythonhosted.org/packages/3c/d8/15819dc7c1f9fdd02d72ebf5fec5e8575abae7de9c3887d37adc25de9b38/zeroconf-0.147.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2f36096616f89f3aec678613316014e3a35e293c3c2e26466695d91688c49a34", size = 1841597, upload-time = "2025-05-03T16:58:31.018Z" }, + { url = "https://files.pythonhosted.org/packages/19/78/d7033a7eb2b0e7b875e5578d22de52b4553d5ce49deca1b1a316f97c8ee1/zeroconf-0.147.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:abb3f45ce14fdbcf70d2cb711714553e20e704cc2d86988125936d853f01c132", size = 1699441, upload-time = "2025-05-03T16:58:32.566Z" }, + { url = "https://files.pythonhosted.org/packages/22/53/c0883d7342ba30c1a5c4cce17afc7b41e703771f14516c95328f7e800d2a/zeroconf-0.147.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f511b32c1693f5f76acea9ce7add629ed62071f001929d818bea09aaa2c2969", size = 2245810, upload-time = "2025-05-03T16:58:34.128Z" }, + { url = "https://files.pythonhosted.org/packages/15/e9/b12823125c41f20056c83a541554b26d65ab5f2ede684232f1c0f05ad26b/zeroconf-0.147.0-cp311-cp311-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:6269129298004531b0b809a32bfe82865e8641f7940647c33a0b9c9e36012187", size = 2410474, upload-time = "2025-05-03T16:58:35.749Z" }, + { url = "https://files.pythonhosted.org/packages/cc/fd/90d3b23d4477176ec6c95c2bdbe795aeeb1659ab026321e577b1ab0ba1ee/zeroconf-0.147.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed2b6369a50e4a27667a6c80011ff276d63d205f8ccf5771f9fceddb0c9ce6b4", size = 2356775, upload-time = "2025-05-03T16:58:37.802Z" }, + { url = "https://files.pythonhosted.org/packages/b5/0a/7c0762c416dcaf80023febce9a1692694056a4f43aed93a939647a1c0991/zeroconf-0.147.0-cp311-cp311-manylinux_2_31_armv7l.manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:02205731db993193034b0f5cc5108e2cf2c580e445ff401be05ea80aeb762c7c", size = 2146315, upload-time = "2025-05-03T16:58:39.849Z" }, + { url = "https://files.pythonhosted.org/packages/83/e0/159a36eef4cc5c63b34fc1af7af4f1cfae94155f0447507555cee0879af7/zeroconf-0.147.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5bd0984a2f457d399e414622941cce30bb52bd9bcbfc0594a266ed724a030469", size = 2386446, upload-time = "2025-05-03T16:58:41.635Z" }, + { url = "https://files.pythonhosted.org/packages/ab/16/307a43f141f4da6f9f505412e6cfdc9ca8dbe5653ae87a2537b906047c3b/zeroconf-0.147.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:e4a1ccbbbeb3c5e1867f38aee18647245069ca01572f6e9188d549f294f2ac77", size = 2180777, upload-time = "2025-05-03T16:58:43.728Z" }, + { url = "https://files.pythonhosted.org/packages/07/47/4e12c0e215f10d507c9e6fc2a33b905fd1fa6341d382fe398ab05123bbd5/zeroconf-0.147.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9f2b7f930407403f9813525537a78613510d9c394a11328cafb8bb46f060d89e", size = 2564745, upload-time = "2025-05-03T16:58:45.339Z" }, + { url = "https://files.pythonhosted.org/packages/4a/f6/5b9e7946603ed4f5b542b182534d39ff2099d6f03f4a951dd9493a823627/zeroconf-0.147.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f7b6ee515a76bb983b26590eda099d57fede043f3b753427ff9dc4e1c7405395", size = 2532320, upload-time = "2025-05-03T16:58:47.077Z" }, + { url = "https://files.pythonhosted.org/packages/59/bf/ae9739c035273f0e04c51a806d1ae0113df24e08791be39e7408e7a7d10c/zeroconf-0.147.0-cp311-cp311-win32.whl", hash = "sha256:3dec7640d85362d70a2e4c89e34e0c865f41c00073378597afdac0a2e146b061", size = 1427811, upload-time = "2025-05-03T16:58:49.347Z" }, + { url = "https://files.pythonhosted.org/packages/d7/f1/43bc2388d8e7e342e115625be928d731a84e66aef42bbcb9c484b5776d8b/zeroconf-0.147.0-cp311-cp311-win_amd64.whl", hash = "sha256:5c8962eb8c829fd22bbda2ec23443e6e14e6f44adf2a823da0f074a941d8b8e7", size = 1663520, upload-time = "2025-05-03T16:58:51.416Z" }, + { url = "https://files.pythonhosted.org/packages/28/72/551e19b1066a930b4e2d7114c9ba8217be46b17d46b95b7b256842d4bfb9/zeroconf-0.147.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:89542174ec4f1e86ba428cab19a33c77378dcac0ee37577df8859af849cf736e", size = 1863387, upload-time = "2025-05-03T16:58:53.088Z" }, + { url = "https://files.pythonhosted.org/packages/1c/3a/8cb2ce2022417b20f3d63a4411d21d21d1a01366d89f0cd451c0f42d775f/zeroconf-0.147.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0086b8c280fc3410fa887a0da68cc6dc5a7d1da8a57157f6c7e4acb029674ce9", size = 1717362, upload-time = "2025-05-03T16:58:54.766Z" }, + { url = "https://files.pythonhosted.org/packages/fd/33/6c52100705bc118b77d1516499f737074a9da7965f268243234d21fa872b/zeroconf-0.147.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04018f48c38fa174af8e2c6cd00e6fb8a9a7269a187ba1f52cf32c14f2ddd941", size = 2155929, upload-time = "2025-05-03T16:58:56.456Z" }, + { url = "https://files.pythonhosted.org/packages/67/ca/d6cc026655f8bc894c0f03c153f10f4c2cd091d088c13a3cafaea771cd1e/zeroconf-0.147.0-cp312-cp312-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:71a5690ad94a8b5809bb3888e3c30de943458b9fb751730fa9a60e580d1b47ca", size = 2327718, upload-time = "2025-05-03T16:58:58.224Z" }, + { url = "https://files.pythonhosted.org/packages/fa/11/6499c380e8e7f8d24586ed8fc6339079541b4ac244a39fe2b65558140917/zeroconf-0.147.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34b5f1f472eadd090232af6b52c16c417359d9541e7bb31afbde3a0e33e55594", size = 2270324, upload-time = "2025-05-03T16:59:00.356Z" }, + { url = "https://files.pythonhosted.org/packages/c0/99/28c0ec3b2a47b6e7c65ea50213ac4d3851554fe7f2bd520d0bbc9a8ea5c5/zeroconf-0.147.0-cp312-cp312-manylinux_2_31_armv7l.manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:213b9ebdb5876d7b30515e2850d250625ac1a5c54b022a0fb407ea25af39251f", size = 2109142, upload-time = "2025-05-03T16:59:02.145Z" }, + { url = "https://files.pythonhosted.org/packages/2c/a6/96207513fe3e69adcd6694fe58f3802903f0fdcc2473bd709b4f96bceea3/zeroconf-0.147.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:10e75e41160f376b7b43a242ffeee5803878fd31d30991eb60cd1d0949373d51", size = 2298105, upload-time = "2025-05-03T16:59:05.395Z" }, + { url = "https://files.pythonhosted.org/packages/d9/30/0068cfd5189fd149507e62ee44e4e10adb2ed4f5cc23084a737f479da8e7/zeroconf-0.147.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d7b488d1a74bac55080a9cadb6b8690f0aefa89ae8130485557bc53ba866d445", size = 2158683, upload-time = "2025-05-03T16:59:07.53Z" }, + { url = "https://files.pythonhosted.org/packages/60/ea/60d3fb09d15ae60ebddc489eeba1e3af85642242744db0504599403c0668/zeroconf-0.147.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a3f6d9c6c226a7fd6669584dfcb8160a60b8711f00229a8d7347451447b220e2", size = 2500325, upload-time = "2025-05-03T16:59:10.369Z" }, + { url = "https://files.pythonhosted.org/packages/d0/91/1505222cdb1164a34412c372a88eeee30933fd24f73e5113d7496c551136/zeroconf-0.147.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:137d83815347e0ede605f9d7a0d5253f95d62a9872f291a123679c4a01e016bb", size = 2465882, upload-time = "2025-05-03T16:59:12.166Z" }, + { url = "https://files.pythonhosted.org/packages/e8/26/ad45cfdb58c5b56750101a660d4e3f3b30562b17cff1be8d801190c35095/zeroconf-0.147.0-cp312-cp312-win32.whl", hash = "sha256:1ae71afd284f07d9a46acf69674efef283c039f5e326250c29578e0605f7dac6", size = 1431330, upload-time = "2025-05-03T16:59:13.947Z" }, + { url = "https://files.pythonhosted.org/packages/ac/4d/e287db04c2c95cdf3a9e99a897a54ab798e010ce14dff710c5f745e996c3/zeroconf-0.147.0-cp312-cp312-win_amd64.whl", hash = "sha256:e66b2044a626f20bc4ddab92de662b4f4bce8e4f1e85672d88186c9e776505a1", size = 1660798, upload-time = "2025-05-03T16:59:15.653Z" }, + { url = "https://files.pythonhosted.org/packages/ad/83/c6ee14c962b79f616f8f987a52244e877647db3846007fc167f481a81b7d/zeroconf-0.147.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1deedbedea7402754b3a1a05a2a1c881443451ccd600b2a7f979e97dd9fcbe6d", size = 1841229, upload-time = "2025-05-03T16:59:17.783Z" }, + { url = "https://files.pythonhosted.org/packages/91/c0/42c08a8b2c5b6052d48a5517a5d05076b8ee2c0a458ea9bd5e0e2be38c01/zeroconf-0.147.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5c57d551e65a2a9b6333b685e3b074601f6e85762e4b4a490c663f1f2e215b24", size = 1697806, upload-time = "2025-05-03T16:59:20.083Z" }, + { url = "https://files.pythonhosted.org/packages/bf/79/d9b440786d62626f2ca4bd692b6c2bbd1e70e1124c56321bac6a2212a5eb/zeroconf-0.147.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:095bdb0cd369355ff919e3be930991b38557baaa8292d82f4a4a8567a3944f05", size = 2141482, upload-time = "2025-05-03T16:59:22.067Z" }, + { url = "https://files.pythonhosted.org/packages/48/12/ab7d31620892a7f4d446a3f0261ddb1198318348c039b4a5ec7d9d09579c/zeroconf-0.147.0-cp313-cp313-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:8ae0fe0bb947b3a128af586c76a16b5a7d027daa65e67637b042c745f9b136c4", size = 2315614, upload-time = "2025-05-03T16:59:24.091Z" }, + { url = "https://files.pythonhosted.org/packages/7b/48/2de072ee42e36328e1d80408b70eddf3df0a5b9640db188caa363b3e120f/zeroconf-0.147.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cbeea4d8d0c4f6eb5a82099d53f5729b628685039a44c1a84422080f8ec5b0d", size = 2259809, upload-time = "2025-05-03T16:59:25.976Z" }, + { url = "https://files.pythonhosted.org/packages/02/ec/3344b1ed4e60b36dd73cb66c36299c83a356e853e728c68314061498e9cd/zeroconf-0.147.0-cp313-cp313-manylinux_2_31_armv7l.manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:728f82417800c5c5dd3298f65cf7a8fef1707123b457d3832dbdf17d38f68840", size = 2096364, upload-time = "2025-05-03T16:59:27.786Z" }, + { url = "https://files.pythonhosted.org/packages/cd/30/5f34363e2d3c25a78fc925edcc5d45d332296a756d698ccfc060bba8a7aa/zeroconf-0.147.0-cp313-cp313-manylinux_2_36_x86_64.whl", hash = "sha256:a2dc9ae96cd49b50d651a78204aafe9f41e907122dc98e719be5376b4dddec6f", size = 2307868, upload-time = "2025-05-03T16:24:52.178Z" }, + { url = "https://files.pythonhosted.org/packages/1b/a8/9b4242ae78bd271520e019faf47d8a2b36242b3b1a7fd47ee7510d380734/zeroconf-0.147.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e9570ab3203cc4bd3ad023737ef4339558cdf1f33a5d45d76ed3fe77e5fa5f57", size = 2295063, upload-time = "2025-05-03T16:59:29.695Z" }, + { url = "https://files.pythonhosted.org/packages/9d/e6/b63e4e09d71e94bfe0d30c6fc80b0e67e3845eb630bcfb056626db070776/zeroconf-0.147.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:fd783d9bac258e79d07e2bd164c1962b8f248579392b5078fd607e7bb6760b53", size = 2152284, upload-time = "2025-05-03T16:59:31.598Z" }, + { url = "https://files.pythonhosted.org/packages/72/12/42b990cb7ad997eb9f9fff15c61abff022adc44f5d1e96bd712ed6cd85ab/zeroconf-0.147.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b4acc76063cc379774db407dce0263616518bb5135057eb5eeafc447b3c05a81", size = 2498559, upload-time = "2025-05-03T16:59:33.444Z" }, + { url = "https://files.pythonhosted.org/packages/99/f9/080619bfcfc353deeb8cf7e813eaf73e8e28ff9a8ca7b97b9f0ecbf4d1d6/zeroconf-0.147.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:acc5334cb6cb98db3917bf9a3d6b6b7fdd205f8a74fd6f4b885abb4f61098857", size = 2456548, upload-time = "2025-05-03T16:59:35.721Z" }, + { url = "https://files.pythonhosted.org/packages/35/b6/a25b703f418200edd6932d56bbd32cbd087b828579cf223348fa778fb1ff/zeroconf-0.147.0-cp313-cp313-win32.whl", hash = "sha256:7c52c523aa756e67bf18d46db298a5964291f7d868b4a970163432e7d745b992", size = 1427188, upload-time = "2025-05-03T16:59:38.756Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e1/ba463435cdb0b38088eae56d508ec6128b9012f58cedab145b1b77e51316/zeroconf-0.147.0-cp313-cp313-win_amd64.whl", hash = "sha256:60f623af0e45fba69f5fe80d7b300c913afe7928fb43f4b9757f0f76f80f0d82", size = 1655531, upload-time = "2025-05-03T16:59:40.65Z" }, + { url = "https://files.pythonhosted.org/packages/d8/9d/f641ad9a06a099cac9ad3b04e6c0f9a2f3a5569ce59b2a541f5d0d710b21/zeroconf-0.147.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a5b570c0697144876bf54ff9d87dc46f5f7c8b2709702b7182b99b363e37e301", size = 1846540, upload-time = "2025-05-03T16:59:42.486Z" }, + { url = "https://files.pythonhosted.org/packages/61/9c/7f7316aae0e6748019f38cb9c29b07b4fce44e47fe24436c29295fc8c4d2/zeroconf-0.147.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12a24145231b26d1e6d7ded60984f8f32e2b17fe4f9a824be26b7622b875bc12", size = 1705432, upload-time = "2025-05-03T16:59:44.366Z" }, + { url = "https://files.pythonhosted.org/packages/18/63/04ceca3b1aea16ebbd789195d654e330f6f08382da63c6830d635c28ca58/zeroconf-0.147.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf73a1a202a02f2e4810eb582f054104bff1a29a550ce0819c5fc6dfafe50f94", size = 2258226, upload-time = "2025-05-03T16:59:46.255Z" }, + { url = "https://files.pythonhosted.org/packages/6e/7b/0211f102cae24028434ba782c172fde54496b247da5969e78c551e7d38d6/zeroconf-0.147.0-cp39-cp39-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:aa55888411404cc7ff1c6822ace733680172a02931eb20561afda94d06342c4f", size = 2430683, upload-time = "2025-05-03T16:59:48.274Z" }, + { url = "https://files.pythonhosted.org/packages/3c/91/feadd56e6df0508c591007a290984219e3d6526854741fd794dd47f51cbb/zeroconf-0.147.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5291a5f26d961cfc0cd22905187a0627d07913e566783191f97a5a49dec9fc32", size = 2375153, upload-time = "2025-05-03T16:59:50.251Z" }, + { url = "https://files.pythonhosted.org/packages/0c/f0/2f69a979397bef7890663380882d76d9d0f8a754fbe624f8377618205997/zeroconf-0.147.0-cp39-cp39-manylinux_2_31_armv7l.manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:930b434ee3471430f3938f129979926a13c5ee1802ad6fb51383314f7193d33d", size = 2163487, upload-time = "2025-05-03T16:59:52.177Z" }, + { url = "https://files.pythonhosted.org/packages/29/04/96ce911f4ba54ec45decc5fd24687070761b1af9ee5bb3c9798dcc68e5b3/zeroconf-0.147.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4add353da94e067fd3a4fdb47e9be64bd451bc7bc2234d74775514bde5d8096c", size = 2392226, upload-time = "2025-05-03T16:59:54.487Z" }, + { url = "https://files.pythonhosted.org/packages/a7/35/3ce3c89eb2e45d26ecb94f7e0557871c1c84a061893f1588f7e27b6f002f/zeroconf-0.147.0-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:8c0a1c69ef9ff5aab6acdf33b892a45d5ca2f96af11fd53891a43ec816ab6c25", size = 2187944, upload-time = "2025-05-03T16:59:56.934Z" }, + { url = "https://files.pythonhosted.org/packages/f7/13/e2f3882f65b65d849b9eccd6554fd9c7aea5d72f011a8b5db1c24ae9113c/zeroconf-0.147.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:743fff2187da3d9501606555b1cf27699c24c36b9f1a6f02c168033034c5c22e", size = 2579691, upload-time = "2025-05-03T16:59:58.95Z" }, + { url = "https://files.pythonhosted.org/packages/7e/8a/7850106c53fadcf9eb35bff6de56f22ecf6aca47380219cef0f99ae75e37/zeroconf-0.147.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9a629b63f8f80a32121c4832264c23fbc6cec4e15200d4fd8e715257c06d84b1", size = 2534000, upload-time = "2025-05-03T17:00:01.395Z" }, + { url = "https://files.pythonhosted.org/packages/0c/fd/7f4b3557ceb92035b44a968fa0dcd63e7702d688543a0b36c1463e94915e/zeroconf-0.147.0-cp39-cp39-win32.whl", hash = "sha256:600b2a2453e7877b45c55d0c011e24f9eb7b75d71eee8a302e9b8b55e878b62b", size = 1439517, upload-time = "2025-05-03T17:00:03.403Z" }, + { url = "https://files.pythonhosted.org/packages/18/bb/c28f968cf2b0845991510a16d607e1a5343b35d2bc8278819152a9fcb90b/zeroconf-0.147.0-cp39-cp39-win_amd64.whl", hash = "sha256:34d40e09a7e4aff294ce086a63c5133c4d683b0165054af07c15035af1718829", size = 1667520, upload-time = "2025-05-03T17:00:05.54Z" }, + { url = "https://files.pythonhosted.org/packages/5c/eb/3980391d7b9ddaabd4cbc8bc1f0139420b2f62d7aa7ad510369fbafcf487/zeroconf-0.147.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8a2ceada07a6e89d7000e19826598a2fe013192e7a752637c1232cbc6041f434", size = 1642469, upload-time = "2025-05-03T17:00:07.602Z" }, + { url = "https://files.pythonhosted.org/packages/50/21/21b8287721e149cce3c8eb771f22d07841a63aa36274bc32634128ba37f7/zeroconf-0.147.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:60b548b8b58f4f7435f96e4a8bed0ffedc6023ebd9e30872d3e71e3f5d8bd8e3", size = 1542184, upload-time = "2025-05-03T17:00:09.717Z" }, + { url = "https://files.pythonhosted.org/packages/ba/9d/0fd01c963b9936407cb2ac9223ff2b18c29ea0835eb094297194fd483b7b/zeroconf-0.147.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7edafeb07c88398d6c2f01ce6810c566199d5d50c9da7ac93e9f0da1d34b7c8", size = 1984448, upload-time = "2025-05-03T17:00:12.341Z" }, + { url = "https://files.pythonhosted.org/packages/c9/83/1d93f618598692054d8703b7bcd8c0867d5345051df881d1125954d1c388/zeroconf-0.147.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:b39f83ff516ad764bda67ad242ef85481d1653d85bd4bc98cc62070bb086789c", size = 2106403, upload-time = "2025-05-03T17:00:14.57Z" }, + { url = "https://files.pythonhosted.org/packages/8a/8f/615ed826da6cae2815de54fd81ea848ab437a6dc2ccc70dbe650196f1c68/zeroconf-0.147.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abe4c6da969c64419e30ca83368475d97ae57421edb2ec86e5c2baa8f659bad5", size = 2077468, upload-time = "2025-05-03T17:00:16.711Z" }, + { url = "https://files.pythonhosted.org/packages/a2/72/c81d21d97746d4e615d84e36022b7d8e78b1371b9151df044aad176227cd/zeroconf-0.147.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:8ec79d8693874f0dda108be48f56bdd343ddb9a469d629a796f853ba0865f07e", size = 1548427, upload-time = "2025-05-03T17:00:20.431Z" }, + { url = "https://files.pythonhosted.org/packages/1a/90/a11ada56c3ae0b8c9377b2309c8cb24a5027aa87b45da654ec057f1ade38/zeroconf-0.147.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b89c62ea0220235da8b353958ea8340d62ed820dca34be0ff08146674a93168b", size = 1645736, upload-time = "2025-05-03T17:00:22.533Z" }, + { url = "https://files.pythonhosted.org/packages/08/2a/be74419b6b42a8782c45a68c2516c1757dd71266d04f035843f89e135d27/zeroconf-0.147.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f4fd6848de32756ec34531ea9b3cf1988c9115b7d8363687d3ffaa2cdba244d4", size = 1543083, upload-time = "2025-05-03T17:00:25.113Z" }, + { url = "https://files.pythonhosted.org/packages/95/d3/d8b6d896c93c0d9f713368db6dddaf89902446150da544e65d3acb77c5bb/zeroconf-0.147.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0f51b5e363c137291a56688898fe284c5f99f52b7f8a1528ebe9d81e8daeecf", size = 1982849, upload-time = "2025-05-03T17:00:27.153Z" }, + { url = "https://files.pythonhosted.org/packages/20/97/d6c75b9fae6687bc02ba09f502974951adedb1e943f4dfe0917f1440c40c/zeroconf-0.147.0-pp311-pypy311_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:de84c8e09a49009ff44fb1146bfd2380545cde2a9f5ebfa7038afc578b187b2a", size = 2103537, upload-time = "2025-05-03T17:00:29.325Z" }, + { url = "https://files.pythonhosted.org/packages/7a/ab/9bf900cdad74f53a991b9d2f83f0a63e0e5d8d31e9113900e287c06275f1/zeroconf-0.147.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81ea55950ace20a93ce1ef684b111498cb212e06cc190a311a572d42a49809fc", size = 2075789, upload-time = "2025-05-03T17:00:31.444Z" }, + { url = "https://files.pythonhosted.org/packages/09/43/12d772ed4bda07475bab206c881a0f16069578b6001eb030c894493d06f5/zeroconf-0.147.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f0e1e1abe27ab81bbaaac2e4d94f9e817e64128ab03ba5909462d1f4cc560bc5", size = 1549139, upload-time = "2025-05-03T17:00:33.578Z" }, + { url = "https://files.pythonhosted.org/packages/36/11/1fdd779a700a35bedf18d795d05a902313600aa4ea39a1d87d2ac5cdd30b/zeroconf-0.147.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:6883f1b39ef1fea628e1ad027c4e5ed5058582d1453ea0f8dee5f7afd421b228", size = 1639350, upload-time = "2025-05-03T17:00:36.227Z" }, + { url = "https://files.pythonhosted.org/packages/0e/bd/74c5d4a7d947461205b7b155df4f500de1af5d8410c22169c4d6ccb8afb5/zeroconf-0.147.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:f0c1157a7500145224b2606ca1efe393afa9879133acf40b1b428dfa5503581a", size = 1539401, upload-time = "2025-05-03T17:00:38.864Z" }, + { url = "https://files.pythonhosted.org/packages/28/ed/b2ad7de2784d18db96b6ed4980b6c2867fdaa3813af759d52dcce13a95b5/zeroconf-0.147.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f815a2202a4fdc66bd6cf81e4cd55657fb903b5f748455f6b9ca1702fb7d559", size = 1983583, upload-time = "2025-05-03T17:00:42.206Z" }, + { url = "https://files.pythonhosted.org/packages/1f/25/8c02b8edb73d7c7bec3ff2282f1ff48a094df51773959d24d4e2829e9bde/zeroconf-0.147.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux_2_5_i686.manylinux1_i686.manylinux2014_i686.whl", hash = "sha256:5f139fcf33fa166779b959185c46feae5c82dc86b09a8ee77484d1bd4155a87f", size = 2103966, upload-time = "2025-05-03T17:00:44.371Z" }, + { url = "https://files.pythonhosted.org/packages/00/8e/df781910be359b3178d0b4f2c9fd589c6a979c58e73990ccfede1983e0cc/zeroconf-0.147.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:536f5f07d2f2d5c872dc6acc8e8a560254c2a5874eba45165dc5deb14a49cc19", size = 2074606, upload-time = "2025-05-03T17:00:46.62Z" }, + { url = "https://files.pythonhosted.org/packages/27/26/fa79f0bafe8830c0de298bfaa7481858d22633c04e508001d80daf95ef4c/zeroconf-0.147.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:760d9b318e6ba311054348719f3e9ea33f678afbbf9e9585d7993638bba12220", size = 1545427, upload-time = "2025-05-03T17:00:48.801Z" }, +] From b7292d73dc563cf53645b586b7896163b011cee6 Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Mon, 11 Aug 2025 22:47:27 +0000 Subject: [PATCH 15/21] feat(ci): run pytest --- .github/workflows/python.yml | 32 +++++++++++++++++++++++++------- pyproject.toml | 4 +++- uv.lock | 28 ++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 8 deletions(-) diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 6c0c598..8213a2b 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -1,29 +1,47 @@ -name: Python lint and packages +name: Python lint, format, test on: push: - branches: [ master, dev ] + branches: [ dev ] pull_request: - branches: [ master, dev ] + branches: [ dev ] jobs: - build: - + check: runs-on: ubuntu-latest strategy: + fail-fast: false matrix: python-version: [ "3.9", "3.10", "3.11", "3.12", "3.13" ] steps: - uses: actions/checkout@v4 + - uses: astral-sh/setup-uv@v6 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - - uses: astral-sh/ruff-action@v3 + - name: Lint code + if: ${{ !cancelled() }} + uses: astral-sh/ruff-action@v3 - - uses: astral-sh/ruff-action@v3 + - name: Check formatting + if: ${{ !cancelled() }} + uses: astral-sh/ruff-action@v3 with: args: "format --check --diff" + + - name: Run unit tests + if: ${{ !cancelled() }} + run: | + github_report_args=(--md=report.md --emoji) + uv run pytest "${github_report_args[@]}" || exit + + { + echo "# Python ${{ matrix.python-version }} Test Report" + echo "
Click to expand!" + tail -n+2 report.md + echo "
" + } >>"$GITHUB_STEP_SUMMARY" diff --git a/pyproject.toml b/pyproject.toml index 93b2120..f733181 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,10 +49,12 @@ module-root = "" [dependency-groups] dev = [ "colorlog>=6.9.0", - "eval-type-backport>=0.2.2", # Required by pydantic to support Python 3.9 + "eval-type-backport>=0.2.2", # Required by pydantic to support Python 3.9 "pydantic>=2.11.7", "pytest>=8.4.1", "pytest-asyncio>=1.1.0", + "pytest-emoji>=0.2.0", + "pytest-md>=0.2.0", "ruff>=0.12.8", ] diff --git a/uv.lock b/uv.lock index 468ebe8..faee34a 100644 --- a/uv.lock +++ b/uv.lock @@ -238,6 +238,8 @@ dev = [ { name = "pydantic" }, { name = "pytest" }, { name = "pytest-asyncio" }, + { name = "pytest-emoji" }, + { name = "pytest-md" }, { name = "ruff" }, ] @@ -257,6 +259,8 @@ dev = [ { name = "pydantic", specifier = ">=2.11.7" }, { name = "pytest", specifier = ">=8.4.1" }, { name = "pytest-asyncio", specifier = ">=1.1.0" }, + { name = "pytest-emoji", specifier = ">=0.2.0" }, + { name = "pytest-md", specifier = ">=0.2.0" }, { name = "ruff", specifier = ">=0.12.8" }, ] @@ -827,6 +831,30 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c7/9d/bf86eddabf8c6c9cb1ea9a869d6873b46f105a5d292d3a6f7071f5b07935/pytest_asyncio-1.1.0-py3-none-any.whl", hash = "sha256:5fe2d69607b0bd75c656d1211f969cadba035030156745ee09e7d71740e58ecf", size = 15157, upload-time = "2025-07-16T04:29:24.929Z" }, ] +[[package]] +name = "pytest-emoji" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/88/4d/d489f939f0717a034cea7955d36bc2a7a5ba1b263871e63ad8cb16d47555/pytest-emoji-0.2.0.tar.gz", hash = "sha256:e1bd4790d87649c2d09c272c88bdfc4d37c1cc7c7a46583087d7c510944571e8", size = 6171, upload-time = "2019-02-19T09:33:17.454Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/51/80af966c0aded877da7577d21c4601ca98c6f603c6e6073ddea071af01ec/pytest_emoji-0.2.0-py3-none-any.whl", hash = "sha256:6e34ed21970fa4b80a56ad11417456bd873eb066c02315fe9df0fafe6d4d4436", size = 5664, upload-time = "2019-02-19T09:33:15.771Z" }, +] + +[[package]] +name = "pytest-md" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/55/1d4248f08a97255abb23b05d8ba07586333194fadb17beda96b707aebecd/pytest-md-0.2.0.tar.gz", hash = "sha256:3b248d5b360ea5198e05b4f49c7442234812809a63137ec6cdd3643a40cf0112", size = 5985, upload-time = "2019-07-11T08:15:59.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/80/71/23d03f57c18116c6770141478e33b3500c4e92500cf4b49a396e9226733f/pytest_md-0.2.0-py3-none-any.whl", hash = "sha256:4c4cd16fea6d1485e87ee254558712c804a96d2aa9674b780e7eb8fb6526e1d1", size = 6117, upload-time = "2019-07-11T08:15:57.829Z" }, +] + [[package]] name = "ruff" version = "0.12.8" From 0430b1dcc905a91d65c62ab40167112042126246 Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Thu, 14 Aug 2025 16:19:23 +0000 Subject: [PATCH 16/21] feat(rest): add ram endpoint --- dingz/rest/__init__.py | 2 ++ dingz/rest/_client.py | 6 +++++- dingz/rest/_types.py | 7 +++++++ scripts/gather.py | 5 +++++ tests/snapshot.py | 6 +++++- tests/snapshots/07f40e76ee72.json | 12 ++++++++++++ tests/snapshots/1b148b4bc772.json | 12 ++++++++++++ tests/snapshots/336a87b7ddcc.json | 12 ++++++++++++ tests/snapshots/4dfaa25d449e.json | 12 ++++++++++++ tests/snapshots/687e682a7db1.json | 12 ++++++++++++ tests/snapshots/a1cbf24095e8.json | 12 ++++++++++++ tests/snapshots/b6dbe5948d2f.json | 12 ++++++++++++ tests/test_rest_types.py | 7 ++++++- 13 files changed, 114 insertions(+), 3 deletions(-) diff --git a/dingz/rest/__init__.py b/dingz/rest/__init__.py index 1223ad1..9509a0d 100644 --- a/dingz/rest/__init__.py +++ b/dingz/rest/__init__.py @@ -10,6 +10,7 @@ NetworkInfo, PirSensorState, PowerOutputSensorState, + Ram, SensorsState, State, ThermostatState, @@ -25,6 +26,7 @@ "NetworkInfo", "PirSensorState", "PowerOutputSensorState", + "Ram", "RestClient", "SensorsState", "State", diff --git a/dingz/rest/_client.py b/dingz/rest/_client.py index 233686c..2542088 100644 --- a/dingz/rest/_client.py +++ b/dingz/rest/_client.py @@ -11,7 +11,7 @@ if TYPE_CHECKING: from types import TracebackType - from ._types import Device, NetworkInfo, State + from ._types import Device, NetworkInfo, Ram, State class RestClient: @@ -141,3 +141,7 @@ async def get_state(self) -> State: cloud. """ return await self._request("GET", URL("/api/v1/state")) + + async def get_ram(self) -> Ram: + """Get RAM information.""" + return await self._request("GET", URL("/api/v1/ram")) diff --git a/dingz/rest/_types.py b/dingz/rest/_types.py index 39a7aa4..238c1f4 100644 --- a/dingz/rest/_types.py +++ b/dingz/rest/_types.py @@ -264,3 +264,10 @@ class State(TypedDict, total=True): cloud: CloudState time: str config: ConfigState + + +class Ram(TypedDict, total=True): + """RAM information returned by the `/api/v1/ram` endpoint.""" + + free: int + largest_free_block: int diff --git a/scripts/gather.py b/scripts/gather.py index 9cd7771..7caef03 100755 --- a/scripts/gather.py +++ b/scripts/gather.py @@ -158,6 +158,11 @@ async def gather_snapshot(client: RestClient) -> Snapshot: "wifi.dns", ], ), + ram=await gather_endpoint( + lambda: client.get_ram(), + name="ram", + redact_paths=[], + ), ) diff --git a/tests/snapshot.py b/tests/snapshot.py index b8490f0..aec9e35 100644 --- a/tests/snapshot.py +++ b/tests/snapshot.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: from collections.abc import Mapping - from dingz.rest import Device, NetworkInfo, State + from dingz.rest import Device, NetworkInfo, Ram, State __all__ = [ "Endpoint", @@ -58,6 +58,7 @@ class Snapshot: device: Endpoint[Device] network_info: Endpoint[NetworkInfo] state: Endpoint[State] + ram: Endpoint[Ram] def endpoint_by_path(self, path: str) -> Endpoint[Any]: if path == "/api/v1/device": @@ -66,6 +67,8 @@ def endpoint_by_path(self, path: str) -> Endpoint[Any]: return self.network_info if path == "/api/v1/state": return self.state + if path == "/api/v1/ram": + return self.ram msg = f"Unknown endpoint path: {path}" raise LookupError(msg) @@ -84,6 +87,7 @@ def from_dict(cls, data: Mapping[str, Any]) -> Self: device=Endpoint.from_dict(data["device"]), network_info=Endpoint.from_dict(data["network_info"]), state=Endpoint.from_dict(data["state"]), + ram=Endpoint.from_dict(data["ram"]), ) diff --git a/tests/snapshots/07f40e76ee72.json b/tests/snapshots/07f40e76ee72.json index 1abb813..860f335 100644 --- a/tests/snapshots/07f40e76ee72.json +++ b/tests/snapshots/07f40e76ee72.json @@ -199,5 +199,17 @@ } }, "error": null + }, + "ram": { + "value": { + "free": 51848, + "diff": -1136, + "rtos_free_heap": 51724, + "caps_free_heap": 51652, + "largest_free_block": 26624, + "rtos_min_free_heap": 10484, + "caps_min_free_heap": 10484 + }, + "error": null } } \ No newline at end of file diff --git a/tests/snapshots/1b148b4bc772.json b/tests/snapshots/1b148b4bc772.json index 1cde4e5..a7709dc 100644 --- a/tests/snapshots/1b148b4bc772.json +++ b/tests/snapshots/1b148b4bc772.json @@ -199,5 +199,17 @@ } }, "error": null + }, + "ram": { + "value": { + "free": 54012, + "diff": -964, + "rtos_free_heap": 53868, + "caps_free_heap": 53784, + "largest_free_block": 28672, + "rtos_min_free_heap": 12852, + "caps_min_free_heap": 12852 + }, + "error": null } } \ No newline at end of file diff --git a/tests/snapshots/336a87b7ddcc.json b/tests/snapshots/336a87b7ddcc.json index c330e8b..2a4e327 100644 --- a/tests/snapshots/336a87b7ddcc.json +++ b/tests/snapshots/336a87b7ddcc.json @@ -202,5 +202,17 @@ } }, "error": null + }, + "ram": { + "value": { + "free": 104860, + "diff": -3440, + "rtos_free_heap": 104740, + "caps_free_heap": 104668, + "largest_free_block": 55296, + "rtos_min_free_heap": 24052, + "caps_min_free_heap": 24052 + }, + "error": null } } \ No newline at end of file diff --git a/tests/snapshots/4dfaa25d449e.json b/tests/snapshots/4dfaa25d449e.json index 773557c..2635517 100644 --- a/tests/snapshots/4dfaa25d449e.json +++ b/tests/snapshots/4dfaa25d449e.json @@ -205,5 +205,17 @@ } }, "error": null + }, + "ram": { + "value": { + "free": 50480, + "diff": -1040, + "rtos_free_heap": 50348, + "caps_free_heap": 50280, + "largest_free_block": 28672, + "rtos_min_free_heap": 9172, + "caps_min_free_heap": 9172 + }, + "error": null } } \ No newline at end of file diff --git a/tests/snapshots/687e682a7db1.json b/tests/snapshots/687e682a7db1.json index db78e2c..e53345c 100644 --- a/tests/snapshots/687e682a7db1.json +++ b/tests/snapshots/687e682a7db1.json @@ -205,5 +205,17 @@ } }, "error": null + }, + "ram": { + "value": { + "free": 53504, + "diff": -960, + "rtos_free_heap": 53368, + "caps_free_heap": 53304, + "largest_free_block": 25600, + "rtos_min_free_heap": 11616, + "caps_min_free_heap": 11616 + }, + "error": null } } \ No newline at end of file diff --git a/tests/snapshots/a1cbf24095e8.json b/tests/snapshots/a1cbf24095e8.json index 74e5574..75959c0 100644 --- a/tests/snapshots/a1cbf24095e8.json +++ b/tests/snapshots/a1cbf24095e8.json @@ -199,5 +199,17 @@ } }, "error": null + }, + "ram": { + "value": { + "free": 52592, + "diff": 668, + "rtos_free_heap": 52444, + "caps_free_heap": 52380, + "largest_free_block": 36864, + "rtos_min_free_heap": 10584, + "caps_min_free_heap": 10584 + }, + "error": null } } \ No newline at end of file diff --git a/tests/snapshots/b6dbe5948d2f.json b/tests/snapshots/b6dbe5948d2f.json index 66bf248..3d98036 100644 --- a/tests/snapshots/b6dbe5948d2f.json +++ b/tests/snapshots/b6dbe5948d2f.json @@ -205,5 +205,17 @@ } }, "error": null + }, + "ram": { + "value": { + "free": 54660, + "diff": 4, + "rtos_free_heap": 54532, + "caps_free_heap": 54464, + "largest_free_block": 31744, + "rtos_min_free_heap": 12344, + "caps_min_free_heap": 12344 + }, + "error": null } } \ No newline at end of file diff --git a/tests/test_rest_types.py b/tests/test_rest_types.py index 109c34c..0e2eb2c 100644 --- a/tests/test_rest_types.py +++ b/tests/test_rest_types.py @@ -7,7 +7,7 @@ from pydantic import TypeAdapter -from dingz.rest import Device, NetworkInfo, RestClient, State +from dingz.rest import Device, NetworkInfo, Ram, RestClient, State def _validate_strict(ty: Any, value: Any) -> None: @@ -28,3 +28,8 @@ async def test_network_info(rest_client_with_snapshot: RestClient) -> None: async def test_state(rest_client_with_snapshot: RestClient) -> None: state = await rest_client_with_snapshot.get_state() _validate_strict(State, state) + + +async def test_ram(rest_client_with_snapshot: RestClient) -> None: + ram = await rest_client_with_snapshot.get_ram() + _validate_strict(Ram, ram) From de5ff0b18ea54e778c12771835dc458b1cd4b84f Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Thu, 14 Aug 2025 22:57:06 +0000 Subject: [PATCH 17/21] feat(rest): add device configuration endpoints --- dingz/rest/__init__.py | 12 + dingz/rest/_client.py | 68 +- dingz/rest/_types/__init__.py | 4 + dingz/rest/_types/config.py | 661 +++++++ dingz/rest/_types/device.py | 89 + dingz/rest/_types/helpers.py | 31 + dingz/rest/{_types.py => _types/state.py} | 148 +- scripts/gather.py | 4 + tests/conftest.py | 7 +- tests/snapshot.py | 6 +- tests/snapshots/07f40e76ee72.json | 1949 ++++++++++++++++++++ tests/snapshots/1b148b4bc772.json | 1951 +++++++++++++++++++++ tests/snapshots/336a87b7ddcc.json | 1949 ++++++++++++++++++++ tests/snapshots/4dfaa25d449e.json | 1951 +++++++++++++++++++++ tests/snapshots/687e682a7db1.json | 1949 ++++++++++++++++++++ tests/snapshots/a1cbf24095e8.json | 1949 ++++++++++++++++++++ tests/snapshots/b6dbe5948d2f.json | 1947 ++++++++++++++++++++ tests/test_rest_types.py | 7 +- 18 files changed, 14562 insertions(+), 120 deletions(-) create mode 100644 dingz/rest/_types/__init__.py create mode 100644 dingz/rest/_types/config.py create mode 100644 dingz/rest/_types/device.py create mode 100644 dingz/rest/_types/helpers.py rename dingz/rest/{_types.py => _types/state.py} (54%) diff --git a/dingz/rest/__init__.py b/dingz/rest/__init__.py index 9509a0d..8ae847c 100644 --- a/dingz/rest/__init__.py +++ b/dingz/rest/__init__.py @@ -2,9 +2,15 @@ from ._client import RestClient from ._types import ( + ButtonConfig, + ButtonsConfig, + ConfigDump, + ConfigState, Date, Device, DynLightState, + InputConfig, + InputsConfig, LedState, LightState, NetworkInfo, @@ -18,9 +24,15 @@ ) __all__ = [ + "ButtonConfig", + "ButtonsConfig", + "ConfigDump", + "ConfigState", "Date", "Device", "DynLightState", + "InputConfig", + "InputsConfig", "LedState", "LightState", "NetworkInfo", diff --git a/dingz/rest/_client.py b/dingz/rest/_client.py index 2542088..026b287 100644 --- a/dingz/rest/_client.py +++ b/dingz/rest/_client.py @@ -11,7 +11,22 @@ if TYPE_CHECKING: from types import TracebackType - from ._types import Device, NetworkInfo, Ram, State + from ._types import ( + ActionsConfig, + ButtonsConfig, + ConfigDump, + DdiConfig, + Device, + InputsConfig, + LuxConfig, + NetworkInfo, + OutputsConfig, + PirsConfig, + Ram, + ServicesConfig, + State, + SystemConfig, + ) class RestClient: @@ -78,7 +93,13 @@ async def close(self) -> None: if self._session_owner: await self._session.close() - async def _request(self, method: Literal["GET"], endpoint: URL) -> Any: # noqa: ANN401 The return value really could be anything! + async def _request( + self, + method: Literal["GET"], + endpoint: URL, + *, + ignore_content_type: bool = False, + ) -> Any: # noqa: ANN401 The return value really could be anything! async with self._session.request( method, self._base_url.join(endpoint), @@ -86,7 +107,7 @@ async def _request(self, method: Literal["GET"], endpoint: URL) -> Any: # noqa: timeout=self._timeout, ) as resp: resp.raise_for_status() - return await resp.json() + return await resp.json(content_type=None if ignore_content_type else CONTENT_TYPE_JSON) async def get_firmware_version(self) -> str: """Get the firmware version of the dingz device. @@ -134,6 +155,47 @@ async def get_network_info(self) -> NetworkInfo: """Get general network settings.""" return await self._request("GET", URL("/api/v1/info")) + async def get_button_config(self) -> ButtonsConfig: + """Get the button configuration.""" + return await self._request("GET", URL("/api/v1/button_config")) + + async def get_input_config(self) -> InputsConfig: + """Get the input configuration.""" + return await self._request("GET", URL("/api/v1/input_config")) + + async def get_pir_config(self) -> PirsConfig: + """Get the PIR configuration.""" + return await self._request("GET", URL("/api/v1/pir_config")) + + async def get_lux_config(self) -> LuxConfig: + """Get the Lux configuration.""" + return await self._request("GET", URL("/api/v1/lux_config")) + + async def get_output_config(self) -> OutputsConfig: + """Get the output configuration.""" + return await self._request("GET", URL("/api/v1/output_config")) + + async def get_services_config(self) -> ServicesConfig: + """Get the services configuration.""" + return await self._request("GET", URL("/api/v1/services_config")) + + async def get_system_config(self) -> SystemConfig: + """Get the system configuration.""" + return await self._request("GET", URL("/api/v1/system_config")) + + async def get_ddi_config(self) -> DdiConfig: + """Get the DDI configuration.""" + return await self._request("GET", URL("/api/v1/ddi_config")) + + async def get_actions_config(self) -> ActionsConfig: + """Get the actions configuration.""" + return await self._request("GET", URL("/api/v1/actions")) + + async def get_config_dump(self) -> ConfigDump: + """Get the full configuration dump.""" + # dump_config reports content type application/octet-stream for some reason + return await self._request("GET", URL("/api/v1/dump_config"), ignore_content_type=True) + async def get_state(self) -> State: """Get the full dingz status. diff --git a/dingz/rest/_types/__init__.py b/dingz/rest/_types/__init__.py new file mode 100644 index 0000000..1571d0e --- /dev/null +++ b/dingz/rest/_types/__init__.py @@ -0,0 +1,4 @@ +from .config import * # noqa: F403 +from .device import * # noqa: F403 +from .helpers import * # noqa: F403 +from .state import * # noqa: F403 diff --git a/dingz/rest/_types/config.py b/dingz/rest/_types/config.py new file mode 100644 index 0000000..258402b --- /dev/null +++ b/dingz/rest/_types/config.py @@ -0,0 +1,661 @@ +from __future__ import annotations + +from typing_extensions import Literal, NotRequired, TypedDict + +# We need to actually import these types for `pydantic.TypeAdapter` to work. +from .helpers import Color # noqa: TC001 + +__all__ = [ + "ActionsConfig", + "BlindConfig", + "BlindsConfig", + "ButtonConfig", + "ButtonsConfig", + "ConfigDump", + "DdiChannelConfig", + "DdiChannelsConfig", + "DdiConfig", + "InputConfig", + "InputsConfig", + "LedConfig", + "LuxConfig", + "NlConfig", + "OutputConfig", + "OutputsConfig", + "OutputsConfig", + "PirConfig", + "PirsConfig", + "ServicesConfig", + "SystemConfig", + "ThermostatConfig", +] + + +class _LocalAndRemote(TypedDict): + local: bool + remote: bool + + +class _LightAndMotor(TypedDict): + light: bool + motor: bool + + +class _Actions(TypedDict): + off: bool + default_on: bool + custom_on: bool + open: bool + close: bool + default_pos: bool + custom_pos: bool + + +class _DdiActions(TypedDict): + brightness: bool + colour_temperature: bool + + +class _OutputsLocalCustom(TypedDict): + value: int + + +class _OutputsLocal(TypedDict): + controlled: bool + custom: _OutputsLocalCustom + + +class _OutputsRemoteCustom(TypedDict): + value: int + ct_value: int + + +class _OutputsRemote(TypedDict): + groups: str + custom: _OutputsRemoteCustom + + +class _OutputsDdiControlled(TypedDict): + active: bool + channel_id: int + + +class _OutputsDdiCustom(TypedDict): + brightness: int + colour_temperature: int + + +class _OutputsDdi(TypedDict): + controlled: _OutputsDdiControlled + custom: _OutputsDdiCustom + + +class _Outputs(TypedDict): + fade_in_time: int + fade_out_time: int + auto_off_delay: int + local: list[_OutputsLocal] + remote: _OutputsRemote + ddi: _OutputsDdi + + +class _MotorsCustom(TypedDict): + blind: int + lamella: int + + +class _MotorsLocal(TypedDict): + controlled: bool + custom: _MotorsCustom + + +class _MotorsRemote(TypedDict): + groups: str + custom: _MotorsCustom + + +class _Motors(TypedDict): + invert: bool + local: list[_MotorsLocal] + remote: _MotorsRemote + + +class _Feedback(TypedDict): + color: Literal["none"] | Color + brightness: int + + +class _ActionTriggerBase(TypedDict): + active: bool + name: str + icon: int + mode: _LocalAndRemote + local_type: _LightAndMotor + type: _LightAndMotor + actions: _Actions + ddi_actions: _DdiActions + outputs: _Outputs + motors: _Motors + feedback: _Feedback + carousel: bool + + +class _Button(TypedDict): + remote_push: bool + therm_ctrl: bool + + +class ButtonConfig(_ActionTriggerBase): + """Button configuration part of `ButtonsConfig`.""" + + button: _Button + + +class ButtonsConfig(TypedDict): + """Button config returned by the `/api/v1/button_config` endpoint.""" + + dingz_orientation: str + """Dingz orientation (e.g. '1,2,3,4').""" + buttons: list[ButtonConfig] + + +class _InputConfigContactFreeCooling(TypedDict): + repeat_period: int + + +class _InputConfigInput(TypedDict): + type: Literal["button_toggle", "button_push", "contact_state"] + invert: bool + contact_free_cooling: _InputConfigContactFreeCooling + + +class InputConfig(_ActionTriggerBase): + """Button configuration part of `InputsConfig`.""" + + input: _InputConfigInput + + +class InputsConfig(TypedDict): + """Inputs config returned by the `/api/v1/input_config` endpoint.""" + + inputs: list[InputConfig] + + +class _PirConfigPir(TypedDict): + backoff_time: int + on_time: int + manual_on_time: int + manual_off_time: int + + +class PirConfig(_ActionTriggerBase): + """PIR configuration part of `PirsConfig`.""" + + pir: _PirConfigPir + + +class PirsConfig(TypedDict): + """PIR config returned by the `/api/v1/pir_config` endpoint.""" + + pirs: list[PirConfig] + + +class _LuxConfigThresholds(TypedDict): + twilight_to_night: int + night_to_twilight: int + day_to_twilight: int + twilight_to_day: int + day_to_night: int + night_to_day: int + + +class LuxConfig(TypedDict): + """Lux config returned by the `/api/v1/lux_config` endpoint.""" + + enabled: bool + output: None + ddi_channels: None + feedback: bool + dim_value_night: int + dim_value_twilight: int + dim_value_day: int + ct_value_night: int + ct_value_twilight: int + ct_value_day: int + fade_in_time: int + fade_out_time: int + thresholds: _LuxConfigThresholds + light_lpf: bool + off_period: int + + +class _ThermostatFeedback(TypedDict): + enable: bool + brightness: int + + +class _ThermostatOutput(TypedDict): + controlled: bool + + +class ThermostatConfig(TypedDict): + """Thermostat config returned by the `/api/v1/thermostat_config` endpoint.""" + + active: bool + min_target_temp: int + max_target_temp: int + target_temp: int + cooling: bool + enable: bool + fahrenheit: bool + free_cooling: bool + groups: str + mode: _LocalAndRemote + feedback: _ThermostatFeedback + outputs: list[_ThermostatOutput] + user_mode: Literal["comfort"] + + +class LedConfig(TypedDict): + """LED config returned by the `/api/v1/led_config` endpoint.""" + + state: bool + local_feedback: bool + groups: str + + +class _Range(TypedDict): + min: int + max: int + + +class _Dynamic(TypedDict): + day: int + twilight: int + night: int + + +class _LightDimmer(TypedDict): + type: Literal["led_driver", "linear", "led_bulb", "halogen_bulb"] + use_last_value: bool + range: _Range + dynamic: _Dynamic + + +class _LightOnoffGroupOn(TypedDict): + day: bool + twilight: bool + night: bool + + +class _LightOnoff(TypedDict): + group_on: _LightOnoffGroupOn + + +class _Light(TypedDict): + dimmable: bool + auto_off_delay: int + dimmer: _LightDimmer + onoff: _LightOnoff + + +class _Heater(TypedDict): + type: Literal["nc"] + function: Literal["heating"] + + +class _PulseLength(TypedDict): + min: float + max: float + + +class _Pulse(TypedDict): + type: Literal["positive"] + length: _PulseLength + + +class _FanDelay(TypedDict): + pre: int + post: int + + +class _HourAndMinute(TypedDict): + hour: int + minute: int + + +_FanVentilation = TypedDict( + "_FanVentilation", + { + "from": _HourAndMinute, + "to": _HourAndMinute, + "force_in_24": int, + }, +) + + +class _FanReact(TypedDict): + pir_during_slot: bool + btn_no_delay: bool + + +class _Fan(TypedDict): + delay: _FanDelay + ventilation: _FanVentilation + react: _FanReact + active: bool + + +class _GarageDoor(TypedDict): + opening_travel_time: int + close_timeout: int + pulse_time: int + + +class _Valve(TypedDict): + duration: int + + +class OutputConfig(TypedDict): + """Output configuration part of `OutputsConfig`.""" + + active: bool + name: str + type: Literal["light"] + groups: str + feedback: _Feedback + light: _Light + heater: _Heater + pulse: _Pulse + fan: _Fan + garage_door: _GarageDoor + valve: _Valve + + +class OutputsConfig(TypedDict): + """Outputs config returned by the `/api/v1/output_config` endpoint.""" + + outputs: list[OutputConfig] + + +class BlindConfig(TypedDict): + """Blind configuration part of `BlindsConfig`.""" + + active: bool + name: str + type: Literal["blind"] + min_value: int + max_value: int + def_blind: int + def_lamella: int + groups: str + auto_calibration: bool + shade_up_time: int + shade_down_time: int + invert_direction: bool + lamella_time: float + step_duration: int + step_interval: int + state: Literal["Not initialised"] + + +class BlindsConfig(TypedDict): + """Blinds config returned by the `/api/v1/blind_config` endpoint.""" + + blinds: list[BlindConfig] + + +_ServicesConfigMqtt = TypedDict( + "_ServicesConfigMqtt", + { + "uri": str, + "enable": bool, + "server.crt": "str | None", + }, +) + + +class ServicesConfig(TypedDict): + """Services config returned by the `/api/v1/services_config` endpoint.""" + + mystrom: bool + homekit: bool + panel: bool + aws: bool + discovery: bool + udp_search: bool + aws_notifies: bool + ssdp: bool + mdns: bool + mdns_search: bool + homekit_configured: bool + cloud_ping: bool + broadcast_period: int + mdns_search_period: int + mqtt: _ServicesConfigMqtt + cloud_paired: bool + cloud_test_enabled: bool + + +class _SystemConfigTempComp(TypedDict): + fet_offset: float + gain_up: float + gain_down: float + gain_total: float + idle_offset: int + front_offset: int + inf_factor: float + + +class _SystemConfigDynLightSunOffset(TypedDict): + day: int + twilight: int + night: int + + +class _SystemConfigDynLight(TypedDict): + enable: bool + phases: int + source: Literal["sun", "lux"] + sun_offset: _SystemConfigDynLightSunOffset + + +class SystemConfig(TypedDict): + """System config returned by the `/api/v1/system_config` endpoint.""" + + rest_password: bool + protected_status: bool + allow_reset: bool + allow_wps: bool + allow_reboot: bool + allow_remote_reboot: bool + allow_update: bool + origin: bool + upgrade_blink: bool + reboot_blink: bool + dingz_name: str + room_name: str + home_name: str + id: str + temp_offset: float + fet_offset: NotRequired[float] + cpu_offset: NotRequired[float] + temp_comp: _SystemConfigTempComp + sun_offset: int + tzid: int + lat: float + long: float + dyn_light: _SystemConfigDynLight + wifi_ps: bool + new_comp_alg: bool + + +class DdiConfig(TypedDict): + """DDI config returned by the `/api/v1/ddi_config` endpoint.""" + + repeat: bool + repeat_interval: int + + +class _DdiChannelConfigFeaturesColourTemperature(TypedDict): + en: bool + range: _Range + dynamic: _Dynamic + + +class _DdiChannelConfigFeatures(TypedDict): + colour_temperature: _DdiChannelConfigFeaturesColourTemperature + + +class DdiChannelConfig(TypedDict): + """DDI channel configuration part of `DdiChannelsConfig`.""" + + name: str + en: bool + ddi_group_id: int + dingz_groups: str + use_last_value: bool + auto_off_delay: int + range: _Range + dynamic: _Dynamic + features: _DdiChannelConfigFeatures + feedback: _Feedback + + +class DdiChannelsConfig(TypedDict): + """DDI channels config returned by the `/api/v1/ddi_channels_config` endpoint.""" + + ddi_channels: list[DdiChannelConfig] + + +class _NlConfigLed(TypedDict): + color: str + """Semicolon-separated RGB color code (e.g. "255;0;0" for red).""" + + +# TODO: what even is this?? +class NlConfig(TypedDict): + enable: bool + on: _HourAndMinute + off: _HourAndMinute + dimmers: list[None] + ddi_channels: list[None] + led: _NlConfigLed | None + + +class _ActionsConfigBtnFeedback(TypedDict): + single: bool + double: bool + long: bool + m3: bool + m4: bool + m5: bool + begin: bool + hold_up: bool + hold_down: bool + end: bool + off: bool + + +class _ActionsConfigBase(TypedDict): + single: str + double: str + long: str + m3: str + m4: str + m5: str + begin: str + hold_up: str + hold_down: str + end: str + off: str + hold_up_repeat_period: int + hold_down_repeat_period: int + + +class _ActionsConfigBtn(_ActionsConfigBase): + feedback: _ActionsConfigBtnFeedback + + +class _ActionsConfigInputFeedback(_ActionsConfigBtnFeedback): + active: bool + inactive: bool + + +class _ActionsConfigInput(_ActionsConfigBase): + active: str + inactive: str + active_repeat_period: int + inactive_repeat_period: int + feedback: _ActionsConfigInputFeedback + + +class _ActionsConfigThermostat(TypedDict): + idle: str + heating: str + cooling: str + repeat_period: int + + +class _ActionsConfigLux(TypedDict): + night: str + twilight: str + day: str + repeat_period: int + + +class _ActionsConfigPirFeedback(TypedDict): + night: bool + twilight: bool + day: bool + rise: bool + fall: bool + timer_off: bool + + +class _ActionsConfigPir(TypedDict): + night: str + twilight: str + day: str + rise: str + fall: str + timer_off: str + motion_repeat_period: int + feedback: _ActionsConfigPirFeedback + + +class ActionsConfig(TypedDict): + """Actions config returned by the `/api/v1/action` endpoint.""" + + generic: str + btn1: _ActionsConfigBtn + btn2: _ActionsConfigBtn + btn3: _ActionsConfigBtn + btn4: _ActionsConfigBtn + input: _ActionsConfigInput + input2: _ActionsConfigInput + thermostat: _ActionsConfigThermostat + lux: _ActionsConfigLux + pir1: _ActionsConfigPir + pir2: _ActionsConfigPir + pir3: _ActionsConfigPir + + +class ConfigDump(TypedDict): + """Full config dump returned by the `/api/v1/dump_config` endpoint.""" + + buttons: ButtonsConfig + inputs: InputsConfig + pir: PirsConfig + lux: LuxConfig + thermostat: ThermostatConfig + led: LedConfig + outputs: OutputsConfig + blinds: BlindsConfig + services: ServicesConfig + system: SystemConfig + ddi: DdiConfig + ddi_channels: DdiChannelsConfig + nl: NlConfig + actions: ActionsConfig + # scheduler: list[...] diff --git a/dingz/rest/_types/device.py b/dingz/rest/_types/device.py new file mode 100644 index 0000000..2eb8cd8 --- /dev/null +++ b/dingz/rest/_types/device.py @@ -0,0 +1,89 @@ +from __future__ import annotations + +from typing_extensions import Literal, NotRequired, TypedDict + +# We need to actually import these types for `pydantic.TypeAdapter` to work. +from .helpers import Date, ShortColorCode # noqa: TC001 + +__all__ = [ + "Device", + "NetworkInfo", + "Ram", +] + + +class Device(TypedDict): + """Device information returned by the `/api/v1/device` endpoint.""" + + type: Literal["dingz"] + device_id: str + """User-settable identifier of the device. + + This field isn't present in the API model itself. The actual API response is a + `dict[str, Device]` with a single entry. The key is the device id. + """ + battery: bool + reachable: bool + meshroot: bool + fw_version: str + hw_version: str + fw_version_puck: str + bl_version_puck: str + hw_version_puck: str + hw_id_puck: int + puck_sn: str + puck_production_date: Date + ddi_base: bool + dip_config: int + dip_static: bool + dip_misconf: bool + puck_hw_model: Literal["DZ1B-4CH", ""] # TODO: incomplete + """Puck hardware model. + + Can be an empty string if unknown. + """ + front_hw_model: NotRequired[Literal["dz1f-pir", "dz1f-4b"]] # TODO: incomplete + """Front hardware model. + + Can be missing. + """ + front_production_date: NotRequired[str] + """Front production date. + + Format: `DD/MM/YY` + + Can be missing. + """ + front_sn: NotRequired[str] + """Front serial number. + + Can be missing. + """ + front_color: ShortColorCode + has_pir: bool + first_boot: bool + hash: str + + +class NetworkInfo(TypedDict): + """Network information returned by the `/api/v1/info` endpoint.""" + + version: str + """Version of the front.""" + mac: str + """MAC Address""" + type: Literal[108] # TODO: incomplete? + ssid: str + ip: str + mask: str + gw: str + dns: str + static: bool + connected: bool + + +class Ram(TypedDict): + """RAM information returned by the `/api/v1/ram` endpoint.""" + + free: int + largest_free_block: int diff --git a/dingz/rest/_types/helpers.py b/dingz/rest/_types/helpers.py new file mode 100644 index 0000000..48b04d6 --- /dev/null +++ b/dingz/rest/_types/helpers.py @@ -0,0 +1,31 @@ +from typing_extensions import Literal, TypedDict + +__all__ = [ + "Color", + "Date", + "Index", + "ShortColorCode", +] + +ShortColorCode = Literal["WH", "MC"] +Color = Literal["red", "blue", "green", "white"] + + +class Index(TypedDict): + """Index information of a dingz sub-component.""" + + relative: int + """The relative index of dimmer (depending on DIP switch configuration). + + Use this index to refer to component for actions. + """ + absolute: int + """The absolute index. Refers to hardware output number.""" + + +class Date(TypedDict): + """Split date information part of `Device`.""" + + year: int + month: int + day: int diff --git a/dingz/rest/_types.py b/dingz/rest/_types/state.py similarity index 54% rename from dingz/rest/_types.py rename to dingz/rest/_types/state.py index 238c1f4..47fc4dd 100644 --- a/dingz/rest/_types.py +++ b/dingz/rest/_types/state.py @@ -1,104 +1,31 @@ from __future__ import annotations -from typing import Literal - -from typing_extensions import NotRequired, TypedDict - - -class Index(TypedDict, total=True): - """Index information of a dingz sub-component.""" - - relative: int - """The relative index of dimmer (depending on DIP switch configuration). - - Use this index to refer to component for actions. - """ - absolute: int - """The absolute index. Refers to hardware output number.""" - +from typing_extensions import Literal, TypedDict + +# We need to actually import these types for `pydantic.TypeAdapter` to work. +from .helpers import Index # noqa: TC001 + +__all__ = [ + "BlindState", + "CloudState", + "ConfigState", + "DdiChannelState", + "DimmerState", + "DynLightState", + "LedState", + "LightState", + "PirSensorState", + "PowerOutputSensorState", + "SensorsState", + "State", + "ThermostatState", + "WifiState", +] LightState = Literal["day", "twilight", "night"] -class Date(TypedDict, total=True): - """Split date information part of `Device`.""" - - year: int - month: int - day: int - - -class Device(TypedDict, total=True): - """Device information returned by the `/api/v1/device` endpoint.""" - - type: Literal["dingz"] - device_id: str - """User-settable identifier of the device. - - This field isn't present in the API model itself. The actual API response is a - `dict[str, Device]` with a single entry. The key is the device id. - """ - battery: bool - reachable: bool - meshroot: bool - fw_version: str - hw_version: str - fw_version_puck: str - bl_version_puck: str - hw_version_puck: str - hw_id_puck: int - puck_sn: str - puck_production_date: Date - ddi_base: bool - dip_config: int - dip_static: bool - dip_misconf: bool - puck_hw_model: Literal["DZ1B-4CH", ""] # TODO: incomplete - """Puck hardware model. - - Can be an empty string if unknown. - """ - front_hw_model: NotRequired[Literal["dz1f-pir", "dz1f-4b"]] # TODO: incomplete - """Front hardware model. - - Can be missing. - """ - front_production_date: NotRequired[str] - """Front production date. - - Format: `DD/MM/YY` - - Can be missing. - """ - front_sn: NotRequired[str] - """Front serial number. - - Can be missing. - """ - front_color: str - has_pir: bool - first_boot: bool - hash: str - - -class NetworkInfo(TypedDict, total=True): - """Network information returned by the `/api/v1/info` endpoint.""" - - version: str - """Version of the front.""" - mac: str - """MAC Address""" - type: Literal[108] # TODO: incomplete? - ssid: str - ip: str - mask: str - gw: str - dns: str - static: bool - connected: bool - - -class DimmerState(TypedDict, total=True): +class DimmerState(TypedDict): """Dimmer status part of `State`.""" on: bool @@ -119,7 +46,7 @@ class DimmerState(TypedDict, total=True): # TODO CHECK -class BlindState(TypedDict, total=True): +class BlindState(TypedDict): """Blind status part of `State`.""" moving: Literal["up", "down", "stop"] @@ -132,7 +59,7 @@ class BlindState(TypedDict, total=True): # TODO CHECK -class DdiChannelState(TypedDict, total=True): +class DdiChannelState(TypedDict): """DDI Channel status part of `State`.""" name: str @@ -147,7 +74,7 @@ class DdiChannelState(TypedDict, total=True): off_timer_value: int -class LedState(TypedDict, total=True): +class LedState(TypedDict): """LED status part of `State`.""" on: bool @@ -164,7 +91,7 @@ class LedState(TypedDict, total=True): override_level: int -class PirSensorState(TypedDict, total=True): +class PirSensorState(TypedDict): """PIR sensor status part of `SensorsState`.""" enabled: bool @@ -174,13 +101,13 @@ class PirSensorState(TypedDict, total=True): suspend_timer: int -class PowerOutputSensorState(TypedDict, total=True): +class PowerOutputSensorState(TypedDict): """Power output sensor status part of `SensorsState`.""" value: float -class SensorsState(TypedDict, total=True): +class SensorsState(TypedDict): """Sensors status part of `State`.""" brightness: int @@ -202,13 +129,13 @@ class SensorsState(TypedDict, total=True): power_outputs: list[PowerOutputSensorState] -class DynLightState(TypedDict, total=True): +class DynLightState(TypedDict): """Dyn light status part of `State`.""" mode: LightState -class ThermostatState(TypedDict, total=True): +class ThermostatState(TypedDict): """Thermostat status part of `State`.""" active: bool @@ -224,7 +151,7 @@ class ThermostatState(TypedDict, total=True): temp: float -class WifiState(TypedDict, total=True): +class WifiState(TypedDict): """Wifi status part of `State`.""" version: str @@ -238,19 +165,19 @@ class WifiState(TypedDict, total=True): connected: bool -class CloudState(TypedDict, total=True): +class CloudState(TypedDict): """Cloud status part of `State`.""" aws: Literal["connected", "disconnected"] # TODO: incomplete -class ConfigState(TypedDict, total=True): +class ConfigState(TypedDict): """Config status part of `State`.""" timestamp: int -class State(TypedDict, total=True): +class State(TypedDict): """Full device status returned by the `/api/v1/state` endpoint.""" dimmers: list[DimmerState] @@ -264,10 +191,3 @@ class State(TypedDict, total=True): cloud: CloudState time: str config: ConfigState - - -class Ram(TypedDict, total=True): - """RAM information returned by the `/api/v1/ram` endpoint.""" - - free: int - largest_free_block: int diff --git a/scripts/gather.py b/scripts/gather.py index 7caef03..708d767 100755 --- a/scripts/gather.py +++ b/scripts/gather.py @@ -146,6 +146,10 @@ async def gather_snapshot(client: RestClient) -> Snapshot: name="network_info", redact_paths=["mac", "ssid", "ip", "mask", "gw", "dns"], ), + config_dump=await gather_endpoint( + lambda: client.get_config_dump(), + name="config_dump", + ), state=await gather_endpoint( lambda: client.get_state(), name="state", diff --git a/tests/conftest.py b/tests/conftest.py index 64e1746..71094d7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -23,7 +23,12 @@ def snapshot(request: pytest.FixtureRequest) -> Snapshot: @pytest_asyncio.fixture async def rest_client_with_snapshot(snapshot: Snapshot) -> AsyncIterator[RestClient]: - def side_effect(_method: Literal["GET"], endpoint: URL) -> Any: + def side_effect( + _method: Literal["GET"], + endpoint: URL, + *, + ignore_content_type: bool = False, + ) -> Any: endpoint_data = snapshot.endpoint_by_path(endpoint.path) if endpoint_data.error is not None: msg = "Error mocking is not yet implemented in test framework!" diff --git a/tests/snapshot.py b/tests/snapshot.py index aec9e35..a87c0ff 100644 --- a/tests/snapshot.py +++ b/tests/snapshot.py @@ -10,7 +10,7 @@ if TYPE_CHECKING: from collections.abc import Mapping - from dingz.rest import Device, NetworkInfo, Ram, State + from dingz.rest import ConfigDump, Device, NetworkInfo, Ram, State __all__ = [ "Endpoint", @@ -57,6 +57,7 @@ class Snapshot: firmware_version: Endpoint[str] device: Endpoint[Device] network_info: Endpoint[NetworkInfo] + config_dump: Endpoint[ConfigDump] state: Endpoint[State] ram: Endpoint[Ram] @@ -65,6 +66,8 @@ def endpoint_by_path(self, path: str) -> Endpoint[Any]: return self.device if path == "/api/v1/info": return self.network_info + if path == "/api/v1/dump_config": + return self.config_dump if path == "/api/v1/state": return self.state if path == "/api/v1/ram": @@ -86,6 +89,7 @@ def from_dict(cls, data: Mapping[str, Any]) -> Self: firmware_version=Endpoint.from_dict(data["firmware_version"]), device=Endpoint.from_dict(data["device"]), network_info=Endpoint.from_dict(data["network_info"]), + config_dump=Endpoint.from_dict(data["config_dump"]), state=Endpoint.from_dict(data["state"]), ram=Endpoint.from_dict(data["ram"]), ) diff --git a/tests/snapshots/07f40e76ee72.json b/tests/snapshots/07f40e76ee72.json index 860f335..8ce903c 100644 --- a/tests/snapshots/07f40e76ee72.json +++ b/tests/snapshots/07f40e76ee72.json @@ -54,6 +54,1955 @@ }, "error": null }, + "config_dump": { + "value": { + "buttons": { + "dingz_orientation": "1,2,3,4", + "buttons": [ + { + "active": true, + "name": "Terrasse Licht Wand", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Terrasse Tisch", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Wohnzimmer", + "icon": 1, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": true, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": false, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "a", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Gang EG", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": false, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + } + ] + }, + "inputs": { + "inputs": [ + { + "active": false, + "name": "", + "icon": 17, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_toggle", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + } + ] + }, + "pir": { + "pirs": [ + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 7200, + "manual_off_time": 5 + } + } + ] + }, + "lux": { + "enabled": true, + "output": null, + "ddi_channels": null, + "feedback": false, + "dim_value_night": 30, + "dim_value_twilight": 50, + "dim_value_day": 75, + "ct_value_night": 0, + "ct_value_twilight": 0, + "ct_value_day": 0, + "fade_in_time": 10, + "fade_out_time": 10, + "thresholds": { + "twilight_to_night": 50, + "night_to_twilight": 100, + "day_to_twilight": 150, + "twilight_to_day": 200, + "day_to_night": 50, + "night_to_day": 200 + }, + "light_lpf": true, + "off_period": 900 + }, + "thermostat": { + "active": false, + "min_target_temp": 17, + "max_target_temp": 31, + "target_temp": 21, + "cooling": false, + "enable": true, + "fahrenheit": false, + "free_cooling": false, + "groups": "z", + "mode": { + "local": false, + "remote": false + }, + "feedback": { + "enable": false, + "brightness": 100 + }, + "outputs": [ + { + "controlled": true + }, + { + "controlled": true + }, + { + "controlled": true + }, + { + "controlled": true + } + ], + "user_mode": "comfort" + }, + "led": { + "state": false, + "local_feedback": true, + "groups": "z" + }, + "outputs": { + "outputs": [ + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "white", + "brightness": 1 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "led_bulb", + "use_last_value": false, + "range": { + "min": 23, + "max": 100 + }, + "dynamic": { + "day": 75, + "twilight": 50, + "night": 30 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + } + ] + }, + "blinds": { + "blinds": [ + { + "active": true, + "name": "", + "type": "blind", + "min_value": 0, + "max_value": 100, + "def_blind": 0, + "def_lamella": 80, + "groups": "z", + "auto_calibration": true, + "shade_up_time": 180, + "shade_down_time": 180, + "invert_direction": false, + "lamella_time": 1.8, + "step_duration": 300, + "step_interval": 1200, + "state": "Not initialised" + }, + { + "active": true, + "name": "", + "type": "blind", + "min_value": 0, + "max_value": 100, + "def_blind": 0, + "def_lamella": 80, + "groups": "z", + "auto_calibration": true, + "shade_up_time": 180, + "shade_down_time": 180, + "invert_direction": false, + "lamella_time": 1.8, + "step_duration": 300, + "step_interval": 1200, + "state": "Not initialised" + } + ] + }, + "services": { + "mystrom": false, + "homekit": false, + "rest_api": true, + "panel": true, + "aws": true, + "discovery": false, + "udp_search": true, + "aws_notifies": false, + "ssdp": false, + "mdns": true, + "mdns_search": true, + "homekit_configured": false, + "cloud_ping": false, + "broadcast_period": 5, + "mdns_search_period": 60, + "mqtt": { + "uri": "[redacted]", + "enable": true, + "server.crt": null + }, + "cloud_paired": false, + "cloud_test_enabled": false + }, + "system": { + "rest_password": false, + "protected_status": false, + "allow_reset": true, + "allow_wps": true, + "allow_reboot": true, + "allow_remote_reboot": true, + "allow_update": true, + "origin": true, + "upgrade_blink": true, + "reboot_blink": false, + "dingz_name": "Wohnzimmer Terrasse", + "room_name": "Wohnzimmer", + "home_name": "BG12", + "id": "[redacted]", + "temp_offset": 7, + "fet_offset": 2.6666666666666665, + "cpu_offset": 26.6, + "temp_comp": { + "fet_offset": 2.64, + "gain_up": 0.012, + "gain_down": 0.006, + "gain_total": 0.25, + "idle_offset": 0, + "front_offset": 15, + "inf_factor": 0.5 + }, + "sun_offset": 0, + "tzid": 0, + "lat": 46.929, + "long": 7.118, + "dyn_light": { + "enable": true, + "phases": 3, + "source": "sun", + "sun_offset": { + "day": 30, + "twilight": 30, + "night": 30 + } + }, + "wifi_ps": true, + "new_comp_alg": false + }, + "ddi": { + "repeat": true, + "repeat_interval": 5 + }, + "ddi_channels": { + "ddi_channels": [ + { + "name": "BC", + "en": true, + "ddi_group_id": 16, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": true, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + } + ] + }, + "nl": { + "enable": false, + "on": { + "hour": 20, + "minute": 0 + }, + "off": { + "hour": 6, + "minute": 0 + }, + "dimmers": [ + null, + null, + null, + null + ], + "ddi_channels": [ + null, + null, + null, + null + ], + "led": null + }, + "actions": { + "generic": "", + "btn1": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn3": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn4": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "input": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "input2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "thermostat": { + "idle": "", + "heating": "", + "cooling": "", + "repeat_period": 60000 + }, + "lux": { + "night": "", + "twilight": "", + "day": "", + "repeat_period": 0 + }, + "pir1": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir2": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir3": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + } + }, + "scheduler": [] + }, + "error": null + }, "state": { "value": { "dimmers": [ diff --git a/tests/snapshots/1b148b4bc772.json b/tests/snapshots/1b148b4bc772.json index a7709dc..7f46ea4 100644 --- a/tests/snapshots/1b148b4bc772.json +++ b/tests/snapshots/1b148b4bc772.json @@ -54,6 +54,1957 @@ }, "error": null }, + "config_dump": { + "value": { + "buttons": { + "dingz_orientation": "1,2,3,4", + "buttons": [ + { + "active": true, + "name": "St\u00fcbli", + "icon": 0, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": true, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "b", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 0 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Wohnzimmer", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Sofa", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 73 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + } + ] + }, + "inputs": { + "inputs": [ + { + "active": true, + "name": "Wohnzimmer K\u00fcche", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_toggle", + "invert": true, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + } + ] + }, + "pir": { + "pirs": [ + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 7200, + "manual_off_time": 5 + } + } + ] + }, + "lux": { + "enabled": true, + "output": null, + "ddi_channels": null, + "feedback": false, + "dim_value_night": 100, + "dim_value_twilight": 100, + "dim_value_day": 100, + "ct_value_night": 0, + "ct_value_twilight": 0, + "ct_value_day": 0, + "fade_in_time": 10, + "fade_out_time": 10, + "thresholds": { + "twilight_to_night": 50, + "night_to_twilight": 100, + "day_to_twilight": 150, + "twilight_to_day": 200, + "day_to_night": 50, + "night_to_day": 200 + }, + "light_lpf": true, + "off_period": 900 + }, + "thermostat": { + "active": false, + "min_target_temp": 17, + "max_target_temp": 31, + "target_temp": 22, + "cooling": false, + "enable": true, + "fahrenheit": false, + "free_cooling": false, + "groups": "z", + "mode": { + "local": false, + "remote": false + }, + "feedback": { + "enable": false, + "brightness": 100 + }, + "outputs": [ + { + "controlled": true + }, + { + "controlled": true + }, + { + "controlled": true + }, + { + "controlled": true + } + ], + "user_mode": "comfort" + }, + "led": { + "state": false, + "local_feedback": true, + "groups": "z" + }, + "outputs": { + "outputs": [ + { + "active": true, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": false, + "name": "St\u00fcbli", + "type": "light", + "groups": "bz", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": true, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 0, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": false, + "twilight": false, + "night": false + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Sofa", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 67 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "led_bulb", + "use_last_value": false, + "range": { + "min": 25, + "max": 100 + }, + "dynamic": { + "day": 75, + "twilight": 50, + "night": 34 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Wohnzimmer", + "type": "light", + "groups": "az", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "led_driver", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 60, + "twilight": 35, + "night": 10 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + } + ] + }, + "blinds": { + "blinds": [ + { + "active": true, + "name": "", + "type": "blind", + "min_value": 0, + "max_value": 100, + "def_blind": 0, + "def_lamella": 80, + "groups": "z", + "auto_calibration": true, + "shade_up_time": 180, + "shade_down_time": 180, + "invert_direction": false, + "lamella_time": 1.8, + "step_duration": 300, + "step_interval": 1200, + "state": "Not initialised" + }, + { + "active": true, + "name": "", + "type": "blind", + "min_value": 0, + "max_value": 100, + "def_blind": 0, + "def_lamella": 80, + "groups": "z", + "auto_calibration": true, + "shade_up_time": 180, + "shade_down_time": 180, + "invert_direction": false, + "lamella_time": 1.8, + "step_duration": 300, + "step_interval": 1200, + "state": "Not initialised" + } + ] + }, + "services": { + "mystrom": false, + "homekit": false, + "rest_api": true, + "panel": true, + "aws": true, + "discovery": false, + "udp_search": true, + "aws_notifies": false, + "ssdp": false, + "mdns": true, + "mdns_search": true, + "homekit_configured": false, + "cloud_ping": false, + "broadcast_period": 5, + "mdns_search_period": 60, + "mqtt": { + "uri": "[redacted]", + "enable": true, + "server.crt": null + }, + "cloud_paired": false, + "cloud_test_enabled": false + }, + "system": { + "rest_password": false, + "protected_status": false, + "allow_reset": true, + "allow_wps": true, + "allow_reboot": true, + "allow_remote_reboot": true, + "allow_update": true, + "origin": true, + "upgrade_blink": true, + "reboot_blink": true, + "dingz_name": "Wohnzimmer", + "room_name": "Wohnzimmer", + "home_name": "", + "id": "[redacted]", + "temp_offset": 6, + "fet_offset": 3.1666666666666665, + "cpu_offset": 26.3, + "temp_comp": { + "fet_offset": 2.64, + "gain_up": 0.012, + "gain_down": 0.006, + "gain_total": 0.25, + "idle_offset": 0, + "front_offset": 15, + "inf_factor": 0.5 + }, + "sun_offset": 0, + "tzid": 0, + "lat": 46.929, + "long": 7.118, + "dyn_light": { + "enable": true, + "phases": 3, + "source": "sun", + "sun_offset": { + "day": 30, + "twilight": 30, + "night": 30 + } + }, + "wifi_ps": true, + "new_comp_alg": false + }, + "ddi": { + "repeat": true, + "repeat_interval": 5 + }, + "ddi_channels": { + "ddi_channels": [ + { + "name": "BC", + "en": true, + "ddi_group_id": 16, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": true, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + } + ] + }, + "nl": { + "enable": false, + "on": { + "hour": 20, + "minute": 0 + }, + "off": { + "hour": 6, + "minute": 0 + }, + "dimmers": [ + null, + null, + null, + null + ], + "ddi_channels": [ + null, + null, + null, + null + ], + "led": { + "color": "0;0;0" + } + }, + "actions": { + "generic": "", + "btn1": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn3": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn4": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "input": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "input2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "thermostat": { + "idle": "", + "heating": "", + "cooling": "", + "repeat_period": 20000 + }, + "lux": { + "night": "", + "twilight": "", + "day": "", + "repeat_period": 0 + }, + "pir1": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir2": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir3": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + } + }, + "scheduler": [] + }, + "error": null + }, "state": { "value": { "dimmers": [ diff --git a/tests/snapshots/336a87b7ddcc.json b/tests/snapshots/336a87b7ddcc.json index 2a4e327..7c545c4 100644 --- a/tests/snapshots/336a87b7ddcc.json +++ b/tests/snapshots/336a87b7ddcc.json @@ -51,6 +51,1955 @@ }, "error": null }, + "config_dump": { + "value": { + "buttons": { + "dingz_orientation": "1,2,3,4", + "buttons": [ + { + "active": true, + "name": "Licht Mitte", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Licht Aussen West", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Licht S\u00fcd", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": false, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "", + "icon": 1, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": false, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + } + ] + }, + "inputs": { + "inputs": [ + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + } + ] + }, + "pir": { + "pirs": [ + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": false, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": false, + "default_on": false, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "white", + "brightness": 1 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 600, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 7200, + "manual_off_time": 5 + } + } + ] + }, + "lux": { + "enabled": true, + "output": null, + "ddi_channels": null, + "feedback": false, + "dim_value_night": 100, + "dim_value_twilight": 100, + "dim_value_day": 100, + "ct_value_night": 0, + "ct_value_twilight": 0, + "ct_value_day": 0, + "fade_in_time": 10, + "fade_out_time": 10, + "thresholds": { + "twilight_to_night": 5, + "night_to_twilight": 10, + "day_to_twilight": 15, + "twilight_to_day": 20, + "day_to_night": 5, + "night_to_day": 20 + }, + "light_lpf": true, + "off_period": 900 + }, + "thermostat": { + "active": false, + "min_target_temp": 17, + "max_target_temp": 31, + "target_temp": 21, + "cooling": false, + "enable": true, + "fahrenheit": false, + "free_cooling": false, + "groups": "z", + "mode": { + "local": false, + "remote": false + }, + "feedback": { + "enable": false, + "brightness": 100 + }, + "outputs": [ + { + "controlled": true + }, + { + "controlled": true + }, + { + "controlled": true + }, + { + "controlled": true + } + ], + "user_mode": "comfort" + }, + "led": { + "state": false, + "local_feedback": true, + "groups": "z" + }, + "outputs": { + "outputs": [ + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "halogen_bulb", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Licht Mitte", + "type": "light", + "groups": "ez", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Aussen West", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Licht S\u00fcd", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + } + ] + }, + "blinds": { + "blinds": [ + { + "active": true, + "name": "", + "type": "blind", + "min_value": 0, + "max_value": 100, + "def_blind": 0, + "def_lamella": 80, + "groups": "z", + "auto_calibration": true, + "shade_up_time": 180, + "shade_down_time": 180, + "invert_direction": false, + "lamella_time": 1.8, + "step_duration": 300, + "step_interval": 1200, + "state": "Not initialised" + }, + { + "active": true, + "name": "", + "type": "blind", + "min_value": 0, + "max_value": 100, + "def_blind": 0, + "def_lamella": 80, + "groups": "z", + "auto_calibration": true, + "shade_up_time": 180, + "shade_down_time": 180, + "invert_direction": false, + "lamella_time": 1.8, + "step_duration": 300, + "step_interval": 1200, + "state": "Not initialised" + } + ] + }, + "services": { + "mystrom": false, + "homekit": false, + "rest_api": true, + "panel": true, + "aws": true, + "discovery": false, + "udp_search": true, + "aws_notifies": false, + "ssdp": false, + "mdns": true, + "mdns_search": true, + "homekit_configured": false, + "cloud_ping": false, + "broadcast_period": 5, + "mdns_search_period": 60, + "mqtt": { + "uri": "[redacted]", + "enable": true, + "server.crt": null + }, + "cloud_paired": false, + "cloud_test_enabled": false + }, + "system": { + "rest_password": false, + "protected_status": false, + "allow_reset": true, + "allow_wps": true, + "allow_reboot": true, + "allow_remote_reboot": true, + "allow_update": true, + "origin": true, + "upgrade_blink": true, + "reboot_blink": false, + "dingz_name": "Bastelraum West", + "room_name": "Bastelraum", + "home_name": "", + "id": "[redacted]", + "temp_offset": 6, + "fet_offset": 3.5, + "cpu_offset": 26.8, + "temp_comp": { + "fet_offset": 2.64, + "gain_up": 0.012, + "gain_down": 0.006, + "gain_total": 0.25, + "idle_offset": 0, + "front_offset": 15, + "inf_factor": 0.5 + }, + "sun_offset": 0, + "tzid": 0, + "lat": 46.929, + "long": 7.118, + "dyn_light": { + "enable": false, + "phases": 3, + "source": "lux", + "sun_offset": { + "day": 30, + "twilight": 30, + "night": 30 + } + }, + "wifi_ps": true, + "new_comp_alg": false + }, + "ddi": { + "repeat": true, + "repeat_interval": 5 + }, + "ddi_channels": { + "ddi_channels": [ + { + "name": "BC", + "en": true, + "ddi_group_id": 16, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": true, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + } + ] + }, + "nl": { + "enable": false, + "on": { + "hour": 20, + "minute": 0 + }, + "off": { + "hour": 6, + "minute": 0 + }, + "dimmers": [ + null, + null, + null, + null + ], + "ddi_channels": [ + null, + null, + null, + null + ], + "led": null + }, + "actions": { + "generic": "", + "btn1": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn3": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn4": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "input": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "input2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "thermostat": { + "idle": "", + "heating": "", + "cooling": "", + "repeat_period": 20000 + }, + "lux": { + "night": "", + "twilight": "", + "day": "", + "repeat_period": 0 + }, + "pir1": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir2": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir3": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + } + }, + "scheduler": [] + }, + "error": null + }, "state": { "value": { "dimmers": [ diff --git a/tests/snapshots/4dfaa25d449e.json b/tests/snapshots/4dfaa25d449e.json index 2635517..cfd2adf 100644 --- a/tests/snapshots/4dfaa25d449e.json +++ b/tests/snapshots/4dfaa25d449e.json @@ -54,6 +54,1957 @@ }, "error": null }, + "config_dump": { + "value": { + "buttons": { + "dingz_orientation": "1,2,3,4", + "buttons": [ + { + "active": true, + "name": "Gang OG Licht", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 75 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 1 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Rolladen Dachfenster Auf", + "icon": 8, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "green", + "brightness": 1 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Gang EG Licht", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": false, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "blue", + "brightness": 1 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Rolladen Dachfenster Zu", + "icon": 9, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": false, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "red", + "brightness": 1 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + } + ] + }, + "inputs": { + "inputs": [ + { + "active": true, + "name": "", + "icon": 17, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 75 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 1 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + } + ] + }, + "pir": { + "pirs": [ + { + "active": true, + "name": "Bewegung Gang OG", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "white", + "brightness": 1 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 60, + "manual_on_time": 600, + "manual_off_time": 60 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 300, + "manual_off_time": 300 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 7200, + "manual_off_time": 5 + } + } + ] + }, + "lux": { + "enabled": true, + "output": null, + "ddi_channels": null, + "feedback": false, + "dim_value_night": 100, + "dim_value_twilight": 100, + "dim_value_day": 100, + "ct_value_night": 0, + "ct_value_twilight": 0, + "ct_value_day": 0, + "fade_in_time": 0, + "fade_out_time": 10, + "thresholds": { + "twilight_to_night": 4, + "night_to_twilight": 5, + "day_to_twilight": 10, + "twilight_to_day": 13, + "day_to_night": 10, + "night_to_day": 13 + }, + "light_lpf": true, + "off_period": 900 + }, + "thermostat": { + "active": false, + "min_target_temp": 17, + "max_target_temp": 31, + "target_temp": 21, + "cooling": false, + "enable": true, + "fahrenheit": false, + "free_cooling": false, + "groups": "z", + "mode": { + "local": false, + "remote": false + }, + "feedback": { + "enable": false, + "brightness": 100 + }, + "outputs": [ + { + "controlled": true + }, + { + "controlled": true + }, + { + "controlled": true + }, + { + "controlled": true + } + ], + "user_mode": "comfort" + }, + "led": { + "state": false, + "local_feedback": true, + "groups": "z" + }, + "outputs": { + "outputs": [ + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 1 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Gang OG Licht", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 1 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 30, + "max": 100 + }, + "dynamic": { + "day": 0, + "twilight": 36, + "night": 32 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 1 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + } + ] + }, + "blinds": { + "blinds": [ + { + "active": true, + "name": "", + "type": "blind", + "min_value": 0, + "max_value": 100, + "def_blind": 0, + "def_lamella": 80, + "groups": "z", + "auto_calibration": true, + "shade_up_time": 180, + "shade_down_time": 180, + "invert_direction": false, + "lamella_time": 1.8, + "step_duration": 300, + "step_interval": 1200, + "state": "Not initialised" + }, + { + "active": true, + "name": "", + "type": "blind", + "min_value": 0, + "max_value": 100, + "def_blind": 0, + "def_lamella": 80, + "groups": "z", + "auto_calibration": true, + "shade_up_time": 180, + "shade_down_time": 180, + "invert_direction": false, + "lamella_time": 1.8, + "step_duration": 300, + "step_interval": 1200, + "state": "Not initialised" + } + ] + }, + "services": { + "mystrom": false, + "homekit": false, + "rest_api": true, + "panel": true, + "aws": true, + "discovery": false, + "udp_search": true, + "aws_notifies": false, + "ssdp": false, + "mdns": true, + "mdns_search": true, + "homekit_configured": false, + "cloud_ping": false, + "broadcast_period": 5, + "mdns_search_period": 60, + "mqtt": { + "uri": "[redacted]", + "enable": true, + "server.crt": null + }, + "cloud_paired": false, + "cloud_test_enabled": false + }, + "system": { + "rest_password": false, + "protected_status": false, + "allow_reset": true, + "allow_wps": true, + "allow_reboot": true, + "allow_remote_reboot": true, + "allow_update": true, + "origin": true, + "upgrade_blink": true, + "reboot_blink": false, + "dingz_name": "Treppenhaus dingz", + "room_name": "Treppenhaus", + "home_name": "BG12", + "id": "[redacted]", + "temp_offset": 6, + "fet_offset": 0, + "cpu_offset": 25.2, + "temp_comp": { + "fet_offset": 2.64, + "gain_up": 0.012, + "gain_down": 0.006, + "gain_total": 0.25, + "idle_offset": 0, + "front_offset": 15, + "inf_factor": 0.5 + }, + "sun_offset": 0, + "tzid": 0, + "lat": 46.929, + "long": 7.118, + "dyn_light": { + "enable": true, + "phases": 3, + "source": "lux", + "sun_offset": { + "day": 30, + "twilight": 30, + "night": 30 + } + }, + "wifi_ps": true, + "new_comp_alg": false + }, + "ddi": { + "repeat": true, + "repeat_interval": 5 + }, + "ddi_channels": { + "ddi_channels": [ + { + "name": "BC", + "en": true, + "ddi_group_id": 16, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": true, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + } + ] + }, + "nl": { + "enable": false, + "on": { + "hour": 20, + "minute": 0 + }, + "off": { + "hour": 6, + "minute": 0 + }, + "dimmers": [ + null, + null, + null, + null + ], + "ddi_channels": [ + null, + null, + null, + null + ], + "led": { + "color": "43;11;2" + } + }, + "actions": { + "generic": "", + "btn1": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 3000, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn3": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn4": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 3000, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "input": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "input2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "thermostat": { + "idle": "", + "heating": "", + "cooling": "", + "repeat_period": 60000 + }, + "lux": { + "night": "", + "twilight": "", + "day": "", + "repeat_period": 0 + }, + "pir1": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir2": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir3": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + } + }, + "scheduler": [] + }, + "error": null + }, "state": { "value": { "dimmers": [ diff --git a/tests/snapshots/687e682a7db1.json b/tests/snapshots/687e682a7db1.json index e53345c..a53772c 100644 --- a/tests/snapshots/687e682a7db1.json +++ b/tests/snapshots/687e682a7db1.json @@ -54,6 +54,1955 @@ }, "error": null }, + "config_dump": { + "value": { + "buttons": { + "dingz_orientation": "1,2,3,4", + "buttons": [ + { + "active": true, + "name": "Licht Mitte", + "icon": 1, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": true, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "e", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Licht Tisch", + "icon": 1, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": true, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": true, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Licht Nord", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + } + ] + }, + "inputs": { + "inputs": [ + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_toggle", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + } + ] + }, + "pir": { + "pirs": [ + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": false, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": true, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "e", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "white", + "brightness": 1 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 600, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 7200, + "manual_off_time": 5 + } + } + ] + }, + "lux": { + "enabled": true, + "output": null, + "ddi_channels": null, + "feedback": false, + "dim_value_night": 100, + "dim_value_twilight": 100, + "dim_value_day": 100, + "ct_value_night": 0, + "ct_value_twilight": 0, + "ct_value_day": 0, + "fade_in_time": 10, + "fade_out_time": 10, + "thresholds": { + "twilight_to_night": 5, + "night_to_twilight": 10, + "day_to_twilight": 15, + "twilight_to_day": 20, + "day_to_night": 5, + "night_to_day": 20 + }, + "light_lpf": true, + "off_period": 900 + }, + "thermostat": { + "active": false, + "min_target_temp": 17, + "max_target_temp": 31, + "target_temp": 22, + "cooling": false, + "enable": true, + "fahrenheit": false, + "free_cooling": false, + "groups": "z", + "mode": { + "local": false, + "remote": false + }, + "feedback": { + "enable": false, + "brightness": 100 + }, + "outputs": [ + { + "controlled": true + }, + { + "controlled": true + }, + { + "controlled": true + }, + { + "controlled": true + } + ], + "user_mode": "comfort" + }, + "led": { + "state": false, + "local_feedback": true, + "groups": "z" + }, + "outputs": { + "outputs": [ + { + "active": false, + "name": "Licht Mitte", + "type": "light", + "groups": "ez", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Licht Nord", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "halogen_bulb", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "halogen_bulb", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + } + ] + }, + "blinds": { + "blinds": [ + { + "active": true, + "name": "", + "type": "blind", + "min_value": 0, + "max_value": 100, + "def_blind": 0, + "def_lamella": 80, + "groups": "z", + "auto_calibration": true, + "shade_up_time": 180, + "shade_down_time": 180, + "invert_direction": false, + "lamella_time": 1.8, + "step_duration": 300, + "step_interval": 1200, + "state": "Not initialised" + }, + { + "active": true, + "name": "", + "type": "blind", + "min_value": 0, + "max_value": 100, + "def_blind": 0, + "def_lamella": 80, + "groups": "z", + "auto_calibration": true, + "shade_up_time": 180, + "shade_down_time": 180, + "invert_direction": false, + "lamella_time": 1.8, + "step_duration": 300, + "step_interval": 1200, + "state": "Not initialised" + } + ] + }, + "services": { + "mystrom": false, + "homekit": false, + "rest_api": true, + "panel": true, + "aws": true, + "discovery": false, + "udp_search": true, + "aws_notifies": false, + "ssdp": false, + "mdns": true, + "mdns_search": true, + "homekit_configured": false, + "cloud_ping": false, + "broadcast_period": 5, + "mdns_search_period": 60, + "mqtt": { + "uri": "[redacted]", + "enable": true, + "server.crt": null + }, + "cloud_paired": false, + "cloud_test_enabled": false + }, + "system": { + "rest_password": false, + "protected_status": false, + "allow_reset": true, + "allow_wps": true, + "allow_reboot": true, + "allow_remote_reboot": true, + "allow_update": true, + "origin": true, + "upgrade_blink": true, + "reboot_blink": true, + "dingz_name": "Bastelraum Ost", + "room_name": "Bastelraum", + "home_name": "", + "id": "[redacted]", + "temp_offset": 6, + "fet_offset": 3.5, + "cpu_offset": 26.9, + "temp_comp": { + "fet_offset": 2.64, + "gain_up": 0.012, + "gain_down": 0.006, + "gain_total": 0.25, + "idle_offset": 0, + "front_offset": 15, + "inf_factor": 0.5 + }, + "sun_offset": 0, + "tzid": 0, + "lat": 46.929, + "long": 7.118, + "dyn_light": { + "enable": false, + "phases": 3, + "source": "lux", + "sun_offset": { + "day": 30, + "twilight": 30, + "night": 30 + } + }, + "wifi_ps": true, + "new_comp_alg": false + }, + "ddi": { + "repeat": true, + "repeat_interval": 5 + }, + "ddi_channels": { + "ddi_channels": [ + { + "name": "BC", + "en": true, + "ddi_group_id": 16, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": true, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + } + ] + }, + "nl": { + "enable": false, + "on": { + "hour": 20, + "minute": 0 + }, + "off": { + "hour": 6, + "minute": 0 + }, + "dimmers": [ + null, + null, + null, + null + ], + "ddi_channels": [ + null, + null, + null, + null + ], + "led": null + }, + "actions": { + "generic": "", + "btn1": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn3": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn4": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "input": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "input2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "thermostat": { + "idle": "", + "heating": "", + "cooling": "", + "repeat_period": 20000 + }, + "lux": { + "night": "", + "twilight": "", + "day": "", + "repeat_period": 0 + }, + "pir1": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir2": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir3": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + } + }, + "scheduler": [] + }, + "error": null + }, "state": { "value": { "dimmers": [ diff --git a/tests/snapshots/a1cbf24095e8.json b/tests/snapshots/a1cbf24095e8.json index 75959c0..26ebce8 100644 --- a/tests/snapshots/a1cbf24095e8.json +++ b/tests/snapshots/a1cbf24095e8.json @@ -54,6 +54,1955 @@ }, "error": null }, + "config_dump": { + "value": { + "buttons": { + "dingz_orientation": "1,2,3,4", + "buttons": [ + { + "active": true, + "name": "Gedimmt", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 2 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Licht", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "St\u00e4nderlampe", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": false, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Vitrine", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": false, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + } + ] + }, + "inputs": { + "inputs": [ + { + "active": true, + "name": "Stuebli Licht Eingang", + "icon": 17, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": true, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "white", + "brightness": 50 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "contact_state", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + } + ] + }, + "pir": { + "pirs": [ + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 7200, + "manual_off_time": 5 + } + } + ] + }, + "lux": { + "enabled": true, + "output": null, + "ddi_channels": null, + "feedback": false, + "dim_value_night": 100, + "dim_value_twilight": 100, + "dim_value_day": 100, + "ct_value_night": 0, + "ct_value_twilight": 0, + "ct_value_day": 0, + "fade_in_time": 10, + "fade_out_time": 10, + "thresholds": { + "twilight_to_night": 10, + "night_to_twilight": 30, + "day_to_twilight": 50, + "twilight_to_day": 100, + "day_to_night": 50, + "night_to_day": 100 + }, + "light_lpf": true, + "off_period": 900 + }, + "thermostat": { + "active": false, + "min_target_temp": 17, + "max_target_temp": 31, + "target_temp": 21, + "cooling": false, + "enable": true, + "fahrenheit": false, + "free_cooling": false, + "groups": "z", + "mode": { + "local": false, + "remote": false + }, + "feedback": { + "enable": false, + "brightness": 100 + }, + "outputs": [ + { + "controlled": true + }, + { + "controlled": true + }, + { + "controlled": true + }, + { + "controlled": true + } + ], + "user_mode": "comfort" + }, + "led": { + "state": false, + "local_feedback": true, + "groups": "z" + }, + "outputs": { + "outputs": [ + { + "active": false, + "name": "Eingang", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "led_bulb", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Licht", + "type": "light", + "groups": "bz", + "feedback": { + "color": "none", + "brightness": 10 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "led_driver", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 40, + "night": 2 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Staenderlampe", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Vitrine", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + } + ] + }, + "blinds": { + "blinds": [ + { + "active": true, + "name": "", + "type": "blind", + "min_value": 0, + "max_value": 100, + "def_blind": 0, + "def_lamella": 80, + "groups": "z", + "auto_calibration": true, + "shade_up_time": 180, + "shade_down_time": 180, + "invert_direction": false, + "lamella_time": 1.8, + "step_duration": 300, + "step_interval": 1200, + "state": "Not initialised" + }, + { + "active": true, + "name": "", + "type": "blind", + "min_value": 0, + "max_value": 100, + "def_blind": 0, + "def_lamella": 80, + "groups": "z", + "auto_calibration": true, + "shade_up_time": 180, + "shade_down_time": 180, + "invert_direction": false, + "lamella_time": 1.8, + "step_duration": 300, + "step_interval": 1200, + "state": "Not initialised" + } + ] + }, + "services": { + "mystrom": false, + "homekit": false, + "rest_api": true, + "panel": true, + "aws": true, + "discovery": false, + "udp_search": true, + "aws_notifies": false, + "ssdp": false, + "mdns": true, + "mdns_search": true, + "homekit_configured": false, + "cloud_ping": false, + "broadcast_period": 5, + "mdns_search_period": 60, + "mqtt": { + "uri": "[redacted]", + "enable": true, + "server.crt": null + }, + "cloud_paired": false, + "cloud_test_enabled": false + }, + "system": { + "rest_password": false, + "protected_status": false, + "allow_reset": true, + "allow_wps": true, + "allow_reboot": true, + "allow_remote_reboot": true, + "allow_update": true, + "origin": true, + "upgrade_blink": true, + "reboot_blink": true, + "dingz_name": "Stuebli dingz", + "room_name": "Stuebli", + "home_name": "BG12", + "id": "[redacted]", + "temp_offset": 7.5, + "fet_offset": 1, + "cpu_offset": 25.2, + "temp_comp": { + "fet_offset": 2.64, + "gain_up": 0.012, + "gain_down": 0.006, + "gain_total": 0.25, + "idle_offset": 0, + "front_offset": 15, + "inf_factor": 0.5 + }, + "sun_offset": 0, + "tzid": 0, + "lat": 46.929, + "long": 7.118, + "dyn_light": { + "enable": true, + "phases": 3, + "source": "sun", + "sun_offset": { + "day": 30, + "twilight": 30, + "night": 30 + } + }, + "wifi_ps": true, + "new_comp_alg": false + }, + "ddi": { + "repeat": true, + "repeat_interval": 5 + }, + "ddi_channels": { + "ddi_channels": [ + { + "name": "BC", + "en": true, + "ddi_group_id": 16, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": true, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + } + ] + }, + "nl": { + "enable": false, + "on": { + "hour": 20, + "minute": 0 + }, + "off": { + "hour": 6, + "minute": 0 + }, + "dimmers": [ + null, + null, + null, + null + ], + "ddi_channels": [ + null, + null, + null, + null + ], + "led": null + }, + "actions": { + "generic": "", + "btn1": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn3": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn4": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "input": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "input2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "thermostat": { + "idle": "", + "heating": "", + "cooling": "", + "repeat_period": 60000 + }, + "lux": { + "night": "", + "twilight": "", + "day": "", + "repeat_period": 0 + }, + "pir1": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir2": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir3": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + } + }, + "scheduler": [] + }, + "error": null + }, "state": { "value": { "dimmers": [ diff --git a/tests/snapshots/b6dbe5948d2f.json b/tests/snapshots/b6dbe5948d2f.json index 3d98036..e2fd257 100644 --- a/tests/snapshots/b6dbe5948d2f.json +++ b/tests/snapshots/b6dbe5948d2f.json @@ -54,6 +54,1953 @@ }, "error": null }, + "config_dump": { + "value": { + "buttons": { + "dingz_orientation": "1,2,3,4", + "buttons": [ + { + "active": true, + "name": "Wohnzimmer K\u00fcche", + "icon": 1, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": true, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "a", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Abwaschen", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Essen", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "K\u00fcche Mitte", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + } + ] + }, + "inputs": { + "inputs": [ + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_toggle", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + } + ] + }, + "pir": { + "pirs": [ + { + "active": true, + "name": "Bewegung K\u00fcche", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 20 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 300, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 7200, + "manual_off_time": 5 + } + } + ] + }, + "lux": { + "enabled": true, + "output": null, + "ddi_channels": null, + "feedback": false, + "dim_value_night": 100, + "dim_value_twilight": 100, + "dim_value_day": 100, + "ct_value_night": 0, + "ct_value_twilight": 0, + "ct_value_day": 0, + "fade_in_time": 10, + "fade_out_time": 10, + "thresholds": { + "twilight_to_night": 50, + "night_to_twilight": 100, + "day_to_twilight": 150, + "twilight_to_day": 200, + "day_to_night": 50, + "night_to_day": 200 + }, + "light_lpf": true, + "off_period": 900 + }, + "thermostat": { + "active": false, + "min_target_temp": 17, + "max_target_temp": 31, + "target_temp": 22, + "cooling": false, + "enable": true, + "fahrenheit": false, + "free_cooling": false, + "groups": "z", + "mode": { + "local": false, + "remote": false + }, + "feedback": { + "enable": false, + "brightness": 100 + }, + "outputs": [ + { + "controlled": true + }, + { + "controlled": true + }, + { + "controlled": true + }, + { + "controlled": true + } + ], + "user_mode": "comfort" + }, + "led": { + "state": false, + "local_feedback": true, + "groups": "z" + }, + "outputs": { + "outputs": [ + { + "active": true, + "name": "Essen", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Abwaschen", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": false, + "twilight": false, + "night": false + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "K\u00fcche Mitte", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 70, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": false, + "twilight": false, + "night": false + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": false, + "twilight": false, + "night": false + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + } + ] + }, + "blinds": { + "blinds": [ + { + "active": true, + "name": "", + "type": "blind", + "min_value": 0, + "max_value": 100, + "def_blind": 0, + "def_lamella": 80, + "groups": "z", + "auto_calibration": true, + "shade_up_time": 180, + "shade_down_time": 180, + "invert_direction": false, + "lamella_time": 1.8, + "step_duration": 300, + "step_interval": 1200, + "state": "Not initialised" + }, + { + "active": true, + "name": "", + "type": "blind", + "min_value": 0, + "max_value": 100, + "def_blind": 0, + "def_lamella": 80, + "groups": "z", + "auto_calibration": true, + "shade_up_time": 180, + "shade_down_time": 180, + "invert_direction": false, + "lamella_time": 1.8, + "step_duration": 300, + "step_interval": 1200, + "state": "Not initialised" + } + ] + }, + "services": { + "mystrom": false, + "homekit": false, + "rest_api": true, + "panel": true, + "aws": true, + "discovery": false, + "udp_search": true, + "aws_notifies": false, + "ssdp": false, + "mdns": true, + "mdns_search": true, + "homekit_configured": false, + "cloud_ping": false, + "broadcast_period": 5, + "mdns_search_period": 60, + "mqtt": { + "uri": "[redacted]", + "enable": true, + "server.crt": null + }, + "cloud_paired": false, + "cloud_test_enabled": false + }, + "system": { + "rest_password": false, + "protected_status": false, + "allow_reset": true, + "allow_wps": true, + "allow_reboot": true, + "allow_remote_reboot": true, + "allow_update": true, + "origin": true, + "upgrade_blink": true, + "reboot_blink": true, + "dingz_name": "K\u00fcche", + "room_name": "K\u00fcche", + "home_name": "", + "id": "[redacted]", + "temp_offset": 6, + "temp_comp": { + "fet_offset": 2.64, + "gain_up": 0.012, + "gain_down": 0.006, + "gain_total": 0.25, + "idle_offset": 0, + "front_offset": 15, + "inf_factor": 0.5 + }, + "sun_offset": 0, + "tzid": 0, + "lat": 46.929, + "long": 7.118, + "dyn_light": { + "enable": true, + "phases": 3, + "source": "lux", + "sun_offset": { + "day": 30, + "twilight": 30, + "night": 30 + } + }, + "wifi_ps": true, + "new_comp_alg": false + }, + "ddi": { + "repeat": true, + "repeat_interval": 5 + }, + "ddi_channels": { + "ddi_channels": [ + { + "name": "BC", + "en": true, + "ddi_group_id": 16, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": true, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + }, + { + "name": "", + "en": false, + "ddi_group_id": 0, + "dingz_groups": "z", + "use_last_value": false, + "auto_off_delay": 0, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + }, + "features": { + "colour_temperature": { + "en": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + } + } + ] + }, + "nl": { + "enable": false, + "on": { + "hour": 20, + "minute": 0 + }, + "off": { + "hour": 6, + "minute": 0 + }, + "dimmers": [ + null, + null, + null, + null + ], + "ddi_channels": [ + null, + null, + null, + null + ], + "led": null + }, + "actions": { + "generic": "", + "btn1": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn3": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn4": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "input": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "input2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "thermostat": { + "idle": "", + "heating": "", + "cooling": "", + "repeat_period": 20000 + }, + "lux": { + "night": "", + "twilight": "", + "day": "", + "repeat_period": 0 + }, + "pir1": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir2": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir3": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + } + }, + "scheduler": [] + }, + "error": null + }, "state": { "value": { "dimmers": [ diff --git a/tests/test_rest_types.py b/tests/test_rest_types.py index 0e2eb2c..80cf069 100644 --- a/tests/test_rest_types.py +++ b/tests/test_rest_types.py @@ -7,7 +7,7 @@ from pydantic import TypeAdapter -from dingz.rest import Device, NetworkInfo, Ram, RestClient, State +from dingz.rest import ConfigDump, Device, NetworkInfo, Ram, RestClient, State def _validate_strict(ty: Any, value: Any) -> None: @@ -25,6 +25,11 @@ async def test_network_info(rest_client_with_snapshot: RestClient) -> None: _validate_strict(NetworkInfo, nw_info) +async def test_config_dump(rest_client_with_snapshot: RestClient) -> None: + config_dump = await rest_client_with_snapshot.get_config_dump() + _validate_strict(ConfigDump, config_dump) + + async def test_state(rest_client_with_snapshot: RestClient) -> None: state = await rest_client_with_snapshot.get_state() _validate_strict(State, state) From acd2bf60509ce19dd0ea0685d710cbfa87513ce3 Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Thu, 14 Aug 2025 23:12:30 +0000 Subject: [PATCH 18/21] feat(rest): add scheduler config --- dingz/rest/_client.py | 5 +++ dingz/rest/_types/config.py | 58 ++++++++++++++++++++++++++++--- tests/snapshots/687e682a7db1.json | 45 +++++++++++++++++++++++- 3 files changed, 103 insertions(+), 5 deletions(-) diff --git a/dingz/rest/_client.py b/dingz/rest/_client.py index 026b287..22676a2 100644 --- a/dingz/rest/_client.py +++ b/dingz/rest/_client.py @@ -23,6 +23,7 @@ OutputsConfig, PirsConfig, Ram, + SchedulerConfig, ServicesConfig, State, SystemConfig, @@ -191,6 +192,10 @@ async def get_actions_config(self) -> ActionsConfig: """Get the actions configuration.""" return await self._request("GET", URL("/api/v1/actions")) + async def get_scheduler_config(self) -> list[SchedulerConfig]: + """Get the scheduler configuration.""" + return await self._request("GET", URL("/api/v1/scheduler")) + async def get_config_dump(self) -> ConfigDump: """Get the full configuration dump.""" # dump_config reports content type application/octet-stream for some reason diff --git a/dingz/rest/_types/config.py b/dingz/rest/_types/config.py index 258402b..fc9be82 100644 --- a/dingz/rest/_types/config.py +++ b/dingz/rest/_types/config.py @@ -25,6 +25,7 @@ "OutputsConfig", "PirConfig", "PirsConfig", + "SchedulerConfig", "ServicesConfig", "SystemConfig", "ThermostatConfig", @@ -99,19 +100,19 @@ class _Outputs(TypedDict): ddi: _OutputsDdi -class _MotorsCustom(TypedDict): +class _BlindAndLamella(TypedDict): blind: int lamella: int class _MotorsLocal(TypedDict): controlled: bool - custom: _MotorsCustom + custom: _BlindAndLamella class _MotorsRemote(TypedDict): groups: str - custom: _MotorsCustom + custom: _BlindAndLamella class _Motors(TypedDict): @@ -641,6 +642,55 @@ class ActionsConfig(TypedDict): pir3: _ActionsConfigPir +class _SchedulerConfigBcEventsLightsConfigActions(TypedDict): + off: bool + default_on: bool + custom_on: bool + + +class _SchedulerConfigBcEventsLightsConfig(TypedDict): + fade_in_time: int + fade_out_time: int + groups: str + custom_value: int + actions: _SchedulerConfigBcEventsLightsConfigActions + + +class _SchedulerConfigBcEventsMotorsConfigActions(TypedDict): + open: bool + close: bool + default_pos: bool + custom_pos: bool + + +class _SchedulerConfigBcEventsMotorsConfig(TypedDict): + groups: str + shade_position: _BlindAndLamella + actions: _SchedulerConfigBcEventsMotorsConfigActions + + +class _SchedulerConfigBcEvents(TypedDict): + remote_type: _LightAndMotor + lights_config: _SchedulerConfigBcEventsLightsConfig + motors_config: _SchedulerConfigBcEventsMotorsConfig + + +class SchedulerConfig(TypedDict): + """Scheduler config returned by the `/api/v1/scheduler` endpoint.""" + + id: int + name: str + en: bool + type: Literal["time"] + hour: int + min: int + offset: int + rand: int + days: str + url: str + bc_events: _SchedulerConfigBcEvents + + class ConfigDump(TypedDict): """Full config dump returned by the `/api/v1/dump_config` endpoint.""" @@ -658,4 +708,4 @@ class ConfigDump(TypedDict): ddi_channels: DdiChannelsConfig nl: NlConfig actions: ActionsConfig - # scheduler: list[...] + scheduler: list[SchedulerConfig] diff --git a/tests/snapshots/687e682a7db1.json b/tests/snapshots/687e682a7db1.json index a53772c..b321731 100644 --- a/tests/snapshots/687e682a7db1.json +++ b/tests/snapshots/687e682a7db1.json @@ -1999,7 +1999,50 @@ } } }, - "scheduler": [] + "scheduler": [ + { + "id": 1, + "name": "test", + "en": false, + "type": "time", + "hour": 0, + "min": 0, + "offset": 0, + "rand": 0, + "days": "", + "url": "", + "bc_events": { + "remote_type": { + "light": false, + "motor": false + }, + "lights_config": { + "fade_in_time": 0, + "fade_out_time": 0, + "groups": "", + "custom_value": 100, + "actions": { + "off": false, + "default_on": true, + "custom_on": false + } + }, + "motors_config": { + "groups": "", + "shade_position": { + "blind": 100, + "lamella": 100 + }, + "actions": { + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + } + } + } + } + ] }, "error": null }, From 3dc73835a2a96720e6040b1a4ab3d1822b36ec63 Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Thu, 14 Aug 2025 23:27:25 +0000 Subject: [PATCH 19/21] chore: update dingz.rest exports --- dingz/rest/__init__.py | 46 +++++++++++++++++++++++++++++++++-- dingz/rest/_types/__init__.py | 1 - dingz/rest/_types/config.py | 5 +--- dingz/rest/_types/device.py | 16 ++++++++---- dingz/rest/_types/helpers.py | 31 ----------------------- dingz/rest/_types/state.py | 19 +++++++++++---- 6 files changed, 70 insertions(+), 48 deletions(-) delete mode 100644 dingz/rest/_types/helpers.py diff --git a/dingz/rest/__init__.py b/dingz/rest/__init__.py index 8ae847c..0b67587 100644 --- a/dingz/rest/__init__.py +++ b/dingz/rest/__init__.py @@ -2,46 +2,88 @@ from ._client import RestClient from ._types import ( + ActionsConfig, + BlindConfig, + BlindsConfig, + BlindState, ButtonConfig, ButtonsConfig, + CloudState, ConfigDump, ConfigState, - Date, + DdiChannelConfig, + DdiChannelsConfig, + DdiChannelState, + DdiConfig, Device, + DimmerState, DynLightState, + FrontColorCode, InputConfig, InputsConfig, + LedConfig, LedState, LightState, + LuxConfig, NetworkInfo, + NlConfig, + OutputConfig, + OutputsConfig, + PirConfig, + PirsConfig, PirSensorState, PowerOutputSensorState, Ram, + SchedulerConfig, SensorsState, + ServicesConfig, State, + SystemConfig, + ThermostatConfig, ThermostatState, WifiState, ) __all__ = [ + "ActionsConfig", + "BlindConfig", + "BlindState", + "BlindsConfig", "ButtonConfig", "ButtonsConfig", + "CloudState", "ConfigDump", "ConfigState", - "Date", + "DdiChannelConfig", + "DdiChannelState", + "DdiChannelsConfig", + "DdiConfig", "Device", + "DimmerState", "DynLightState", + "FrontColorCode", "InputConfig", "InputsConfig", + "LedConfig", "LedState", "LightState", + "LuxConfig", "NetworkInfo", + "NlConfig", + "OutputConfig", + "OutputsConfig", + "PirConfig", "PirSensorState", + "PirsConfig", "PowerOutputSensorState", "Ram", "RestClient", + "SchedulerConfig", "SensorsState", + "ServicesConfig", "State", + "SystemConfig", + "ThermostatConfig", "ThermostatState", "WifiState", ] diff --git a/dingz/rest/_types/__init__.py b/dingz/rest/_types/__init__.py index 1571d0e..8fe9a42 100644 --- a/dingz/rest/_types/__init__.py +++ b/dingz/rest/_types/__init__.py @@ -1,4 +1,3 @@ from .config import * # noqa: F403 from .device import * # noqa: F403 -from .helpers import * # noqa: F403 from .state import * # noqa: F403 diff --git a/dingz/rest/_types/config.py b/dingz/rest/_types/config.py index fc9be82..005ff19 100644 --- a/dingz/rest/_types/config.py +++ b/dingz/rest/_types/config.py @@ -2,9 +2,6 @@ from typing_extensions import Literal, NotRequired, TypedDict -# We need to actually import these types for `pydantic.TypeAdapter` to work. -from .helpers import Color # noqa: TC001 - __all__ = [ "ActionsConfig", "BlindConfig", @@ -122,7 +119,7 @@ class _Motors(TypedDict): class _Feedback(TypedDict): - color: Literal["none"] | Color + color: Literal["none", "red", "blue", "green", "white"] brightness: int diff --git a/dingz/rest/_types/device.py b/dingz/rest/_types/device.py index 2eb8cd8..135dec6 100644 --- a/dingz/rest/_types/device.py +++ b/dingz/rest/_types/device.py @@ -2,15 +2,21 @@ from typing_extensions import Literal, NotRequired, TypedDict -# We need to actually import these types for `pydantic.TypeAdapter` to work. -from .helpers import Date, ShortColorCode # noqa: TC001 - __all__ = [ "Device", + "FrontColorCode", "NetworkInfo", "Ram", ] +FrontColorCode = Literal["WH", "MC"] + + +class _Date(TypedDict): + year: int + month: int + day: int + class Device(TypedDict): """Device information returned by the `/api/v1/device` endpoint.""" @@ -32,7 +38,7 @@ class Device(TypedDict): hw_version_puck: str hw_id_puck: int puck_sn: str - puck_production_date: Date + puck_production_date: _Date ddi_base: bool dip_config: int dip_static: bool @@ -59,7 +65,7 @@ class Device(TypedDict): Can be missing. """ - front_color: ShortColorCode + front_color: FrontColorCode has_pir: bool first_boot: bool hash: str diff --git a/dingz/rest/_types/helpers.py b/dingz/rest/_types/helpers.py deleted file mode 100644 index 48b04d6..0000000 --- a/dingz/rest/_types/helpers.py +++ /dev/null @@ -1,31 +0,0 @@ -from typing_extensions import Literal, TypedDict - -__all__ = [ - "Color", - "Date", - "Index", - "ShortColorCode", -] - -ShortColorCode = Literal["WH", "MC"] -Color = Literal["red", "blue", "green", "white"] - - -class Index(TypedDict): - """Index information of a dingz sub-component.""" - - relative: int - """The relative index of dimmer (depending on DIP switch configuration). - - Use this index to refer to component for actions. - """ - absolute: int - """The absolute index. Refers to hardware output number.""" - - -class Date(TypedDict): - """Split date information part of `Device`.""" - - year: int - month: int - day: int diff --git a/dingz/rest/_types/state.py b/dingz/rest/_types/state.py index 47fc4dd..980243d 100644 --- a/dingz/rest/_types/state.py +++ b/dingz/rest/_types/state.py @@ -2,9 +2,6 @@ from typing_extensions import Literal, TypedDict -# We need to actually import these types for `pydantic.TypeAdapter` to work. -from .helpers import Index # noqa: TC001 - __all__ = [ "BlindState", "CloudState", @@ -25,6 +22,18 @@ LightState = Literal["day", "twilight", "night"] +class _Index(TypedDict): + """Index information of a dingz sub-component.""" + + relative: int + """The relative index of dimmer (depending on DIP switch configuration). + + Use this index to refer to component for actions. + """ + absolute: int + """The absolute index. Refers to hardware output number.""" + + class DimmerState(TypedDict): """Dimmer status part of `State`.""" @@ -42,7 +51,7 @@ class DimmerState(TypedDict): off_timer_type: Literal["none", "pir"] # TODO: incomplete off_timer_id: int off_timer_value: int - index: Index + index: _Index # TODO CHECK @@ -55,7 +64,7 @@ class BlindState(TypedDict): lamella: int """closed = 0, open = 100""" readonly: bool - index: Index + index: _Index # TODO CHECK From 470414ae868d83fab63362c65e9521032009b58c Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Sat, 16 Aug 2025 19:43:22 +0000 Subject: [PATCH 20/21] feat(gather): run gather in parallel --- scripts/gather.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/scripts/gather.py b/scripts/gather.py index 708d767..0560127 100755 --- a/scripts/gather.py +++ b/scripts/gather.py @@ -68,12 +68,25 @@ async def main() -> None: if args.host is not None: hosts.add(args.host) + semaphore = asyncio.Semaphore(8) + + tasks: list[asyncio.Task[None]] = [] for host in hosts: + await semaphore.acquire() + task = asyncio.create_task(_run_for_host(host, semaphore=semaphore)) + tasks.append(task) + await asyncio.gather(*tasks) + + +async def _run_for_host(host: str, *, semaphore: asyncio.Semaphore) -> None: + try: async with RestClient(host) as client: _LOGGER.info("Gathering data from %s", host) snapshot = await gather_snapshot(client) _LOGGER.info("Done with %s. Writing to %s", host, snapshot.path()) snapshot.save() + finally: + semaphore.release() T = TypeVar("T") From cebf7b60970c3f6d71daab77c3cd1dd77435d9c8 Mon Sep 17 00:00:00 2001 From: Simon Berger Date: Sat, 16 Aug 2025 20:24:57 +0000 Subject: [PATCH 21/21] chore: test the individual config endpoints as well --- dingz/rest/_client.py | 2 +- dingz/rest/_types/config.py | 2 + dingz/rest/_types/state.py | 2 +- scripts/gather.py | 113 +- tests/snapshot.py | 129 ++- tests/snapshots/07f40e76ee72.json | 1743 +++++++++++++++++++++++++++- tests/snapshots/1b148b4bc772.json | 1737 ++++++++++++++++++++++++++++ tests/snapshots/336a87b7ddcc.json | 1739 +++++++++++++++++++++++++++- tests/snapshots/4dfaa25d449e.json | 1739 +++++++++++++++++++++++++++- tests/snapshots/687e682a7db1.json | 1780 +++++++++++++++++++++++++++++ tests/snapshots/a1cbf24095e8.json | 1739 +++++++++++++++++++++++++++- tests/snapshots/b6dbe5948d2f.json | 1737 +++++++++++++++++++++++++++- tests/test_rest_types.py | 71 +- 13 files changed, 12490 insertions(+), 43 deletions(-) diff --git a/dingz/rest/_client.py b/dingz/rest/_client.py index 22676a2..1fa2861 100644 --- a/dingz/rest/_client.py +++ b/dingz/rest/_client.py @@ -190,7 +190,7 @@ async def get_ddi_config(self) -> DdiConfig: async def get_actions_config(self) -> ActionsConfig: """Get the actions configuration.""" - return await self._request("GET", URL("/api/v1/actions")) + return await self._request("GET", URL("/api/v1/action")) async def get_scheduler_config(self) -> list[SchedulerConfig]: """Get the scheduler configuration.""" diff --git a/dingz/rest/_types/config.py b/dingz/rest/_types/config.py index 005ff19..1e75ef8 100644 --- a/dingz/rest/_types/config.py +++ b/dingz/rest/_types/config.py @@ -486,6 +486,8 @@ class SystemConfig(TypedDict): dyn_light: _SystemConfigDynLight wifi_ps: bool new_comp_alg: bool + # TODO: there are more fields when the system config is requested through its dedicated API + # compared to the dump config. class DdiConfig(TypedDict): diff --git a/dingz/rest/_types/state.py b/dingz/rest/_types/state.py index 980243d..e297499 100644 --- a/dingz/rest/_types/state.py +++ b/dingz/rest/_types/state.py @@ -105,7 +105,7 @@ class PirSensorState(TypedDict): enabled: bool motion: bool - mode: Literal["idle"] # TODO: INCOMPLETE + mode: Literal["auto", "idle"] # TODO: INCOMPLETE light_off_timer: int suspend_timer: int diff --git a/scripts/gather.py b/scripts/gather.py index 0560127..c3b15c5 100755 --- a/scripts/gather.py +++ b/scripts/gather.py @@ -13,21 +13,17 @@ import dataclasses import hashlib import logging -from pathlib import Path from typing import TYPE_CHECKING, Any, Callable, Protocol, TypeVar, cast import dingz.discovery from dingz.rest import Device, RestClient -from tests.snapshot import Endpoint, Error, Snapshot +from tests.snapshot import REDACTED_VALUE, Endpoint, Error, Snapshot if TYPE_CHECKING: from collections.abc import Awaitable, Iterable _LOGGER = logging.getLogger(__name__) -_PROJECT_ROOT = Path(__file__).parent.parent -_REDACTED_VALUE = "[redacted]" - class _Args(Protocol): host: str | None @@ -121,7 +117,9 @@ def _redact_path(container: Any, path: str) -> bool: key = segments[-1] if not (isinstance(container, dict) and key in container): return False - container[key] = _REDACTED_VALUE + # Preserve empty strings + if container[key] != "": + container[key] = REDACTED_VALUE return True @@ -162,6 +160,11 @@ async def gather_snapshot(client: RestClient) -> Snapshot: config_dump=await gather_endpoint( lambda: client.get_config_dump(), name="config_dump", + redact_paths=[ + "services.mqtt.uri", + "system.id", + *[f"actions.{key}" for key in _REDACT_ACTIONS_CONFIG], + ], ), state=await gather_endpoint( lambda: client.get_state(), @@ -180,9 +183,107 @@ async def gather_snapshot(client: RestClient) -> Snapshot: name="ram", redact_paths=[], ), + button_config=await gather_endpoint( + lambda: client.get_button_config(), + name="button_config", + ), + input_config=await gather_endpoint( + lambda: client.get_input_config(), + name="input_config", + ), + pir_config=await gather_endpoint( + lambda: client.get_pir_config(), + name="pir_config", + ), + lux_config=await gather_endpoint( + lambda: client.get_lux_config(), + name="lux_config", + ), + output_config=await gather_endpoint( + lambda: client.get_output_config(), + name="output_config", + ), + services_config=await gather_endpoint( + lambda: client.get_services_config(), name="services_config", redact_paths=["mqtt.uri"] + ), + system_config=await gather_endpoint( + lambda: client.get_system_config(), + name="system_config", + redact_paths=["id"], + ), + ddi_config=await gather_endpoint( + lambda: client.get_ddi_config(), + name="ddi_config", + ), + actions_config=await gather_endpoint( + lambda: client.get_actions_config(), + name="actions_config", + redact_paths=_REDACT_ACTIONS_CONFIG, + ), + scheduler_config=await gather_endpoint( + lambda: client.get_scheduler_config(), + name="scheduler_config", + ), ) +_REDACT_ACTIONS_CONFIG_BASE = [ + "single", + "double", + "long", + "m3", + "m4", + "m5", + "begin", + "hold_up", + "hold_down", + "end", + "off", +] + +_REDACT_ACTIONS_CONFIG_INPUT = [ + *_REDACT_ACTIONS_CONFIG_BASE, + "active", + "inactive", +] + +_REDACT_ACTIONS_CONFIG_THERMOSTAT = [ + "idle", + "heating", + "cooling", +] + +_REDACT_ACTIONS_CONFIG_LUX = [ + "night", + "twilight", + "day", +] + +_REDACT_ACTIONS_CONFIG_PIR = [ + "night", + "twilight", + "day", + "rise", + "fall", + "timer_off", +] + +_REDACT_ACTIONS_CONFIG = [ + "generic", + *[f"btn1.{key}" for key in _REDACT_ACTIONS_CONFIG_BASE], + *[f"btn2.{key}" for key in _REDACT_ACTIONS_CONFIG_BASE], + *[f"btn3.{key}" for key in _REDACT_ACTIONS_CONFIG_BASE], + *[f"btn4.{key}" for key in _REDACT_ACTIONS_CONFIG_BASE], + *[f"input.{key}" for key in _REDACT_ACTIONS_CONFIG_INPUT], + *[f"input2.{key}" for key in _REDACT_ACTIONS_CONFIG_INPUT], + *[f"thermostat.{key}" for key in _REDACT_ACTIONS_CONFIG_THERMOSTAT], + *[f"lux.{key}" for key in _REDACT_ACTIONS_CONFIG_LUX], + *[f"pir1.{key}" for key in _REDACT_ACTIONS_CONFIG_PIR], + *[f"pir2.{key}" for key in _REDACT_ACTIONS_CONFIG_PIR], + *[f"pir3.{key}" for key in _REDACT_ACTIONS_CONFIG_PIR], +] + + def _generate_device_hash(data: Device) -> str: device_hash = hashlib.sha256(usedforsecurity=False) try: diff --git a/tests/snapshot.py b/tests/snapshot.py index a87c0ff..4fc5581 100644 --- a/tests/snapshot.py +++ b/tests/snapshot.py @@ -3,21 +3,41 @@ import dataclasses import json from pathlib import Path -from typing import TYPE_CHECKING, Any, Generic, TypeVar +from typing import TYPE_CHECKING, Any, Generic, TypeVar, cast from typing_extensions import Self if TYPE_CHECKING: from collections.abc import Mapping - from dingz.rest import ConfigDump, Device, NetworkInfo, Ram, State + from dingz.rest import ( + ActionsConfig, + ButtonsConfig, + ConfigDump, + DdiConfig, + Device, + InputsConfig, + LuxConfig, + NetworkInfo, + OutputsConfig, + PirsConfig, + Ram, + SchedulerConfig, + ServicesConfig, + State, + SystemConfig, + ) __all__ = [ + "REDACTED_VALUE", "Endpoint", "Error", "Snapshot", ] +REDACTED_VALUE = "[redacted]" + + _TESTS_DIR = Path(__file__).parent _SNAPSHOTS_DIR = _TESTS_DIR / "snapshots" @@ -60,39 +80,63 @@ class Snapshot: config_dump: Endpoint[ConfigDump] state: Endpoint[State] ram: Endpoint[Ram] + button_config: Endpoint[ButtonsConfig] + input_config: Endpoint[InputsConfig] + pir_config: Endpoint[PirsConfig] + lux_config: Endpoint[LuxConfig] + output_config: Endpoint[OutputsConfig] + services_config: Endpoint[ServicesConfig] + system_config: Endpoint[SystemConfig] + ddi_config: Endpoint[DdiConfig] + actions_config: Endpoint[ActionsConfig] + scheduler_config: Endpoint[list[SchedulerConfig]] def endpoint_by_path(self, path: str) -> Endpoint[Any]: - if path == "/api/v1/device": - return self.device - if path == "/api/v1/info": - return self.network_info - if path == "/api/v1/dump_config": - return self.config_dump - if path == "/api/v1/state": - return self.state - if path == "/api/v1/ram": - return self.ram - msg = f"Unknown endpoint path: {path}" - raise LookupError(msg) + attr = _ENDPOINT_ATTR_MAP.get(path) + if not attr: + msg = f"Unknown endpoint path: {path}" + raise LookupError(msg) + return getattr(self, attr) def path(self) -> Path: return _SNAPSHOTS_DIR / f"{self.device_hash}.json" - def save(self) -> None: - text = json.dumps(dataclasses.asdict(self), indent=2) - self.path().write_text(text, encoding="utf-8") + def save(self, *, force_update: bool = False) -> None: + data = dataclasses.asdict(self) + path = self.path() + if not force_update and path.exists(): + old_data = json.loads(path.read_text(encoding="utf-8")) + data = _preserve_old_value(old_data, data) + + text = json.dumps(data, indent=2) + path.write_text(text, encoding="utf-8") @classmethod def from_dict(cls, data: Mapping[str, Any]) -> Self: - return cls( - device_hash=data["device_hash"], - firmware_version=Endpoint.from_dict(data["firmware_version"]), - device=Endpoint.from_dict(data["device"]), - network_info=Endpoint.from_dict(data["network_info"]), - config_dump=Endpoint.from_dict(data["config_dump"]), - state=Endpoint.from_dict(data["state"]), - ram=Endpoint.from_dict(data["ram"]), - ) + kwargs: dict[str, Endpoint[Any]] = {} + for attr in _ENDPOINT_ATTR_MAP.values(): + kwargs[attr] = Endpoint.from_dict(data[attr]) + return cls(device_hash=data["device_hash"], **kwargs) + + +_ENDPOINT_ATTR_MAP: dict[str, str] = { + "/api/v1/firmware": "firmware_version", + "/api/v1/device": "device", + "/api/v1/info": "network_info", + "/api/v1/dump_config": "config_dump", + "/api/v1/state": "state", + "/api/v1/ram": "ram", + "/api/v1/button_config": "button_config", + "/api/v1/input_config": "input_config", + "/api/v1/pir_config": "pir_config", + "/api/v1/lux_config": "lux_config", + "/api/v1/output_config": "output_config", + "/api/v1/services_config": "services_config", + "/api/v1/system_config": "system_config", + "/api/v1/ddi_config": "ddi_config", + "/api/v1/action": "actions_config", + "/api/v1/scheduler": "scheduler_config", +} def load_snapshots() -> list[Snapshot]: @@ -101,3 +145,36 @@ def load_snapshots() -> list[Snapshot]: data = json.loads(path.read_text(encoding="utf-8")) snapshots.append(Snapshot.from_dict(data)) return snapshots + + +def _preserve_old_value(old: Any, new: Any) -> Any: # noqa: PLR0911 + """Recursively preserve old values if they haven't changed type or meaning.""" + if isinstance(old, float) and isinstance(new, int): + # Value changed from float to int. The API returns ints if the value happens to align. + return old + if type(old) is not type(new): + return new + if isinstance(old, dict): + old = cast("dict[Any, Any]", old) + new_dict = new.copy() + for key, old_value in old.items(): + if key not in new_dict: + continue + new_value = new_dict[key] + new_dict[key] = _preserve_old_value(old_value, new_value) + return new_dict + if isinstance(old, list): + old = cast("list[Any]", old) + if len(old) != len(new): + return new + return [_preserve_old_value(old_item, new_item) for old_item, new_item in zip(old, new)] + + if new == REDACTED_VALUE: + # Always use the redacted value even if old wasn't yet + return REDACTED_VALUE + + if (new == "") != (old == ""): + # We changed from empty to non-empty string or vice versa + return new + + return old diff --git a/tests/snapshots/07f40e76ee72.json b/tests/snapshots/07f40e76ee72.json index 8ce903c..ecb3f3d 100644 --- a/tests/snapshots/07f40e76ee72.json +++ b/tests/snapshots/07f40e76ee72.json @@ -1323,7 +1323,7 @@ }, { "active": true, - "name": "", + "name": "Terrasse Licht Wand", "type": "light", "groups": "z", "feedback": { @@ -1398,9 +1398,9 @@ }, { "active": false, - "name": "", + "name": "Terrasse Licht Tisch virtuell", "type": "light", - "groups": "z", + "groups": "", "feedback": { "color": "none", "brightness": 100 @@ -2160,5 +2160,1742 @@ "caps_min_free_heap": 10484 }, "error": null + }, + "button_config": { + "value": { + "dingz_orientation": "1,2,3,4", + "buttons": [ + { + "active": true, + "name": "Terrasse Licht Wand", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Terrasse Tisch", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": true, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "white", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Wohnzimmer", + "icon": 1, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": true, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": false, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "a", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Gang EG", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": false, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + } + ] + }, + "error": null + }, + "input_config": { + "value": { + "inputs": [ + { + "active": false, + "name": "", + "icon": 17, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_toggle", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + } + ] + }, + "error": null + }, + "pir_config": { + "value": { + "pirs": [ + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 7200, + "manual_off_time": 5 + } + } + ] + }, + "error": null + }, + "lux_config": { + "value": { + "enabled": true, + "output": null, + "ddi_channels": null, + "feedback": false, + "dim_value_night": 30, + "dim_value_twilight": 50, + "dim_value_day": 75, + "ct_value_night": 0, + "ct_value_twilight": 0, + "ct_value_day": 0, + "fade_in_time": 10, + "fade_out_time": 10, + "thresholds": { + "twilight_to_night": 50, + "night_to_twilight": 100, + "day_to_twilight": 150, + "twilight_to_day": 200, + "day_to_night": 50, + "night_to_day": 200 + }, + "light_lpf": true, + "off_period": 900 + }, + "error": null + }, + "output_config": { + "value": { + "outputs": [ + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Terrasse Licht Wand", + "type": "light", + "groups": "z", + "feedback": { + "color": "white", + "brightness": 1 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "led_bulb", + "use_last_value": false, + "range": { + "min": 30, + "max": 100 + }, + "dynamic": { + "day": 75, + "twilight": 50, + "night": 30 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Terrasse Licht Tisch virtuell", + "type": "light", + "groups": "", + "feedback": { + "color": "green", + "brightness": 1 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 0, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 50, + "night": 5 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + } + ] + }, + "error": null + }, + "services_config": { + "value": { + "mystrom": false, + "homekit": false, + "rest_api": true, + "panel": true, + "aws": true, + "discovery": false, + "udp_search": true, + "aws_notifies": false, + "ssdp": false, + "mdns": true, + "mdns_search": true, + "homekit_configured": false, + "cloud_ping": false, + "broadcast_period": 5, + "mdns_search_period": 60, + "mqtt": { + "uri": "[redacted]", + "enable": true, + "server.crt": null + }, + "cloud_paired": false, + "cloud_test_enabled": false + }, + "error": null + }, + "system_config": { + "value": { + "rest_password": false, + "protected_status": false, + "allow_reset": true, + "allow_wps": true, + "allow_reboot": true, + "allow_remote_reboot": true, + "allow_update": true, + "origin": true, + "upgrade_blink": true, + "reboot_blink": false, + "dingz_name": "Wohnzimmer Terrasse", + "room_name": "Wohnzimmer", + "home_name": "BG12", + "id": "[redacted]", + "temp_offset": 7, + "fet_offset": 2.6666666666666665, + "cpu_offset": 26.6, + "temp_comp": { + "fet_offset": 2.64, + "gain_up": 0.012, + "gain_down": 0.006, + "gain_total": 0.25, + "idle_offset": 0, + "front_offset": 15, + "inf_factor": 0.5 + }, + "sun_offset": 0, + "tzid": 0, + "lat": 46.929, + "long": 7.118, + "dyn_light": { + "enable": true, + "phases": 3, + "source": "sun", + "sun_offset": { + "day": 30, + "twilight": 30, + "night": 30 + } + }, + "wifi_ps": true, + "new_comp_alg": false, + "time": "2025-08-16 22:20:22", + "sunrise": { + "hour": 6, + "minute": 29 + }, + "sunset": { + "hour": 20, + "minute": 41 + }, + "system_status": "OK" + }, + "error": null + }, + "ddi_config": { + "value": { + "repeat": true, + "repeat_interval": 5 + }, + "error": null + }, + "actions_config": { + "value": { + "generic": "", + "btn1": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn3": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn4": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "input": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "input2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "thermostat": { + "idle": "", + "heating": "", + "cooling": "", + "repeat_period": 60000 + }, + "lux": { + "night": "", + "twilight": "", + "day": "", + "repeat_period": 0 + }, + "pir1": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir2": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir3": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + } + }, + "error": null + }, + "scheduler_config": { + "value": [], + "error": null } } \ No newline at end of file diff --git a/tests/snapshots/1b148b4bc772.json b/tests/snapshots/1b148b4bc772.json index 7f46ea4..76414db 100644 --- a/tests/snapshots/1b148b4bc772.json +++ b/tests/snapshots/1b148b4bc772.json @@ -2162,5 +2162,1742 @@ "caps_min_free_heap": 12852 }, "error": null + }, + "button_config": { + "value": { + "dingz_orientation": "1,2,3,4", + "buttons": [ + { + "active": true, + "name": "St\u00fcbli", + "icon": 0, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": true, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "b", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 0 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Wohnzimmer", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Sofa", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 73 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + } + ] + }, + "error": null + }, + "input_config": { + "value": { + "inputs": [ + { + "active": true, + "name": "Wohnzimmer K\u00fcche", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_toggle", + "invert": true, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + } + ] + }, + "error": null + }, + "pir_config": { + "value": { + "pirs": [ + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 7200, + "manual_off_time": 5 + } + } + ] + }, + "error": null + }, + "lux_config": { + "value": { + "enabled": true, + "output": null, + "ddi_channels": null, + "feedback": false, + "dim_value_night": 100, + "dim_value_twilight": 100, + "dim_value_day": 100, + "ct_value_night": 0, + "ct_value_twilight": 0, + "ct_value_day": 0, + "fade_in_time": 10, + "fade_out_time": 10, + "thresholds": { + "twilight_to_night": 50, + "night_to_twilight": 100, + "day_to_twilight": 150, + "twilight_to_day": 200, + "day_to_night": 50, + "night_to_day": 200 + }, + "light_lpf": true, + "off_period": 900 + }, + "error": null + }, + "output_config": { + "value": { + "outputs": [ + { + "active": true, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": false, + "name": "St\u00fcbli", + "type": "light", + "groups": "bz", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": true, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 0, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": false, + "twilight": false, + "night": false + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Sofa", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 67 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "led_bulb", + "use_last_value": false, + "range": { + "min": 25, + "max": 100 + }, + "dynamic": { + "day": 75, + "twilight": 50, + "night": 34 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Wohnzimmer", + "type": "light", + "groups": "az", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "led_driver", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 60, + "twilight": 35, + "night": 10 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + } + ] + }, + "error": null + }, + "services_config": { + "value": { + "mystrom": false, + "homekit": false, + "rest_api": true, + "panel": true, + "aws": true, + "discovery": false, + "udp_search": true, + "aws_notifies": false, + "ssdp": false, + "mdns": true, + "mdns_search": true, + "homekit_configured": false, + "cloud_ping": false, + "broadcast_period": 5, + "mdns_search_period": 60, + "mqtt": { + "uri": "[redacted]", + "enable": true, + "server.crt": null + }, + "cloud_paired": false, + "cloud_test_enabled": false + }, + "error": null + }, + "system_config": { + "value": { + "rest_password": false, + "protected_status": false, + "allow_reset": true, + "allow_wps": true, + "allow_reboot": true, + "allow_remote_reboot": true, + "allow_update": true, + "origin": true, + "upgrade_blink": true, + "reboot_blink": true, + "dingz_name": "Wohnzimmer", + "room_name": "Wohnzimmer", + "home_name": "", + "id": "[redacted]", + "temp_offset": 6, + "fet_offset": 3.1666666666666665, + "cpu_offset": 26.3, + "temp_comp": { + "fet_offset": 2.64, + "gain_up": 0.012, + "gain_down": 0.006, + "gain_total": 0.25, + "idle_offset": 0, + "front_offset": 15, + "inf_factor": 0.5 + }, + "sun_offset": 0, + "tzid": 0, + "lat": 46.929, + "long": 7.118, + "dyn_light": { + "enable": true, + "phases": 3, + "source": "sun", + "sun_offset": { + "day": 30, + "twilight": 30, + "night": 30 + } + }, + "wifi_ps": true, + "new_comp_alg": false, + "time": "2025-08-16 22:20:22", + "sunrise": { + "hour": 6, + "minute": 28 + }, + "sunset": { + "hour": 20, + "minute": 43 + }, + "system_status": "OK" + }, + "error": null + }, + "ddi_config": { + "value": { + "repeat": true, + "repeat_interval": 5 + }, + "error": null + }, + "actions_config": { + "value": { + "generic": "", + "btn1": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn3": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn4": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "input": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "input2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "thermostat": { + "idle": "", + "heating": "", + "cooling": "", + "repeat_period": 20000 + }, + "lux": { + "night": "", + "twilight": "", + "day": "", + "repeat_period": 0 + }, + "pir1": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir2": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir3": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + } + }, + "error": null + }, + "scheduler_config": { + "value": [], + "error": null } } \ No newline at end of file diff --git a/tests/snapshots/336a87b7ddcc.json b/tests/snapshots/336a87b7ddcc.json index 7c545c4..6ff13da 100644 --- a/tests/snapshots/336a87b7ddcc.json +++ b/tests/snapshots/336a87b7ddcc.json @@ -2073,7 +2073,7 @@ "room_temperature": 23.5, "uncompensated_temperature": 35.375, "temp_offset": 6, - "cpu_temperature": 35, + "cpu_temperature": 35.56, "puck_temperature": 37, "fet_temperature": 36.7, "input_state": null, @@ -2163,5 +2163,1742 @@ "caps_min_free_heap": 24052 }, "error": null + }, + "button_config": { + "value": { + "dingz_orientation": "1,2,3,4", + "buttons": [ + { + "active": true, + "name": "Licht Mitte", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Licht Aussen West", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Licht S\u00fcd", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": false, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "", + "icon": 1, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": false, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + } + ] + }, + "error": null + }, + "input_config": { + "value": { + "inputs": [ + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + } + ] + }, + "error": null + }, + "pir_config": { + "value": { + "pirs": [ + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": false, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": false, + "default_on": false, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "white", + "brightness": 1 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 600, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 7200, + "manual_off_time": 5 + } + } + ] + }, + "error": null + }, + "lux_config": { + "value": { + "enabled": true, + "output": null, + "ddi_channels": null, + "feedback": false, + "dim_value_night": 100, + "dim_value_twilight": 100, + "dim_value_day": 100, + "ct_value_night": 0, + "ct_value_twilight": 0, + "ct_value_day": 0, + "fade_in_time": 10, + "fade_out_time": 10, + "thresholds": { + "twilight_to_night": 5, + "night_to_twilight": 10, + "day_to_twilight": 15, + "twilight_to_day": 20, + "day_to_night": 5, + "night_to_day": 20 + }, + "light_lpf": true, + "off_period": 900 + }, + "error": null + }, + "output_config": { + "value": { + "outputs": [ + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "halogen_bulb", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Licht Mitte", + "type": "light", + "groups": "ez", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Aussen West", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Licht S\u00fcd", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + } + ] + }, + "error": null + }, + "services_config": { + "value": { + "mystrom": false, + "homekit": false, + "rest_api": true, + "panel": true, + "aws": true, + "discovery": false, + "udp_search": true, + "aws_notifies": false, + "ssdp": false, + "mdns": true, + "mdns_search": true, + "homekit_configured": false, + "cloud_ping": false, + "broadcast_period": 5, + "mdns_search_period": 60, + "mqtt": { + "uri": "[redacted]", + "enable": true, + "server.crt": null + }, + "cloud_paired": false, + "cloud_test_enabled": false + }, + "error": null + }, + "system_config": { + "value": { + "rest_password": false, + "protected_status": false, + "allow_reset": true, + "allow_wps": true, + "allow_reboot": true, + "allow_remote_reboot": true, + "allow_update": true, + "origin": true, + "upgrade_blink": true, + "reboot_blink": false, + "dingz_name": "Bastelraum West", + "room_name": "Bastelraum", + "home_name": "", + "id": "[redacted]", + "temp_offset": 6, + "fet_offset": 3.5, + "cpu_offset": 26.8, + "temp_comp": { + "fet_offset": 2.64, + "gain_up": 0.012, + "gain_down": 0.006, + "gain_total": 0.25, + "idle_offset": 0, + "front_offset": 15, + "inf_factor": 0.5 + }, + "sun_offset": 0, + "tzid": 0, + "lat": 46.929, + "long": 7.118, + "dyn_light": { + "enable": false, + "phases": 3, + "source": "lux", + "sun_offset": { + "day": 30, + "twilight": 30, + "night": 30 + } + }, + "wifi_ps": true, + "new_comp_alg": false, + "time": "2025-08-16 22:20:22", + "sunrise": { + "hour": 6, + "minute": 28 + }, + "sunset": { + "hour": 20, + "minute": 43 + }, + "system_status": "OK" + }, + "error": null + }, + "ddi_config": { + "value": { + "repeat": true, + "repeat_interval": 5 + }, + "error": null + }, + "actions_config": { + "value": { + "generic": "", + "btn1": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn3": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn4": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "input": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "input2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "thermostat": { + "idle": "", + "heating": "", + "cooling": "", + "repeat_period": 20000 + }, + "lux": { + "night": "", + "twilight": "", + "day": "", + "repeat_period": 0 + }, + "pir1": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir2": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir3": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + } + }, + "error": null + }, + "scheduler_config": { + "value": [], + "error": null } } \ No newline at end of file diff --git a/tests/snapshots/4dfaa25d449e.json b/tests/snapshots/4dfaa25d449e.json index cfd2adf..f3f79b9 100644 --- a/tests/snapshots/4dfaa25d449e.json +++ b/tests/snapshots/4dfaa25d449e.json @@ -2080,7 +2080,7 @@ "temp_offset": 6, "cpu_temperature": 49.44, "puck_temperature": 37, - "fet_temperature": 39, + "fet_temperature": 40.9, "input_state": false, "pirs": [ { @@ -2168,5 +2168,1742 @@ "caps_min_free_heap": 9172 }, "error": null + }, + "button_config": { + "value": { + "dingz_orientation": "1,2,3,4", + "buttons": [ + { + "active": true, + "name": "Gang OG Licht", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 75 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 1 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Rolladen Dachfenster Auf", + "icon": 8, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "green", + "brightness": 1 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Gang EG Licht", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": false, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "blue", + "brightness": 1 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Rolladen Dachfenster Zu", + "icon": 9, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": false, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "red", + "brightness": 1 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + } + ] + }, + "error": null + }, + "input_config": { + "value": { + "inputs": [ + { + "active": true, + "name": "", + "icon": 17, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 75 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 1 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + } + ] + }, + "error": null + }, + "pir_config": { + "value": { + "pirs": [ + { + "active": true, + "name": "Bewegung Gang OG", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "white", + "brightness": 1 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 60, + "manual_on_time": 600, + "manual_off_time": 60 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 300, + "manual_off_time": 300 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 7200, + "manual_off_time": 5 + } + } + ] + }, + "error": null + }, + "lux_config": { + "value": { + "enabled": true, + "output": null, + "ddi_channels": null, + "feedback": false, + "dim_value_night": 100, + "dim_value_twilight": 100, + "dim_value_day": 100, + "ct_value_night": 0, + "ct_value_twilight": 0, + "ct_value_day": 0, + "fade_in_time": 0, + "fade_out_time": 10, + "thresholds": { + "twilight_to_night": 4, + "night_to_twilight": 5, + "day_to_twilight": 10, + "twilight_to_day": 13, + "day_to_night": 10, + "night_to_day": 13 + }, + "light_lpf": true, + "off_period": 900 + }, + "error": null + }, + "output_config": { + "value": { + "outputs": [ + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 1 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Gang OG Licht", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 1 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 30, + "max": 100 + }, + "dynamic": { + "day": 0, + "twilight": 36, + "night": 32 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 1 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + } + ] + }, + "error": null + }, + "services_config": { + "value": { + "mystrom": false, + "homekit": false, + "rest_api": true, + "panel": true, + "aws": true, + "discovery": false, + "udp_search": true, + "aws_notifies": false, + "ssdp": false, + "mdns": true, + "mdns_search": true, + "homekit_configured": false, + "cloud_ping": false, + "broadcast_period": 5, + "mdns_search_period": 60, + "mqtt": { + "uri": "[redacted]", + "enable": true, + "server.crt": null + }, + "cloud_paired": false, + "cloud_test_enabled": false + }, + "error": null + }, + "system_config": { + "value": { + "rest_password": false, + "protected_status": false, + "allow_reset": true, + "allow_wps": true, + "allow_reboot": true, + "allow_remote_reboot": true, + "allow_update": true, + "origin": true, + "upgrade_blink": true, + "reboot_blink": false, + "dingz_name": "Treppenhaus dingz", + "room_name": "Treppenhaus", + "home_name": "BG12", + "id": "[redacted]", + "temp_offset": 6, + "fet_offset": 0, + "cpu_offset": 25.2, + "temp_comp": { + "fet_offset": 2.64, + "gain_up": 0.012, + "gain_down": 0.006, + "gain_total": 0.25, + "idle_offset": 0, + "front_offset": 15, + "inf_factor": 0.5 + }, + "sun_offset": 0, + "tzid": 0, + "lat": 46.929, + "long": 7.118, + "dyn_light": { + "enable": true, + "phases": 3, + "source": "lux", + "sun_offset": { + "day": 30, + "twilight": 30, + "night": 30 + } + }, + "wifi_ps": true, + "new_comp_alg": false, + "time": "2025-08-16 22:20:22", + "sunrise": { + "hour": 6, + "minute": 28 + }, + "sunset": { + "hour": 20, + "minute": 43 + }, + "system_status": "OK" + }, + "error": null + }, + "ddi_config": { + "value": { + "repeat": true, + "repeat_interval": 5 + }, + "error": null + }, + "actions_config": { + "value": { + "generic": "", + "btn1": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 3000, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn3": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn4": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 3000, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "input": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "input2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "thermostat": { + "idle": "", + "heating": "", + "cooling": "", + "repeat_period": 60000 + }, + "lux": { + "night": "", + "twilight": "", + "day": "", + "repeat_period": 0 + }, + "pir1": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir2": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir3": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + } + }, + "error": null + }, + "scheduler_config": { + "value": [], + "error": null } } \ No newline at end of file diff --git a/tests/snapshots/687e682a7db1.json b/tests/snapshots/687e682a7db1.json index b321731..cf57bbf 100644 --- a/tests/snapshots/687e682a7db1.json +++ b/tests/snapshots/687e682a7db1.json @@ -2209,5 +2209,1785 @@ "caps_min_free_heap": 11616 }, "error": null + }, + "button_config": { + "value": { + "dingz_orientation": "1,2,3,4", + "buttons": [ + { + "active": true, + "name": "Licht Mitte", + "icon": 1, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": true, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "e", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Licht Tisch", + "icon": 1, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": true, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": true, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Licht Nord", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + } + ] + }, + "error": null + }, + "input_config": { + "value": { + "inputs": [ + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_toggle", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + } + ] + }, + "error": null + }, + "pir_config": { + "value": { + "pirs": [ + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": false, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": true, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "e", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "white", + "brightness": 1 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 600, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 7200, + "manual_off_time": 5 + } + } + ] + }, + "error": null + }, + "lux_config": { + "value": { + "enabled": true, + "output": null, + "ddi_channels": null, + "feedback": false, + "dim_value_night": 100, + "dim_value_twilight": 100, + "dim_value_day": 100, + "ct_value_night": 0, + "ct_value_twilight": 0, + "ct_value_day": 0, + "fade_in_time": 10, + "fade_out_time": 10, + "thresholds": { + "twilight_to_night": 5, + "night_to_twilight": 10, + "day_to_twilight": 15, + "twilight_to_day": 20, + "day_to_night": 5, + "night_to_day": 20 + }, + "light_lpf": true, + "off_period": 900 + }, + "error": null + }, + "output_config": { + "value": { + "outputs": [ + { + "active": false, + "name": "Licht Mitte", + "type": "light", + "groups": "ez", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Licht Nord", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "halogen_bulb", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "halogen_bulb", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + } + ] + }, + "error": null + }, + "services_config": { + "value": { + "mystrom": false, + "homekit": false, + "rest_api": true, + "panel": true, + "aws": true, + "discovery": false, + "udp_search": true, + "aws_notifies": false, + "ssdp": false, + "mdns": true, + "mdns_search": true, + "homekit_configured": false, + "cloud_ping": false, + "broadcast_period": 5, + "mdns_search_period": 60, + "mqtt": { + "uri": "[redacted]", + "enable": true, + "server.crt": null + }, + "cloud_paired": false, + "cloud_test_enabled": false + }, + "error": null + }, + "system_config": { + "value": { + "rest_password": false, + "protected_status": false, + "allow_reset": true, + "allow_wps": true, + "allow_reboot": true, + "allow_remote_reboot": true, + "allow_update": true, + "origin": true, + "upgrade_blink": true, + "reboot_blink": true, + "dingz_name": "Bastelraum Ost", + "room_name": "Bastelraum", + "home_name": "", + "id": "[redacted]", + "temp_offset": 6, + "fet_offset": 3.5, + "cpu_offset": 26.9, + "temp_comp": { + "fet_offset": 2.64, + "gain_up": 0.012, + "gain_down": 0.006, + "gain_total": 0.25, + "idle_offset": 0, + "front_offset": 15, + "inf_factor": 0.5 + }, + "sun_offset": 0, + "tzid": 0, + "lat": 46.929, + "long": 7.118, + "dyn_light": { + "enable": false, + "phases": 3, + "source": "lux", + "sun_offset": { + "day": 30, + "twilight": 30, + "night": 30 + } + }, + "wifi_ps": true, + "new_comp_alg": false, + "time": "2025-08-16 22:20:22", + "sunrise": { + "hour": 6, + "minute": 28 + }, + "sunset": { + "hour": 20, + "minute": 43 + }, + "system_status": "OK" + }, + "error": null + }, + "ddi_config": { + "value": { + "repeat": true, + "repeat_interval": 5 + }, + "error": null + }, + "actions_config": { + "value": { + "generic": "", + "btn1": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn3": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn4": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "input": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "input2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "thermostat": { + "idle": "", + "heating": "", + "cooling": "", + "repeat_period": 20000 + }, + "lux": { + "night": "", + "twilight": "", + "day": "", + "repeat_period": 0 + }, + "pir1": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir2": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir3": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + } + }, + "error": null + }, + "scheduler_config": { + "value": [ + { + "id": 1, + "name": "test", + "en": false, + "type": "time", + "hour": 0, + "min": 0, + "offset": 0, + "rand": 0, + "days": "", + "url": "", + "bc_events": { + "remote_type": { + "light": false, + "motor": false + }, + "lights_config": { + "fade_in_time": 0, + "fade_out_time": 0, + "groups": "", + "custom_value": 100, + "actions": { + "off": false, + "default_on": true, + "custom_on": false + } + }, + "motors_config": { + "groups": "", + "shade_position": { + "blind": 100, + "lamella": 100 + }, + "actions": { + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + } + } + } + } + ], + "error": null } } \ No newline at end of file diff --git a/tests/snapshots/a1cbf24095e8.json b/tests/snapshots/a1cbf24095e8.json index 26ebce8..c8c1dbe 100644 --- a/tests/snapshots/a1cbf24095e8.json +++ b/tests/snapshots/a1cbf24095e8.json @@ -2076,7 +2076,7 @@ "room_temperature": 23.5, "uncompensated_temperature": 34.3125, "temp_offset": 7.5, - "cpu_temperature": 50, + "cpu_temperature": 50.56, "puck_temperature": 37, "fet_temperature": 38.1, "input_state": false, @@ -2160,5 +2160,1742 @@ "caps_min_free_heap": 10584 }, "error": null + }, + "button_config": { + "value": { + "dingz_orientation": "1,2,3,4", + "buttons": [ + { + "active": true, + "name": "Gedimmt", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 2 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Licht", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "St\u00e4nderlampe", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": false, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Vitrine", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": false, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + } + ] + }, + "error": null + }, + "input_config": { + "value": { + "inputs": [ + { + "active": true, + "name": "Stuebli Licht Eingang", + "icon": 17, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": true, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "white", + "brightness": 50 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "contact_state", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + } + ] + }, + "error": null + }, + "pir_config": { + "value": { + "pirs": [ + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 7200, + "manual_off_time": 5 + } + } + ] + }, + "error": null + }, + "lux_config": { + "value": { + "enabled": true, + "output": null, + "ddi_channels": null, + "feedback": false, + "dim_value_night": 100, + "dim_value_twilight": 100, + "dim_value_day": 100, + "ct_value_night": 0, + "ct_value_twilight": 0, + "ct_value_day": 0, + "fade_in_time": 10, + "fade_out_time": 10, + "thresholds": { + "twilight_to_night": 10, + "night_to_twilight": 30, + "day_to_twilight": 50, + "twilight_to_day": 100, + "day_to_night": 50, + "night_to_day": 100 + }, + "light_lpf": true, + "off_period": 900 + }, + "error": null + }, + "output_config": { + "value": { + "outputs": [ + { + "active": false, + "name": "Eingang", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "led_bulb", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Licht", + "type": "light", + "groups": "bz", + "feedback": { + "color": "none", + "brightness": 10 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "led_driver", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 40, + "night": 2 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Staenderlampe", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Vitrine", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 3, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + } + ] + }, + "error": null + }, + "services_config": { + "value": { + "mystrom": false, + "homekit": false, + "rest_api": true, + "panel": true, + "aws": true, + "discovery": false, + "udp_search": true, + "aws_notifies": false, + "ssdp": false, + "mdns": true, + "mdns_search": true, + "homekit_configured": false, + "cloud_ping": false, + "broadcast_period": 5, + "mdns_search_period": 60, + "mqtt": { + "uri": "[redacted]", + "enable": true, + "server.crt": null + }, + "cloud_paired": false, + "cloud_test_enabled": false + }, + "error": null + }, + "system_config": { + "value": { + "rest_password": false, + "protected_status": false, + "allow_reset": true, + "allow_wps": true, + "allow_reboot": true, + "allow_remote_reboot": true, + "allow_update": true, + "origin": true, + "upgrade_blink": true, + "reboot_blink": true, + "dingz_name": "Stuebli dingz", + "room_name": "Stuebli", + "home_name": "BG12", + "id": "[redacted]", + "temp_offset": 7.5, + "fet_offset": 1, + "cpu_offset": 25.2, + "temp_comp": { + "fet_offset": 2.64, + "gain_up": 0.012, + "gain_down": 0.006, + "gain_total": 0.25, + "idle_offset": 0, + "front_offset": 15, + "inf_factor": 0.5 + }, + "sun_offset": 0, + "tzid": 0, + "lat": 46.929, + "long": 7.118, + "dyn_light": { + "enable": true, + "phases": 3, + "source": "sun", + "sun_offset": { + "day": 30, + "twilight": 30, + "night": 30 + } + }, + "wifi_ps": true, + "new_comp_alg": false, + "time": "2025-08-16 22:20:22", + "sunrise": { + "hour": 6, + "minute": 28 + }, + "sunset": { + "hour": 20, + "minute": 43 + }, + "system_status": "OK" + }, + "error": null + }, + "ddi_config": { + "value": { + "repeat": true, + "repeat_interval": 5 + }, + "error": null + }, + "actions_config": { + "value": { + "generic": "", + "btn1": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn3": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn4": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "input": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "input2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "thermostat": { + "idle": "", + "heating": "", + "cooling": "", + "repeat_period": 60000 + }, + "lux": { + "night": "", + "twilight": "", + "day": "", + "repeat_period": 0 + }, + "pir1": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir2": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir3": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + } + }, + "error": null + }, + "scheduler_config": { + "value": [], + "error": null } } \ No newline at end of file diff --git a/tests/snapshots/b6dbe5948d2f.json b/tests/snapshots/b6dbe5948d2f.json index e2fd257..f0f96b4 100644 --- a/tests/snapshots/b6dbe5948d2f.json +++ b/tests/snapshots/b6dbe5948d2f.json @@ -17,7 +17,7 @@ "bl_version_puck": "1.0.0", "hw_version_puck": "1.1.1", "hw_id_puck": 1, - "puck_sn": "[redacted]", + "puck_sn": "", "puck_production_date": { "year": 20, "month": 1, @@ -2164,5 +2164,1740 @@ "caps_min_free_heap": 12344 }, "error": null + }, + "button_config": { + "value": { + "dingz_orientation": "1,2,3,4", + "buttons": [ + { + "active": true, + "name": "Wohnzimmer K\u00fcche", + "icon": 1, + "mode": { + "local": false, + "remote": true + }, + "local_type": { + "light": false, + "motor": false + }, + "type": { + "light": true, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "a", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Abwaschen", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "Essen", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": false, + "close": true, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + }, + { + "active": true, + "name": "K\u00fcche Mitte", + "icon": 1, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": false + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": false, + "custom_on": true, + "open": true, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": true, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": true, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + } + } + ] + }, + "error": null + }, + "input_config": { + "value": { + "inputs": [ + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_toggle", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 0, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "button": { + "remote_push": false, + "therm_ctrl": false + }, + "input": { + "type": "button_push", + "invert": false, + "contact_free_cooling": { + "repeat_period": 60000 + } + } + } + ] + }, + "error": null + }, + "pir_config": { + "value": { + "pirs": [ + { + "active": true, + "name": "Bewegung K\u00fcche", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 20 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 300, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": true, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 10, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 600, + "manual_off_time": 600 + } + }, + { + "active": false, + "name": "", + "icon": 0, + "mode": { + "local": true, + "remote": false + }, + "local_type": { + "light": true, + "motor": true + }, + "type": { + "light": false, + "motor": false + }, + "actions": { + "off": true, + "default_on": true, + "custom_on": false, + "open": false, + "close": false, + "default_pos": false, + "custom_pos": false + }, + "ddi_actions": { + "brightness": true, + "colour_temperature": false + }, + "outputs": { + "fade_in_time": 10, + "fade_out_time": 0, + "auto_off_delay": 0, + "local": [ + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + }, + { + "controlled": false, + "custom": { + "value": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "value": 100, + "ct_value": 100 + } + }, + "ddi": { + "controlled": { + "active": false, + "channel_id": 0 + }, + "custom": { + "brightness": 100, + "colour_temperature": 100 + } + } + }, + "motors": { + "invert": false, + "local": [ + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + }, + { + "controlled": false, + "custom": { + "blind": 100, + "lamella": 100 + } + } + ], + "remote": { + "groups": "", + "custom": { + "blind": 100, + "lamella": 100 + } + } + }, + "feedback": { + "color": "none", + "brightness": 100 + }, + "carousel": false, + "pir": { + "backoff_time": 10, + "on_time": 180, + "manual_on_time": 7200, + "manual_off_time": 5 + } + } + ] + }, + "error": null + }, + "lux_config": { + "value": { + "enabled": true, + "output": null, + "ddi_channels": null, + "feedback": false, + "dim_value_night": 100, + "dim_value_twilight": 100, + "dim_value_day": 100, + "ct_value_night": 0, + "ct_value_twilight": 0, + "ct_value_day": 0, + "fade_in_time": 10, + "fade_out_time": 10, + "thresholds": { + "twilight_to_night": 50, + "night_to_twilight": 100, + "day_to_twilight": 150, + "twilight_to_day": 200, + "day_to_night": 50, + "night_to_day": 200 + }, + "light_lpf": true, + "off_period": 900 + }, + "error": null + }, + "output_config": { + "value": { + "outputs": [ + { + "active": true, + "name": "Essen", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": true, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": true, + "twilight": true, + "night": true + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "Abwaschen", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": false, + "twilight": false, + "night": false + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": true, + "name": "K\u00fcche Mitte", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 70, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": false, + "twilight": false, + "night": false + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + }, + { + "active": false, + "name": "", + "type": "light", + "groups": "z", + "feedback": { + "color": "none", + "brightness": 100 + }, + "light": { + "dimmable": false, + "auto_off_delay": 0, + "dimmer": { + "type": "linear", + "use_last_value": false, + "range": { + "min": 1, + "max": 100 + }, + "dynamic": { + "day": 100, + "twilight": 100, + "night": 100 + } + }, + "onoff": { + "group_on": { + "day": false, + "twilight": false, + "night": false + } + } + }, + "heater": { + "type": "nc", + "function": "heating" + }, + "pulse": { + "type": "positive", + "length": { + "min": 0.2, + "max": 0 + } + }, + "fan": { + "delay": { + "pre": 180, + "post": 5 + }, + "ventilation": { + "from": { + "hour": 7, + "minute": 0 + }, + "to": { + "hour": 21, + "minute": 0 + }, + "force_in_24": 0 + }, + "react": { + "pir_during_slot": false, + "btn_no_delay": false + }, + "active": true + }, + "garage_door": { + "opening_travel_time": 12, + "close_timeout": 60, + "pulse_time": 1 + }, + "valve": { + "duration": 60 + } + } + ] + }, + "error": null + }, + "services_config": { + "value": { + "mystrom": false, + "homekit": false, + "rest_api": true, + "panel": true, + "aws": true, + "discovery": false, + "udp_search": true, + "aws_notifies": false, + "ssdp": false, + "mdns": true, + "mdns_search": true, + "homekit_configured": false, + "cloud_ping": false, + "broadcast_period": 5, + "mdns_search_period": 60, + "mqtt": { + "uri": "[redacted]", + "enable": true, + "server.crt": null + }, + "cloud_paired": false, + "cloud_test_enabled": false + }, + "error": null + }, + "system_config": { + "value": { + "rest_password": false, + "protected_status": false, + "allow_reset": true, + "allow_wps": true, + "allow_reboot": true, + "allow_remote_reboot": true, + "allow_update": true, + "origin": true, + "upgrade_blink": true, + "reboot_blink": true, + "dingz_name": "K\u00fcche", + "room_name": "K\u00fcche", + "home_name": "", + "id": "[redacted]", + "temp_offset": 6, + "temp_comp": { + "fet_offset": 2.64, + "gain_up": 0.012, + "gain_down": 0.006, + "gain_total": 0.25, + "idle_offset": 0, + "front_offset": 15, + "inf_factor": 0.5 + }, + "sun_offset": 0, + "tzid": 0, + "lat": 46.929, + "long": 7.118, + "dyn_light": { + "enable": true, + "phases": 3, + "source": "lux", + "sun_offset": { + "day": 30, + "twilight": 30, + "night": 30 + } + }, + "wifi_ps": true, + "new_comp_alg": false, + "time": "2025-08-16 22:20:22", + "sunrise": { + "hour": 6, + "minute": 28 + }, + "sunset": { + "hour": 20, + "minute": 43 + }, + "system_status": "OK" + }, + "error": null + }, + "ddi_config": { + "value": { + "repeat": true, + "repeat_interval": 5 + }, + "error": null + }, + "actions_config": { + "value": { + "generic": "", + "btn1": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn3": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "btn4": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true + } + }, + "input": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "input2": { + "single": "", + "double": "", + "long": "", + "m3": "", + "m4": "", + "m5": "", + "begin": "", + "hold_up": "", + "hold_down": "", + "end": "", + "off": "", + "active": "", + "inactive": "", + "active_repeat_period": 0, + "inactive_repeat_period": 0, + "hold_up_repeat_period": 500, + "hold_down_repeat_period": 500, + "feedback": { + "single": true, + "double": true, + "long": true, + "m3": true, + "m4": true, + "m5": true, + "begin": true, + "hold_up": true, + "hold_down": true, + "end": true, + "off": true, + "active": false, + "inactive": false + } + }, + "thermostat": { + "idle": "", + "heating": "", + "cooling": "", + "repeat_period": 20000 + }, + "lux": { + "night": "", + "twilight": "", + "day": "", + "repeat_period": 0 + }, + "pir1": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir2": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + }, + "pir3": { + "night": "", + "twilight": "", + "day": "", + "rise": "", + "fall": "", + "timer_off": "", + "motion_repeat_period": 0, + "feedback": { + "night": true, + "twilight": true, + "day": true, + "rise": true, + "fall": true, + "timer_off": false + } + } + }, + "error": null + }, + "scheduler_config": { + "value": [], + "error": null } } \ No newline at end of file diff --git a/tests/test_rest_types.py b/tests/test_rest_types.py index 80cf069..061b879 100644 --- a/tests/test_rest_types.py +++ b/tests/test_rest_types.py @@ -7,7 +7,24 @@ from pydantic import TypeAdapter -from dingz.rest import ConfigDump, Device, NetworkInfo, Ram, RestClient, State +from dingz.rest import ( + ActionsConfig, + ButtonsConfig, + ConfigDump, + DdiConfig, + Device, + InputsConfig, + LuxConfig, + NetworkInfo, + OutputsConfig, + PirsConfig, + Ram, + RestClient, + SchedulerConfig, + ServicesConfig, + State, + SystemConfig, +) def _validate_strict(ty: Any, value: Any) -> None: @@ -15,7 +32,7 @@ def _validate_strict(ty: Any, value: Any) -> None: adapter.validate_python(value) -async def test_device_type(rest_client_with_snapshot: RestClient) -> None: +async def test_device(rest_client_with_snapshot: RestClient) -> None: device = await rest_client_with_snapshot.get_device() _validate_strict(Device, device) @@ -38,3 +55,53 @@ async def test_state(rest_client_with_snapshot: RestClient) -> None: async def test_ram(rest_client_with_snapshot: RestClient) -> None: ram = await rest_client_with_snapshot.get_ram() _validate_strict(Ram, ram) + + +async def test_button_config(rest_client_with_snapshot: RestClient) -> None: + button_config = await rest_client_with_snapshot.get_button_config() + _validate_strict(ButtonsConfig, button_config) + + +async def test_input_config(rest_client_with_snapshot: RestClient) -> None: + input_config = await rest_client_with_snapshot.get_input_config() + _validate_strict(InputsConfig, input_config) + + +async def test_pir_config(rest_client_with_snapshot: RestClient) -> None: + pir_config = await rest_client_with_snapshot.get_pir_config() + _validate_strict(PirsConfig, pir_config) + + +async def test_lux_config(rest_client_with_snapshot: RestClient) -> None: + lux_config = await rest_client_with_snapshot.get_lux_config() + _validate_strict(LuxConfig, lux_config) + + +async def test_output_config(rest_client_with_snapshot: RestClient) -> None: + output_config = await rest_client_with_snapshot.get_output_config() + _validate_strict(OutputsConfig, output_config) + + +async def test_services_config(rest_client_with_snapshot: RestClient) -> None: + services_config = await rest_client_with_snapshot.get_services_config() + _validate_strict(ServicesConfig, services_config) + + +async def test_system_config(rest_client_with_snapshot: RestClient) -> None: + system_config = await rest_client_with_snapshot.get_system_config() + _validate_strict(SystemConfig, system_config) + + +async def test_ddi_config(rest_client_with_snapshot: RestClient) -> None: + ddi_config = await rest_client_with_snapshot.get_ddi_config() + _validate_strict(DdiConfig, ddi_config) + + +async def test_actions_config(rest_client_with_snapshot: RestClient) -> None: + actions_config = await rest_client_with_snapshot.get_actions_config() + _validate_strict(ActionsConfig, actions_config) + + +async def test_scheduler_config(rest_client_with_snapshot: RestClient) -> None: + scheduler_config = await rest_client_with_snapshot.get_scheduler_config() + _validate_strict(list[SchedulerConfig], scheduler_config)