pax_global_header00006660000000000000000000000064150174052340014513gustar00rootroot0000000000000052 comment=a0746ca996a194bc75a2c4dbed7f4d8b0218528e pyatmo-9.2.1/000077500000000000000000000000001501740523400130355ustar00rootroot00000000000000pyatmo-9.2.1/.devcontainer/000077500000000000000000000000001501740523400155745ustar00rootroot00000000000000pyatmo-9.2.1/.devcontainer/Dockerfile.dev000066400000000000000000000012211501740523400203370ustar00rootroot00000000000000ARG VARIANT="3.11" FROM mcr.microsoft.com/vscode/devcontainers/python:0-${VARIANT} SHELL ["/bin/bash", "-o", "pipefail", "-c"] WORKDIR /workspaces # Install Python dependencies from requirements RUN pip3 install --upgrade pip \ && pip3 install uv \ && pip3 install pdbpp \ && pip3 install pre-commit \ && pip3 install time-machine \ && pip3 install pytest-cov \ && pip3 install anyio # Remove any old pytest versions that might conflict RUN python3 -m pip install --upgrade --force-reinstall pytest \ && rm -rf /usr/local/py-utils/venvs/pytest/bin/pytest # Set the default shell to bash instead of sh ENV SHELL="/bin/bash" pyatmo-9.2.1/.devcontainer/devcontainer.json000066400000000000000000000025351501740523400211550ustar00rootroot00000000000000{ "name": "pyatmo Dev", "context": ".", "dockerFile": "./Dockerfile.dev", "containerEnv": { "DEVCONTAINER": "1" }, "postCreateCommand": "pip3 install -e . && pre-commit run ruff", "runArgs": [ "-e", "GIT_EDITOR=code --wait" ], "customizations": { "vscode": { "extensions": [ "ms-python.vscode-pylance", "visualstudioexptteam.vscodeintellicode" ] }, "settings": { "python.pythonPath": "/usr/local/bin/python", "python.defaultInterpreterPath": "/user/local/bin/python", "python.linting.pylintEnabled": true, "python.linting.enabled": true, "python.formatting.provider": "black", "python.testing.pytestArgs": [ "--no-cov" ], "python.testing.unittestEnabled": false, "python.testing.pytestEnabled": true, "editor.formatOnPaste": false, "editor.formatOnSave": true, "editor.formatOnType": true, "files.trimTrailingWhitespace": true, "terminal.integrated.profiles.linux": { "zsh": { "path": "/usr/bin/zsh" } }, "terminal.integrated.defaultProfile.linux": "zsh" } } } pyatmo-9.2.1/.github/000077500000000000000000000000001501740523400143755ustar00rootroot00000000000000pyatmo-9.2.1/.github/dependabot.yml000066400000000000000000000013161501740523400172260ustar00rootroot00000000000000# To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates version: 2 updates: - package-ecosystem: "github-actions" directory: "/" schedule: # Check for updates to GitHub Actions every weekday interval: "daily" - package-ecosystem: "uv" # See documentation for possible values directory: "/" # Location of package manifests schedule: interval: "weekly" # Check for pip updates on Sundays day: "sunday" pyatmo-9.2.1/.github/workflows/000077500000000000000000000000001501740523400164325ustar00rootroot00000000000000pyatmo-9.2.1/.github/workflows/publish-to-pypi.yml000066400000000000000000000014521501740523400222240ustar00rootroot00000000000000name: Publish 📦 to PyPI on: push: tags: - "v*" permissions: contents: read jobs: build-n-publish: name: Build and publish 📦 to PyPI runs-on: ubuntu-latest permissions: contents: write steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Python 3.11 uses: actions/setup-python@v5.6.0 with: python-version: 3.11.4 - name: Install dependencies run: | python -m pip install --upgrade pip pip install build - name: Build a binary wheel and a source tarball run: >- python -m build . - name: Publish 📦 to PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: password: ${{ secrets.pypi_prod_token }} pyatmo-9.2.1/.github/workflows/publish-to-test-pypi.yml000066400000000000000000000016131501740523400232000ustar00rootroot00000000000000name: Publish 📦 to TestPyPI on: push: branches: - development jobs: build-n-publish: name: Build and publish 📦 to TestPyPI runs-on: ubuntu-latest permissions: contents: read packages: write steps: - uses: actions/checkout@v4 with: ref: development fetch-depth: 0 - name: Set up Python 3.11 uses: actions/setup-python@v5.6.0 with: python-version: 3.11.4 - name: Install dependencies run: | python -m pip install --upgrade pip pip install build - name: Build a binary wheel and a source tarball run: >- python -m build . - name: Publish 📦 to Test PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: password: ${{ secrets.PYPI_TEST_TOKEN }} repository-url: https://test.pypi.org/legacy/ pyatmo-9.2.1/.github/workflows/pythonpackage.yml000066400000000000000000000043461501740523400220210ustar00rootroot00000000000000name: Python package on: push: branches: - '*' pull_request: branches: - master - development permissions: contents: read jobs: black: runs-on: ubuntu-latest strategy: max-parallel: 1 matrix: python-version: [3.11.4] steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5.6.0 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip pip install black - name: Check with black run: | black --check --diff src/pyatmo/ tests/ linter: runs-on: ubuntu-latest strategy: max-parallel: 4 matrix: python-version: [3.11.4] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5.6.0 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip pip install ruff - name: Lint with ruff run: | ruff check src/pyatmo tests/ typechecker: runs-on: ubuntu-latest strategy: max-parallel: 1 matrix: python-version: [3.11.4] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5.6.0 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip tox-gh-actions - name: Typecheck with mypy run: | tox -e mypy build: runs-on: ubuntu-latest strategy: max-parallel: 4 matrix: python-version: [3.11.4, 3.12.5] steps: - uses: actions/checkout@v4 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5.6.0 with: python-version: ${{ matrix.python-version }} - name: Run tests with tox run: | pip install tox tox-gh-actions tox -e py311,py312 pyatmo-9.2.1/.github/workflows/release_gh.yml000066400000000000000000000025441501740523400212600ustar00rootroot00000000000000# This is a basic workflow to help you get started with Actions name: Create Github Release # Controls when the action will run. Triggers the workflow on push or pull request # events but only for the development branch on: push: # Sequence of patterns matched against refs/tags tags: - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: # This workflow contains a single job called "build" build: # The type of runner that the job will run on runs-on: ubuntu-latest permissions: contents: write # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - uses: actions/checkout@v4 with: fetch-depth: 0 # Runs a single command using the runners shell - name: Create a Release uses: actions/create-release@v1.1.4 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: # The name of the tag. This should come from the webhook payload, `github.GITHUB_REF` when a user pushes a new tag tag_name: ${{ github.ref }} # The name of the release. For example, `Release v1.0.1` release_name: Release ${{ github.ref }} pyatmo-9.2.1/.gitignore000066400000000000000000000131441501740523400150300ustar00rootroot00000000000000 build/ dist/ **/pyatmo.egg-info/ *.pyc .DS_Store access.token cov.xml venv/ .venv # Created by https://www.gitignore.io/api/python,pycharm # Edit at https://www.gitignore.io/?templates=python,pycharm ### PyCharm ### # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # User-specific stuff .idea/**/workspace.xml .idea/**/tasks.xml .idea/**/usage.statistics.xml .idea/**/dictionaries .idea/**/shelf # Generated files .idea/**/contentModel.xml # Sensitive or high-churn files .idea/**/dataSources/ .idea/**/dataSources.ids .idea/**/dataSources.local.xml .idea/**/sqlDataSources.xml .idea/**/dynamic.xml .idea/**/uiDesigner.xml .idea/**/dbnavigator.xml # Gradle .idea/**/gradle.xml .idea/**/libraries # Gradle and Maven with auto-import # When using Gradle or Maven with auto-import, you should exclude module files, # since they will be recreated, and may cause churn. Uncomment if using # auto-import. # .idea/modules.xml # .idea/*.iml # .idea/modules # *.iml # *.ipr # CMake cmake-build-*/ # Mongo Explorer plugin .idea/**/mongoSettings.xml # File-based project format *.iws # IntelliJ out/ # mpeltonen/sbt-idea plugin .idea_modules/ # JIRA plugin atlassian-ide-plugin.xml # Cursive Clojure plugin .idea/replstate.xml # Crashlytics plugin (for Android Studio and IntelliJ) com_crashlytics_export_strings.xml crashlytics.properties crashlytics-build.properties fabric.properties # Editor-based Rest Client .idea/httpRequests # Android studio 3.1+ serialized cache file .idea/caches/build_file_checksums.ser ### PyCharm Patch ### # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 # *.iml # modules.xml # .idea/misc.xml # *.ipr # Sonarlint plugin .idea/**/sonarlint/ # SonarQube Plugin .idea/**/sonarIssues.xml # Markdown Navigator plugin .idea/**/markdown-navigator.xml .idea/**/markdown-navigator/ ### Python ### # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ pip-wheel-metadata/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover .hypothesis/ .pytest_cache/ # Translations *.mo *.pot # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # pyenv .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. # However, in case of collaboration, if having platform-specific dependencies or dependencies # having no cross-platform support, pipenv may install dependencies that don't work, or not # install all needed dependencies. Pipfile.lock # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # Mr Developer .mr.developer.cfg .project .pydevproject # mkdocs documentation /site # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ # End of https://www.gitignore.io/api/python,pycharm # Created by https://www.gitignore.io/api/code # Edit at https://www.gitignore.io/?templates=code ### Code ### .vscode/* # End of https://www.gitignore.io/api/code # Created by https://www.gitignore.io/api/jetbrains # Edit at https://www.gitignore.io/?templates=jetbrains ### JetBrains ### # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 # User-specific stuff .idea/**/workspace.xml .idea/**/tasks.xml .idea/**/usage.statistics.xml .idea/**/dictionaries .idea/**/shelf # Generated files .idea/**/contentModel.xml # Sensitive or high-churn files .idea/**/dataSources/ .idea/**/dataSources.ids .idea/**/dataSources.local.xml .idea/**/sqlDataSources.xml .idea/**/dynamic.xml .idea/**/uiDesigner.xml .idea/**/dbnavigator.xml # Gradle .idea/**/gradle.xml .idea/**/libraries # Gradle and Maven with auto-import # When using Gradle or Maven with auto-import, you should exclude module files, # since they will be recreated, and may cause churn. Uncomment if using # auto-import. # .idea/modules.xml # .idea/*.iml # .idea/modules # *.iml # *.ipr # CMake cmake-build-*/ # Mongo Explorer plugin .idea/**/mongoSettings.xml # File-based project format *.iws # IntelliJ out/ # mpeltonen/sbt-idea plugin .idea_modules/ # JIRA plugin atlassian-ide-plugin.xml # Cursive Clojure plugin .idea/replstate.xml # Crashlytics plugin (for Android Studio and IntelliJ) com_crashlytics_export_strings.xml crashlytics.properties crashlytics-build.properties fabric.properties # Editor-based Rest Client .idea/httpRequests # Android studio 3.1+ serialized cache file .idea/caches/build_file_checksums.ser ### JetBrains Patch ### # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 # *.iml # modules.xml # .idea/misc.xml # *.ipr # Sonarlint plugin .idea/**/sonarlint/ # SonarQube Plugin .idea/**/sonarIssues.xml # Markdown Navigator plugin .idea/**/markdown-navigator.xml .idea/**/markdown-navigator/ # End of https://www.gitignore.io/api/jetbrains .idea __version__.py pyatmo-9.2.1/.pre-commit-config.yaml000066400000000000000000000023611501740523400173200ustar00rootroot00000000000000# Note: don't use this config for your own repositories. Instead, see # "Version control integration" in README.md. default_stages: [pre-commit, pre-push] exclude: ^(fixtures/) repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.11.9 hooks: - id: ruff args: - --fix - repo: https://github.com/psf/black rev: 25.1.0 hooks: - id: black language_version: python3 - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 # Use the ref you want to point at hooks: - id: check-ast - id: no-commit-to-branch args: [--branch, master, --branch, devel] - id: forbid-new-submodules - id: check-merge-conflict - id: detect-private-key - id: end-of-file-fixer - id: mixed-line-ending args: [--fix=lf] - id: trailing-whitespace - id: debug-statements - id: check-toml - id: pretty-format-json args: [--autofix] exclude: ^(\.devcontainer|\.vscode)/ # on commit-msg, it needs 'pre-commit install -t commit-msg'* - repo: https://github.com/compilerla/conventional-pre-commit rev: v4.2.0 hooks: - id: conventional-pre-commit stages: [commit-msg] args: [] pyatmo-9.2.1/.tool-versions000066400000000000000000000000161501740523400156560ustar00rootroot00000000000000python 3.11.4 pyatmo-9.2.1/.vscode/000077500000000000000000000000001501740523400143765ustar00rootroot00000000000000pyatmo-9.2.1/.vscode/tasks.json000066400000000000000000000037431501740523400164250ustar00rootroot00000000000000{ "version": "2.0.0", "tasks": [ { "label": "Pytest", "detail": "Run test suite with pytest", "type": "shell", "command": "pytest tests", "dependsOn": [ "Install all Test Requirements" ], "group": { "kind": "test", "isDefault": true }, "presentation": { "reveal": "always", "panel": "new" }, "problemMatcher": [] }, { "label": "Pylint", "detail": "Run pylint code analysis", "type": "shell", "command": "pylint pyatmo", "dependsOn": [ "Install all Requirements" ], "group": { "kind": "test", "isDefault": true }, "presentation": { "reveal": "always", "panel": "new" }, "problemMatcher": [] }, { "label": "Code Coverage", "detail": "Generate code coverage report", "type": "shell", "command": "pytest ./tests --cov=pyatmo --cov-report term-missing", "group": { "kind": "test", "isDefault": true }, "presentation": { "reveal": "always", "panel": "new" }, "problemMatcher": [] }, { "label": "Build wheel artifacts", "command": "rm -r dist; python -m build", "type": "shell", "options": { "cwd": "${workspaceRoot}/" }, "group": { "kind": "build", "isDefault": true }, "problemMatcher": [], "presentation": { "reveal": "always", "panel": "new" } } ] } pyatmo-9.2.1/CHANGELOG.md000066400000000000000000000256651501740523400146640ustar00rootroot00000000000000# Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [unreleased] ### Added - ### Changed - ### Fixed - ### Removed - ## [9.2.1] ### Added - Added SPDX license identifier [PEP 639](https://peps.python.org/pep-0639/). ### Fixed - Removed upper bound for Python version constraint. ## [9.2.0] ### Changed - Improved schedule handling - Updated dev container configuration ## [9.1.0] ### Added - Support for 3rd party zigbee roller blinds - Support for Netatmo Indoor Camera Advance (NPC) - Fixtures for multiple modules (NLL, NLV, NLLV, NLJ, NLIS, NLPT, NLPD, NLPO) - Added conventional-pre-commit hook for commit-msg stage ### Changed - Updated device type descriptions to better reflect their functionality - Removed some unnecessary mixins from Legrand device classes - Create RemoteControlMixin for easier device representation - Replaced setup-cfg-fmt with pyprojectsort pre-commit hook - Improved error handling in extract_raw_data for empty homes - Refactored test file handling to use anyio.open_file() - Updated pre-commit hooks to latest versions - Updated project metadata in pyproject.toml ### Fixed - Handling of cooling/heating control mode - Fixed async tests to avoid blocking file access - Fixed detection of missing homes in API responses - Fixed async mock configuration in tests - Fixed error handling for throttling errors - Fixed exception class names to end with "Error" suffix - Fixed handling of empty homes data - Fixed test file handling to use anyio - Fixed coverage report configuration in tox.ini - Fixed type casting in async_update_measures method for Energy module - Fixed error handling for missing parameters in fake_post_request - Fixed handling of unknown device types - Fixed handling of place data and historical data in NetatmoBase class - Fixed handling of station ids in fix_id function - Fixed handling of zone_id type in async_set_schedule_temperatures method - Fixed handling of angle for display in module.py - Fixed handling of device type and boiler status in Room class - Fixed handling of missing parameters in test functions - Fixed handling of file paths for fixtures - Fixed handling of deprecated assert_called method - Fixed handling of test cases for NLP, NLF, and NLIS Legrand modules - Fixed handling of test cases for different weather modules - Fixed handling of mypy configuration in tox.ini ## [9.0.0] ### Added - Support for Pilot Wire ("fil pilote" support) - AC Auto schedule ### Changed - Replaced pipenv with uv and updated readme ### Removed - Python 3.10 support ### Fixed - Propper handling of climate schedules in heating or cooling - Fix HVAC related setpoint evaluation - devcontainer ## [8.1.0] ### Added - Expose camera person status - Add NLE support - Add proper energy support - Add cooler support - Add BNS support ## [8.0.3] ### Added - Add NLLF centralized ventilation controller ### Fixed - Add BNSC switch capability ## [8.0.3] ### Added - Add NLLF centralized ventilation controller ### Fixed - Add BNSC switch capability ## [8.0.2] ### Fixed - Duplicates in entity names (https://github.com/home-assistant/core/issues/88792) - Add shutter capabilities to BNAB, BNAS and BNMS (https://github.com/home-assistant/core/issues/106392) ## [8.0.1] ### Added - NLFE Legrand dimmer switch evolution ## [8.0.0] ### Added - Bticino IP scopes - Bticino dimmable light (BNLD) - Start and end times to room class ### Changed - Add power data to NLPD entities ### Removed - deprecated code ## [7.6.0] ### Added - Opening category for NACamDoorTag - Schedule modification - Bticino MyHome Server 1 scopes - NLPD - Drivia dry contact - BTicino module stubs (functionality will come later) - support for Legrand garage door opener (NLJ) - support for BTicino intelligent light (BNIL) ### Removed - Support for Python 3.8 and 3.9 ### Fixed - Update functionality for NLP, NLC, NLT and NLG ## [7.5.0] ### Added - Add NLAS - wireless batteryless scene switch device type - Add BNEU, EBU, NLDD, NLAO, NLLF, NLUO, NLUP, Z3L, NLTS, NLUF ### Fixed - Update Legrand and BTicino devices - Fix broken temperature setter when OTM is in the setup ## [7.4.0] ### Added - Add NLUF device stub - Add TPSRS Somfy shutters ### Changed - Update test fixture data to be in line with HA tests ### Fixed - Handle unknown device types and log - Fix misc device types and add stubs for unknown ## [7.3.0] ### Added - Add Legrand NLUI device class ### Changed - Minor code clean ups ### Fixed - Handle invalid ip addressed from the API more gracefully - Let weather station devices register home even if home does not exist - Catch ContentTypeError error and handle more graceful - Fix key error when battery hits very_low - Response handling issues ## [7.2.0] ### Added - Add NLPO Legrand contactor - Add NLD Legrand Double On/Off dimmer remote - Add NLFE Legrand On-Off dimmer switch - Add BTicino device support for BNCX, BNDL, BNSL ## [7.1.1] ### Fixed - Fix Netatmo radiator valves (NRV) set termpature ## [7.1.0] - 2022-10-03 ### Added - Adds Legrand NLIS double switches - Adds Legrand NLPT relay/teleruptor ### Fixed - Use dimmer type for Legrand NLF dimmers ## [7.0.1] - 2022-06-05 ### Deprecated - The following modules are deprecated and will be removed in pyatmo 8.0.0 - camera - home_coach - public_data - thermostat - weather_station ## [7.0.0] - 2022-06-05 ### Added - Adds support for Netatmo modulating thermostat - Adds support for Netatmo doorbell - Adds support for shutters, lights, energy meters and switches - Adds support for 3rd party devices from different Legrand brands such as BTicinio, Bubendorff, Smarther, CX3 - Fetch favorite weather sensors - Add support for third-party Netatmo devices (see `base_url` and `user_prefix` parameters) ### Changed - Replace freezegun with time-machine ### Deprecated - The following modules are deprecated and will be removed in pyatmo 8.0.0 - camera - home_coach - public_data - thermostat - weather_station ### Removed - ### Fixed - Use async fixture decorators ### Security - ## [6.2.4] - 2022-01-31 ### Fixed - Crash when home does not contain valid devices ## [6.2.2] - 2021-12-29 ### Fixed - Use ID if schedule name is missing ## [6.2.1] - 2021-12-18 ### Fixed - Catch when no body is contained in the response ## [6.2.0] - 2021-11-19 ### Added - Add support for python3.20 - Introduce climate module #156 ### Changed - Use assignment expressions ## [6.1.0] - 2021-10-03 ### Added - Provide a VS Code devcontainer ### Changed - Provide separate method for image retrival - Minor f-string conversions ## [6.0.0] - 2021-09-10 ### Changed - Ensure camera name is not None - Split persons by home - BREAKING: Require home_id for person related methods - version is now managed by setuptools scm ## [5.2.3] - 2021-07-22 ### Fixed - Ignore if API omits unimportant attributes in response ## [5.2.2] - 2021-07-21 ### Fixed - Ignore if API omits unimportant attributes in response ## [5.2.1] - 2021-07-10 ### Added - Distribute type information ### Changed - Update type annotations ## [5.2.0] - 2021-06-30 ### Changed - [BREAKING] Fix parameter order of set person home/away methods - Refactor camera person detection checks ## [5.1.0] - 2021-06-14 ### Fixed - Handle error when camera is not reachable more graceful - Update selfcheck to use the new update methods - Fix false positive errors when no climate devices are registered ### Security - Upgrade aiohttp to 3.7.4 or later to fix vulnerability ## [4.2.3] - 2021-05-17 ### Fixed - Extraction of climate schedules was looking for the wrong attribute (Backported from [5.0.1]) ## [5.0.1] - 2021-05-09 ### Fixed - Extraction of climate schedules was looking for the wrong attribute ## [5.0.0] - 2021-04-26 ### Added - Async support ### Changed - [BREAKING] Data retrival extracted into separate update method ## [4.2.2] - 2021-01-20 ### Fixed - Fix error when camera does not return a local url ## [4.2.1] - 2020-12-03 ### Changed - Improve CI & deployment ## [4.2.0] - 2020-11-02 ### Changed - Improve CI & deployment ### Fixed - Set station name if not contained in the backend data ### Removed - Remove min and max from weather station ## [4.1.0] - 2020-10-07 ### Fixed - Fix crash when station name is not contained in the backend data [unreleased]: https://github.com/jabesq-org/pyatmo/compare/v9.2.1...HEAD [9.2.1]: https://github.com/jabesq-org/pyatmo/compare/v9.2.0...v9.2.1 [9.2.0]: https://github.com/jabesq-org/pyatmo/compare/v9.1.0...v9.2.0 [9.1.0]: https://github.com/jabesq-org/pyatmo/compare/v9.0.0...v9.1.0 [9.0.0]: https://github.com/jabesq-org/pyatmo/compare/v8.1.0...v9.0.0 [8.1.0]: https://github.com/jabesq/pyatmo/compare/v8.0.3...v8.1.0 [8.0.3]: https://github.com/jabesq/pyatmo/compare/v8.0.2...v8.0.3 [8.0.2]: https://github.com/jabesq/pyatmo/compare/v8.0.1...v8.0.2 [8.0.1]: https://github.com/jabesq/pyatmo/compare/v8.0.0...v8.0.1 [8.0.0]: https://github.com/jabesq/pyatmo/compare/v7.6.0...v8.0.0 [7.6.0]: https://github.com/jabesq/pyatmo/compare/v7.5.0...v7.6.0 [7.5.0]: https://github.com/jabesq/pyatmo/compare/v7.4.0...v7.5.0 [7.4.0]: https://github.com/jabesq/pyatmo/compare/v7.3.0...v7.4.0 [7.3.0]: https://github.com/jabesq/pyatmo/compare/v7.2.0...v7.3.0 [7.2.0]: https://github.com/jabesq/pyatmo/compare/v7.1.1...v7.2.0 [7.1.1]: https://github.com/jabesq/pyatmo/compare/v7.1.0...v7.1.1 [7.1.0]: https://github.com/jabesq/pyatmo/compare/v7.0.1...v7.1.0 [7.0.1]: https://github.com/jabesq/pyatmo/compare/v7.0.0...v7.0.1 [7.0.0]: https://github.com/jabesq/pyatmo/compare/v6.2.4...v7.0.0 [6.2.4]: https://github.com/jabesq/pyatmo/compare/v6.2.2...v6.2.4 [6.2.2]: https://github.com/jabesq/pyatmo/compare/v6.2.1...v6.2.2 [6.2.1]: https://github.com/jabesq/pyatmo/compare/v6.2.0...v6.2.1 [6.2.0]: https://github.com/jabesq/pyatmo/compare/v6.1.0...v6.2.0 [6.1.0]: https://github.com/jabesq/pyatmo/compare/v6.0.0...v6.1.0 [6.0.0]: https://github.com/jabesq/pyatmo/compare/v5.2.3...v6.0.0 [5.2.3]: https://github.com/jabesq/pyatmo/compare/v5.2.2...v5.2.3 [5.2.2]: https://github.com/jabesq/pyatmo/compare/v5.2.1...v5.2.2 [5.2.1]: https://github.com/jabesq/pyatmo/compare/v5.2.0...v5.2.1 [5.2.0]: https://github.com/jabesq/pyatmo/compare/v5.1.0...v5.2.0 [5.1.0]: https://github.com/jabesq/pyatmo/compare/v5.0.1...v5.1.0 [5.0.1]: https://github.com/jabesq/pyatmo/compare/v5.0.0...v5.0.1 [5.0.0]: https://github.com/jabesq/pyatmo/compare/v4.2.2...v5.0.0 [4.2.3]: https://github.com/jabesq/pyatmo/compare/v4.2.2...v4.2.3 [4.2.2]: https://github.com/jabesq/pyatmo/compare/v4.2.1...v4.2.2 [4.2.1]: https://github.com/jabesq/pyatmo/compare/v4.2.0...v4.2.1 [4.2.0]: https://github.com/jabesq/pyatmo/compare/v4.1.0...v4.2.0 [4.1.0]: https://github.com/jabesq/pyatmo/compare/v4.0.0...v4.1.0 [4.0.0]: https://github.com/jabesq/pyatmo/compare/v3.3.1...v4.0.0 [3.3.1]: https://github.com/jabesq/pyatmo/releases/tag/v3.3.1 pyatmo-9.2.1/CODEOWNERS000066400000000000000000000003371501740523400144330ustar00rootroot00000000000000# These owners will be the default owners for everything in # the repo. Unless a later match takes precedence, # @jabesq and @cgtobi will be requested for # review when someone opens a pull request. * @jabesq @cgtobi pyatmo-9.2.1/CODE_OF_CONDUCT.md000066400000000000000000000121221501740523400156320ustar00rootroot00000000000000# Contributor Covenant Code of Conduct ## Our Pledge We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. ## Our Standards Examples of behavior that contributes to a positive environment for our community include: * Demonstrating empathy and kindness toward other people * Being respectful of differing opinions, viewpoints, and experiences * Giving and gracefully accepting constructive feedback * Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience * Focusing on what is best not just for us as individuals, but for the overall community Examples of unacceptable behavior include: * The use of sexualized language or imagery, and sexual attention or advances of any kind * Trolling, insulting or derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or email address, without their explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Enforcement Responsibilities Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. ## Scope This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at . All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the reporter of any incident. ## Enforcement Guidelines Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: ### 1. Correction **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. ### 2. Warning **Community Impact**: A violation through a single incident or series of actions. **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. ### 3. Temporary Ban **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. ### 4. Permanent Ban **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. **Consequence**: A permanent ban from any sort of public interaction within the community. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.0, available at https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder](https://github.com/mozilla/diversity). [homepage]: https://www.contributor-covenant.org For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. pyatmo-9.2.1/LICENSE.txt000066400000000000000000000020541501740523400146610ustar00rootroot00000000000000MIT License Copyright (c) 2018 Hugo DUPRAS Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. pyatmo-9.2.1/README.md000066400000000000000000000046221501740523400143200ustar00rootroot00000000000000# pyatmo [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) [![GitHub Actions](https://github.com/jabesq/pyatmo/workflows/Python%20package/badge.svg)](https://github.com/jabesq/pyatmo/actions?workflow=Python+package) [![PyPi](https://img.shields.io/pypi/v/pyatmo.svg)](https://pypi.python.org/pypi/pyatmo) [![license](https://img.shields.io/pypi/l/pyatmo.svg)](https://github.com/jabesq/pyatmo/blob/master/LICENSE.txt) > **Warning:** > Due to personal reasons, I am currently unable to dedicate sufficient time to effectively manage this repository. Consequently, no attention will be given to existing or forthcoming issues until further notice. **However**, I want to assure you that I will continue to merge any pull requests that are submitted, provided they successfully pass the continuous integration tests and do not exhibit any glaring issues. > > I apologize for any inconvenience this may cause, and I sincerely hope to have the capacity to allocate more time to this repository in the near future. Your understanding is greatly appreciated. > > *Hugo DUPRAS (jabesq)* --- Simple API to access Netatmo devices and data like weather station or camera data from Python 3. For more detailed information see [dev.netatmo.com](http://dev.netatmo.com) This project has no relation with the Netatmo company. ## Install To install pyatmo simply run: pip install pyatmo Depending on your permissions you might be required to use sudo. Once installed you can simply add `pyatmo` to your Python 3 scripts by including: import pyatmo ## Note The module requires a valid user account and a registered application. Be aware that the module may stop working if Netatmo decides to change their API. ## Development Prerequisits: uv python >=3.11 Clone the repo, install dependencies and install pre-commit hooks: git clone cd pyatmo uv sync pre-commit install ## Testing To run the full suite simply run the following command from within the virtual environment: pytest or python -m pytest tests/ To generate code coverage xml (e.g. for use in VSCode) run python -m pytest --cov-report xml:cov.xml --cov pyatmo --cov-append tests/ Another way to run the tests is by using `tox`. This runs the tests against the installed package and multiple versions of python. tox or by specifying a python version tox -e py310 pyatmo-9.2.1/fixtures/000077500000000000000000000000001501740523400147065ustar00rootroot00000000000000pyatmo-9.2.1/fixtures/archive/000077500000000000000000000000001501740523400163275ustar00rootroot00000000000000pyatmo-9.2.1/fixtures/archive/camera_data_empty.json000066400000000000000000000001301501740523400226530ustar00rootroot00000000000000{ "status": "ok", "time_exec": 0.03621506690979, "time_server": 1560626960 }pyatmo-9.2.1/fixtures/archive/camera_data_events_until.json000066400000000000000000000105661501740523400242520ustar00rootroot00000000000000{ "body": { "events_list": [ { "id": "a1b2c3d4e5f6abcdef123461", "type": "person", "time": 1560706232, "camera_id": "12:34:56:00:f1:62", "device_id": "12:34:56:00:f1:62", "person_id": "91827374-7e04-5298-83ad-a0cb8372dff1", "video_status": "deleted", "is_arrival": true, "message": "John Doe gesehen" }, { "id": "a1b2c3d4e5f6abcdef123462", "type": "person_away", "time": 1560706237, "camera_id": "12:34:56:00:f1:62", "device_id": "12:34:56:00:f1:62", "person_id": "91827374-7e04-5298-83ad-a0cb8372dff1", "message": "John Doe hat das Haus verlassen", "sub_message": "John Doe gilt als „Abwesend“, da das mit diesem Profil verbundene Telefon den Bereich des Hauses verlassen hat." }, { "id": "a1b2c3d4e5f6abcdef123463", "type": "person", "time": 1560706241, "camera_id": "12:34:56:00:f1:62", "device_id": "12:34:56:00:f1:62", "person_id": "91827375-7e04-5298-83ae-a0cb8372dff2", "snapshot": { "id": "19b13efa945ec892c6da2a8c", "version": 1, "key": "1704853cfc9571bd10618591dc9035e5bc0fa3203f44739c49a5b26d2f7ad67f", "url": "https://netatmocameraimage.blob.core.windows.net/production/5ecfa94c6da5e5bc0fa3203f3cfdc903489219b13e2a8c548547b26d2f7ad6717039c49ac9571bd10618591f" }, "video_id": "f914-aa7da416643-4744-82f9-4e7d4440b", "video_status": "available", "is_arrival": false, "message": "Jane Doe gesehen" }, { "id": "a1b2c3d4e5f6abcdef123464", "type": "wifi_status", "time": 1560706271, "camera_id": "12:34:56:00:8b:a2", "device_id": "12:34:56:00:8b:a2", "sub_type": 1, "message": "Hall:WLAN-Verbindung erfolgreich hergestellt" }, { "id": "a1b2c3d4e5f6abcdef123465", "type": "outdoor", "time": 1560706283, "camera_id": "12:34:56:00:a5:a4", "device_id": "12:34:56:00:a5:a4", "video_id": "string", "video_status": "available", "event_list": [ { "type": "string", "time": 1560706283, "offset": 0, "id": "c81bcf7b-2cfg-4ac9-8455-487ed00c0001", "message": "Animal détecté", "snapshot": { "id": "5715e16849c75xxxx00000000xxxxx", "version": 1, "key": "7ac578d05030d0e170643a787ee0a29663dxxx00000xxxxx00000", "url": "https://netatmocameraimage.blob.core.windows.net/production/1aa" }, "vignette": { "id": "5715e16849c75xxxx00000000xxxxx", "version": 1, "key": "7ac578d05030d0e170643a787ee0a29663dxxx00000xxxxx00000", "url": "https://netatmocameraimage.blob.core.windows.net/production/1aa00000" } }, { "type": "string", "time": 1560706283, "offset": 0, "id": "c81bcf7b-2cfg-4ac9-8455-487ed00c0002", "message": "Animal détecté", "snapshot": { "filename": "vod\/af74631d-8311-42dc-825b-82e3abeaab09\/events\/c53b-aze7a.jpg" }, "vignette": { "filename": "vod\/af74631d-8311-42dc-825b-82e3abeaab09\/events\/c5.jpg" } } ] } ] }, "status": "ok", "time_exec": 0.03666909215079, "time_server": 15607062321 }pyatmo-9.2.1/fixtures/archive/camera_home_data.json000066400000000000000000000400221501740523400224510ustar00rootroot00000000000000{ "body": { "homes": [ { "id": "91763b24c43d3e344f424e8b", "name": "MYHOME", "persons": [ { "id": "91827374-7e04-5298-83ad-a0cb8372dff1", "last_seen": 1557071156, "out_of_sight": true, "face": { "id": "d74fad765b9100ef480720a9", "version": 1, "key": "a4a95c24b808a89f8d1730fb69ecdf2bb8b72039d2c69928b029d67fc40cb2d7", "url": "https://netatmocameraimage.blob.core.windows.net/production/d74fad765b9100ef480720a9a4a95c24b808a89f8d1730fb69ecdf2bb8b72039d2c69928b029d67fc40cb2d7" }, "pseudo": "John Doe" }, { "id": "91827375-7e04-5298-83ae-a0cb8372dff2", "last_seen": 1560600726, "out_of_sight": true, "face": { "id": "d74fad765b9100ef480720a9", "version": 3, "key": "a4a95c24b808a89f8d1730039d2c69928b029d67fc40cb2d7fb69ecdf2bb8b72", "url": "https://netatmocameraimage.blob.core.windows.net/production/d74fad765b9100ef480720a9a4a95c24b808a89f8d1730039d2c69928b029d67fc40cb2d7fb69ecdf2bb8b72" }, "pseudo": "Jane Doe" }, { "id": "91827376-7e04-5298-83af-a0cb8372dff3", "last_seen": 1560626666, "out_of_sight": false, "face": { "id": "d74fad765b9100ef480720a9", "version": 1, "key": "a4a95c2d1730fb69ecdf2bb8b72039d2c69928b029d67fc40cb2d74b808a89f8", "url": "https://netatmocameraimage.blob.core.windows.net/production/d74fad765b9100ef480720a9a4a95c2d1730fb69ecdf2bb8b72039d2c69928b029d67fc40cb2d74b808a89f8" }, "pseudo": "Richard Doe" }, { "id": "91827376-7e04-5298-83af-a0cb8372dff4", "last_seen": 1560621666, "out_of_sight": true, "face": { "id": "d0ef44fad765b980720710a9", "version": 1, "key": "ab029da89f84a95c2d1730fb67fc40cb2d74b80869ecdf2bb8b72039d2c69928", "url": "https://netatmocameraimage.blob.core.windows.net/production/d0ef44fad765b980720710a9ab029da89f84a95c2d1730fb67fc40cb2d74b80869ecdf2bb8b72039d2c69928" } } ], "place": { "city": "Frankfurt", "country": "DE", "timezone": "Europe/Berlin" }, "cameras": [ { "id": "12:34:56:00:f1:62", "type": "NACamera", "status": "on", "vpn_url": "https://prodvpn-eu-2.netatmo.net/restricted/10.255.248.91/6d278460699e56180d47ab47169efb31/MpEylTU2MDYzNjRVD-LJxUnIndumKzLboeAwMDqTTg,,", "is_local": true, "sd_status": "on", "alim_status": "on", "name": "Hall", "modules": [ { "id": "12:34:56:00:f2:f1", "type": "NIS", "battery_percent": 84, "rf": 68, "status": "no_news", "monitoring": "on", "alim_source": "battery", "tamper_detection_enabled": true, "name": "Welcome's Siren" } ], "use_pin_code": false, "last_setup": 1544828430 }, { "id": "12:34:56:00:a5:a4", "type": "NOC", "status": "on", "vpn_url": "https://prodvpn-eu-2.netatmo.net/restricted/10.255.248.91/6d278460699e56180d47ab47169efb31/MpEylTU2MDYzNjRVD-LJxUnIndumKzLboeAwMDqTTw,,", "is_local": true, "sd_status": "on", "alim_status": "on", "name": "Garden", "last_setup": 1563737661, "light_mode_status": "auto" } ], "smokedetectors": [ { "id": "12:34:56:00:8b:a2", "type": "NSD", "last_setup": 1567261859, "name": "Hall" }, { "id": "12:34:56:00:8b:ac", "type": "NSD", "last_setup": 1567262759, "name": "Kitchen" } ], "events": [ { "id": "a1b2c3d4e5f6abcdef123456", "type": "person", "time": 1560604700, "camera_id": "12:34:56:00:f1:62", "device_id": "12:34:56:00:f1:62", "person_id": "91827374-7e04-5298-83ad-a0cb8372dff1", "video_status": "deleted", "is_arrival": false, "message": "John Doe gesehen" }, { "id": "a1b2c3d4e5f6abcdef123457", "type": "person_away", "time": 1560602400, "camera_id": "12:34:56:00:f1:62", "device_id": "12:34:56:00:f1:62", "person_id": "91827374-7e04-5298-83ad-a0cb8372dff1", "message": "John Doe hat das Haus verlassen", "sub_message": "John Doe gilt als abwesend, da das mit diesem Profil verbundene Telefon den Bereich des Hauses verlassen hat." }, { "id": "a1b2c3d4e5f6abcdef123458", "type": "person", "time": 1560601200, "camera_id": "12:34:56:00:f1:62", "device_id": "12:34:56:00:f1:62", "person_id": "91827374-7e04-5298-83ad-a0cb8372dff1", "video_status": "deleted", "is_arrival": false, "message": "John Doe gesehen" }, { "id": "a1b2c3d4e5f6abcdef123459", "type": "person", "time": 1560600100, "camera_id": "12:34:56:00:f1:62", "device_id": "12:34:56:00:f1:62", "person_id": "91827375-7e04-5298-83ae-a0cb8372dff2", "snapshot": { "id": "d74fad765b9100ef480720a9", "version": 1, "key": "a4a95c24b808a89f8d1730039d2c69928b029d67fc40cb2d7fb69ecdf2bb8b72", "url": "https://netatmocameraimage.blob.core.windows.net/production/d74fad765b9100ef480720a9a4a95c24b808a89f8d1730039d2c69928b029d67fc40cb2d7fb69ecdf2bb8b72" }, "video_id": "12345678-36bc-4b9a-9762-5194e707ed51", "video_status": "available", "is_arrival": false, "message": "Jane Doe gesehen" }, { "id": "a1b2c3d4e5f6abcdef12345a", "type": "person", "time": 1560603600, "camera_id": "12:34:56:00:f1:62", "device_id": "12:34:56:00:f1:62", "person_id": "91827375-7e04-5298-83ae-a0cb8372dff3", "snapshot": { "id": "532dde8d17554c022ab071b8", "version": 1, "key": "9fbe490fffacf45b8416241946541b031a004a09b6747feb6c38c3ccbc456b28", "url": "https://netatmocameraimage.blob.core.windows.net/production/532dde8d17554c022ab071b89fbe490fffacf45b8416241946541b031a004a09b6747feb6c38c3ccbc456b28" }, "video_id": "12345678-1234-46cb-ad8f-23d893874099", "video_status": "available", "is_arrival": false, "message": "Bewegung erkannt" }, { "id": "a1b2c3d4e5f6abcdef12345b", "type": "movement", "time": 1560506200, "camera_id": "12:34:56:00:f1:62", "device_id": "12:34:56:00:f1:62", "category": "human", "snapshot": { "id": "532dde8d17554c022ab071b9", "version": 1, "key": "8fbe490fffacf45b8416241946541b031a004a09b6747feb6c38c3ccbc456b28", "url": "https://netatmocameraimage.blob.core.windows.net/production/532dde8d17554c022ab071b98fbe490fffacf45b8416241946541b031a004a09b6747feb6c38c3ccbc456b28" }, "vignette": { "id": "5dc021b5dea854bd2321707a", "version": 1, "key": "58c5a05bd6bd908f6bf368865ef7355231c44215f8eb7ae458c919b2c67b4944", "url": "https://netatmocameraimage.blob.core.windows.net/production/5dc021b5dea854bd2321707a58c5a05bd6bd908f6bf368865ef7355231c44215f8eb7ae458c919b2c67b4944" }, "video_id": "12345678-1234-46cb-ad8f-23d89387409a", "video_status": "available", "message": "Bewegung erkannt" }, { "id": "a1b2c3d4e5f6abcdef12345c", "type": "sound_test", "time": 1560506210, "camera_id": "12:34:56:00:8b:a2", "device_id": "12:34:56:00:8b:a2", "sub_type": 0, "message": "Hall: Alarmton erfolgreich getestet" }, { "id": "a1b2c3d4e5f6abcdef12345d", "type": "wifi_status", "time": 1560506220, "camera_id": "12:34:56:00:8b:a2", "device_id": "12:34:56:00:8b:a2", "sub_type": 1, "message": "Hall:WLAN-Verbindung erfolgreich hergestellt" }, { "id": "a1b2c3d4e5f6abcdef12345e", "type": "outdoor", "time": 1560643100, "camera_id": "12:34:56:00:a5:a4", "device_id": "12:34:56:00:a5:a4", "video_id": "string", "video_status": "available", "event_list": [ { "type": "string", "time": 1560643100, "offset": 0, "id": "c81bcf7b-2cfg-4ac9-8455-487ed00c0000", "message": "Animal détecté", "snapshot": { "id": "5715e16849c75xxxx00000000xxxxx", "version": 1, "key": "7ac578d05030d0e170643a787ee0a29663dxxx00000xxxxx00000", "url": "https://netatmocameraimage.blob.core.windows.net/production/1aa" }, "vignette": { "id": "5715e16849c75xxxx00000000xxxxx", "version": 1, "key": "7ac578d05030d0e170643a787ee0a29663dxxx00000xxxxx00000", "url": "https://netatmocameraimage.blob.core.windows.net/production/1aa00000" } }, { "type": "string", "time": 1560506222, "offset": 0, "id": "c81bcf7b-2cfg-4ac9-8455-487ed00c0000", "message": "Animal détecté", "snapshot": { "filename": "vod\/af74631d-8311-42dc-825b-82e3abeaab09\/events\/c53b-aze7a.jpg" }, "vignette": { "filename": "vod\/af74631d-8311-42dc-825b-82e3abeaab09\/events\/c5.jpg" } } ] } ] }, { "id": "91763b24c43d3e344f424e8c", "persons": [], "place": { "city": "Frankfurt", "country": "DE", "timezone": "Europe/Berlin" }, "cameras": [ { "id": "12:34:56:00:a5:a5", "type": "NOC", "status": "on", "vpn_url": "https://prodvpn-eu-2.netatmo.net/restricted/10.255.248.91/6d278460699e56180d47ab47169efb31/MpEylTU2MDYzNjRVD-LJxUnIndumKzLboeAwMDqTTz,,", "is_local": true, "sd_status": "on", "alim_status": "on", "name": "Street", "last_setup": 1563737561, "light_mode_status": "auto" }, { "id": "12:34:56:00:a5:a6", "type": "NOC", "status": "on", "vpn_url": "https://prodvpn-eu-2.netatmo.net/restricted/10.255.248.91/6d278460699e56180d47ab47169efb31/MpEylTU2MDYzNjRVD-LJxUnIndumKzLboeAwMDqTTz,,", "is_local": true, "sd_status": "on", "alim_status": "on", "last_setup": 1563737561, "light_mode_status": "auto" } ], "smokedetectors": [] }, { "id": "91763b24c43d3e344f424e8d", "persons": [], "place": { "city": "Frankfurt", "country": "DE", "timezone": "Europe/Berlin" }, "cameras": [], "smokedetectors": [] } ], "user": { "reg_locale": "de-DE", "lang": "de-DE", "country": "DE", "mail": "john@doe.com" }, "global_info": { "show_tags": true } }, "status": "ok", "time_exec": 0.03621506690979, "time_server": 1560626960 }pyatmo-9.2.1/fixtures/archive/camera_home_data_disconnected.json000066400000000000000000000221631501740523400252010ustar00rootroot00000000000000{ "body": { "homes": [ { "id": "91763b24c43d3e344f424e8b", "name": "MYHOME", "persons": [ { "id": "91827374-7e04-5298-83ad-a0cb8372dff1", "last_seen": 1557071156, "out_of_sight": true, "face": { "id": "d74fad765b9100ef480720a9", "version": 1, "key": "a4a95c24b808a89f8d1730fb69ecdf2bb8b72039d2c69928b029d67fc40cb2d7", "url": "https://netatmocameraimage.blob.core.windows.net/production/d74fad765b9100ef480720a9a4a95c24b808a89f8d1730fb69ecdf2bb8b72039d2c69928b029d67fc40cb2d7" }, "pseudo": "John Doe" }, { "id": "91827375-7e04-5298-83ae-a0cb8372dff2", "last_seen": 1560600726, "out_of_sight": true, "face": { "id": "d74fad765b9100ef480720a9", "version": 3, "key": "a4a95c24b808a89f8d1730039d2c69928b029d67fc40cb2d7fb69ecdf2bb8b72", "url": "https://netatmocameraimage.blob.core.windows.net/production/d74fad765b9100ef480720a9a4a95c24b808a89f8d1730039d2c69928b029d67fc40cb2d7fb69ecdf2bb8b72" }, "pseudo": "Jane Doe" }, { "id": "91827376-7e04-5298-83af-a0cb8372dff3", "last_seen": 1560626666, "out_of_sight": false, "face": { "id": "d74fad765b9100ef480720a9", "version": 1, "key": "a4a95c2d1730fb69ecdf2bb8b72039d2c69928b029d67fc40cb2d74b808a89f8", "url": "https://netatmocameraimage.blob.core.windows.net/production/d74fad765b9100ef480720a9a4a95c2d1730fb69ecdf2bb8b72039d2c69928b029d67fc40cb2d74b808a89f8" }, "pseudo": "Richard Doe" }, { "id": "91827376-7e04-5298-83af-a0cb8372dff4", "last_seen": 1560621666, "out_of_sight": true, "face": { "id": "d0ef44fad765b980720710a9", "version": 1, "key": "ab029da89f84a95c2d1730fb67fc40cb2d74b80869ecdf2bb8b72039d2c69928", "url": "https://netatmocameraimage.blob.core.windows.net/production/d0ef44fad765b980720710a9ab029da89f84a95c2d1730fb67fc40cb2d74b80869ecdf2bb8b72039d2c69928" } } ], "place": { "city": "Frankfurt", "country": "DE", "timezone": "Europe/Berlin" }, "cameras": [ { "id": "12:34:56:00:f1:62", "type": "NACamera", "status": "disconnected", "sd_status": "on", "alim_status": "on", "name": "Hall", "use_pin_code": false, "last_setup": 1544828430 } ], "smokedetectors": [], "events": [ { "id": "a1b2c3d4e5f6abcdef123456", "type": "person", "time": 1560604700, "camera_id": "12:34:56:00:f1:62", "device_id": "12:34:56:00:f1:62", "person_id": "91827374-7e04-5298-83ad-a0cb8372dff1", "video_status": "deleted", "is_arrival": false, "message": "John Doe gesehen" }, { "id": "a1b2c3d4e5f6abcdef123457", "type": "person_away", "time": 1560602400, "camera_id": "12:34:56:00:f1:62", "device_id": "12:34:56:00:f1:62", "person_id": "91827374-7e04-5298-83ad-a0cb8372dff1", "message": "John Doe hat das Haus verlassen", "sub_message": "John Doe gilt als abwesend, da das mit diesem Profil verbundene Telefon den Bereich des Hauses verlassen hat." }, { "id": "a1b2c3d4e5f6abcdef123458", "type": "person", "time": 1560601200, "camera_id": "12:34:56:00:f1:62", "device_id": "12:34:56:00:f1:62", "person_id": "91827374-7e04-5298-83ad-a0cb8372dff1", "video_status": "deleted", "is_arrival": false, "message": "John Doe gesehen" }, { "id": "a1b2c3d4e5f6abcdef123459", "type": "person", "time": 1560600100, "camera_id": "12:34:56:00:f1:62", "device_id": "12:34:56:00:f1:62", "person_id": "91827375-7e04-5298-83ae-a0cb8372dff2", "snapshot": { "id": "d74fad765b9100ef480720a9", "version": 1, "key": "a4a95c24b808a89f8d1730039d2c69928b029d67fc40cb2d7fb69ecdf2bb8b72", "url": "https://netatmocameraimage.blob.core.windows.net/production/d74fad765b9100ef480720a9a4a95c24b808a89f8d1730039d2c69928b029d67fc40cb2d7fb69ecdf2bb8b72" }, "video_id": "12345678-36bc-4b9a-9762-5194e707ed51", "video_status": "available", "is_arrival": false, "message": "Jane Doe gesehen" }, { "id": "a1b2c3d4e5f6abcdef12345a", "type": "person", "time": 1560603600, "camera_id": "12:34:56:00:f1:62", "device_id": "12:34:56:00:f1:62", "person_id": "91827375-7e04-5298-83ae-a0cb8372dff3", "snapshot": { "id": "532dde8d17554c022ab071b8", "version": 1, "key": "9fbe490fffacf45b8416241946541b031a004a09b6747feb6c38c3ccbc456b28", "url": "https://netatmocameraimage.blob.core.windows.net/production/532dde8d17554c022ab071b89fbe490fffacf45b8416241946541b031a004a09b6747feb6c38c3ccbc456b28" }, "video_id": "12345678-1234-46cb-ad8f-23d893874099", "video_status": "available", "is_arrival": false, "message": "Bewegung erkannt" }, { "id": "a1b2c3d4e5f6abcdef12345b", "type": "movement", "time": 1560506200, "camera_id": "12:34:56:00:f1:62", "device_id": "12:34:56:00:f1:62", "category": "human", "snapshot": { "id": "532dde8d17554c022ab071b9", "version": 1, "key": "8fbe490fffacf45b8416241946541b031a004a09b6747feb6c38c3ccbc456b28", "url": "https://netatmocameraimage.blob.core.windows.net/production/532dde8d17554c022ab071b98fbe490fffacf45b8416241946541b031a004a09b6747feb6c38c3ccbc456b28" }, "vignette": { "id": "5dc021b5dea854bd2321707a", "version": 1, "key": "58c5a05bd6bd908f6bf368865ef7355231c44215f8eb7ae458c919b2c67b4944", "url": "https://netatmocameraimage.blob.core.windows.net/production/5dc021b5dea854bd2321707a58c5a05bd6bd908f6bf368865ef7355231c44215f8eb7ae458c919b2c67b4944" }, "video_id": "12345678-1234-46cb-ad8f-23d89387409a", "video_status": "available", "message": "Bewegung erkannt" } ] } ], "user": { "reg_locale": "de-DE", "lang": "de-DE", "country": "DE", "mail": "john@doe.com" }, "global_info": { "show_tags": true } }, "status": "ok", "time_exec": 0.03621506690979, "time_server": 1560626960 }pyatmo-9.2.1/fixtures/archive/camera_home_data_no_homes.json000066400000000000000000000005401501740523400243410ustar00rootroot00000000000000{ "body": { "homes": [], "user": { "reg_locale": "de-DE", "lang": "de-DE", "country": "DE", "mail": "john@doe.com" }, "global_info": { "show_tags": true } }, "status": "ok", "time_exec": 0.03621506690979, "time_server": 1560626960 }pyatmo-9.2.1/fixtures/archive/camera_image_sample.jpg000066400000000000000000000012371501740523400227670ustar00rootroot00000000000000ÿØÿàJFIFÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀ "ÿÄ ÿĵ}!1AQa"q2‘¡#B±ÁRÑð$3br‚ %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚáâãäåæçèéêñòóôõö÷øùúÿÄ ÿĵw!1AQaq"2B‘¡±Á #3RðbrÑ $4á%ñ&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz‚ƒ„…†‡ˆ‰Š’“”•–—˜™š¢£¤¥¦§¨©ª²³´µ¶·¸¹ºÂÃÄÅÆÇÈÉÊÒÓÔÕÖרÙÚâãäåæçèéêòóôõö÷øùúÿÚ ?Åñ´fˆz¥È*òû£µsæ(²x¯ñŸøNµNå±þB¹WfÞÜž§½ÿÙpyatmo-9.2.1/fixtures/archive/camera_ping.json000066400000000000000000000001631501740523400214670ustar00rootroot00000000000000{ "local_url": "http://192.168.0.123/678460a0d47e5618699fb31169e2b47d", "product_name": "Welcome Netatmo" }pyatmo-9.2.1/fixtures/archive/camera_set_state_error.json000066400000000000000000000001461501740523400237370ustar00rootroot00000000000000{ "error": { "code": 21, "message": "Invalid device_id, 12:34:56:00:f1:ff" } }pyatmo-9.2.1/fixtures/archive/camera_set_state_error_already_on.json000066400000000000000000000005601501740523400261340ustar00rootroot00000000000000{ "status": "ok", "time_server": 1582932399, "body": { "home": { "id": "91763b24c43d3e344f424e8b" }, "errors": [ { "code": 23, "message": "Already on", "id": "12:34:56:00:f1:62", "command": "command/changestatus" } ] } }pyatmo-9.2.1/fixtures/archive/camera_set_state_error_wrong_parameter.json000066400000000000000000000001751501740523400272150ustar00rootroot00000000000000{ "error": { "code": 21, "message": "cannot set property floodlight for module 12:34:56:00:f1:62" } }pyatmo-9.2.1/fixtures/archive/camera_set_state_ok.json000066400000000000000000000000651501740523400232170ustar00rootroot00000000000000{ "status": "ok", "time_server": 1582932411 }pyatmo-9.2.1/fixtures/archive/error_scope.json000066400000000000000000000001221501740523400215370ustar00rootroot00000000000000{"error":{"code":13,"message":"Application does not have the good scope rights"}} pyatmo-9.2.1/fixtures/archive/home_coach_no_devices.json000066400000000000000000000007371501740523400235140ustar00rootroot00000000000000{ "body": { "devices": [], "user": { "mail": "john@doe.com", "administrative": { "lang": "de-DE", "reg_locale": "de-DE", "country": "DE", "unit": 0, "windunit": 0, "pressureunit": 0, "feel_like_algo": 0 } } }, "status": "ok", "time_exec": 0.05824708938598633, "time_server": 1565377059 }pyatmo-9.2.1/fixtures/archive/home_coach_simple.json000066400000000000000000000153641501740523400226710ustar00rootroot00000000000000{ "body": { "devices": [ { "_id": "12:34:56:26:69:0c", "cipher_id": "enc:16:1UqwQlYV5AY2pfyEi5H47dmmFOOL3mCUo+KAkchL4A2CLI5u0e45Xr5jeAswO+XO", "date_setup": 1544560184, "last_setup": 1544560184, "type": "NHC", "last_status_store": 1558268332, "firmware": 45, "last_upgrade": 1544560186, "wifi_status": 58, "reachable": false, "co2_calibrating": false, "station_name": "Bedroom", "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure", "health_idx" ], "place": { "city": "Frankfurt", "country": "DE", "timezone": "Europe/Berlin", "location": [ 52.516263, 13.377726 ] } }, { "_id": "12:34:56:25:cf:a8", "cipher_id": "enc:16:A+Jm0yFWBwUyKinFDutPZK7I2PuHN1fqaE9oB/KF+McbFs3oN9CKpR/dYbqL4om2", "date_setup": 1544562192, "last_setup": 1544562192, "type": "NHC", "last_status_store": 1559198922, "firmware": 45, "last_upgrade": 1544562194, "wifi_status": 41, "reachable": true, "co2_calibrating": false, "station_name": "Kitchen", "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure", "health_idx" ], "place": { "city": "Frankfurt", "country": "DE", "timezone": "Europe/Berlin", "location": [ 52.516263, 13.377726 ] } }, { "_id": "12:34:56:26:65:14", "cipher_id": "enc:16:7kK6ZzG4L7NgfZZ6+dMvNxw4l6vXu+88SEJkCUklNdPa4KYIHmsfa1moOilEK61i", "date_setup": 1544564061, "last_setup": 1544564061, "type": "NHC", "last_status_store": 1559067159, "firmware": 45, "last_upgrade": 1544564302, "wifi_status": 66, "reachable": true, "co2_calibrating": false, "station_name": "Livingroom", "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure", "health_idx" ], "place": { "city": "Frankfurt", "country": "DE", "timezone": "Europe/Berlin", "location": [ 52.516263, 13.377726 ] } }, { "_id": "12:34:56:3e:c5:46", "station_name": "Parents Bedroom", "date_setup": 1570732241, "last_setup": 1570732241, "type": "NHC", "last_status_store": 1572073818, "module_name": "Indoor", "firmware": 45, "wifi_status": 67, "reachable": true, "co2_calibrating": false, "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure", "health_idx" ], "place": { "city": "Frankfurt", "country": "DE", "timezone": "Europe/Berlin", "location": [ 52.516263, 13.377726 ] }, "dashboard_data": { "time_utc": 1572073816, "Temperature": 20.3, "CO2": 494, "Humidity": 63, "Noise": 42, "Pressure": 1014.5, "AbsolutePressure": 1004.1, "health_idx": 1, "min_temp": 20.3, "max_temp": 21.6, "date_max_temp": 1572059333, "date_min_temp": 1572073816 } }, { "_id": "12:34:56:26:68:92", "station_name": "Baby Bedroom", "date_setup": 1571342643, "last_setup": 1571342643, "type": "NHC", "last_status_store": 1572073995, "module_name": "Indoor", "firmware": 45, "wifi_status": 68, "reachable": true, "co2_calibrating": false, "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure", "health_idx" ], "place": { "city": "Frankfurt", "country": "DE", "timezone": "Europe/Berlin", "location": [ 52.516263, 13.377726 ] }, "dashboard_data": { "time_utc": 1572073994, "Temperature": 21.6, "CO2": 1053, "Humidity": 66, "Noise": 45, "Pressure": 1021.4, "AbsolutePressure": 1011, "health_idx": 1, "min_temp": 20.9, "max_temp": 21.6, "date_max_temp": 1572073690, "date_min_temp": 1572064254 } } ], "user": { "mail": "john@doe.com", "administrative": { "lang": "de-DE", "reg_locale": "de-DE", "country": "DE", "unit": 0, "windunit": 0, "pressureunit": 0, "feel_like_algo": 0 } } }, "status": "ok", "time_exec": 0.095954179763794, "time_server": 1559463229 }pyatmo-9.2.1/fixtures/archive/home_data_empty.json000066400000000000000000000001511501740523400223560ustar00rootroot00000000000000{ "body": {}, "status": "ok", "time_exec": 0.056135892868042, "time_server": 1559171003 }pyatmo-9.2.1/fixtures/archive/home_data_no_devices.json000066400000000000000000000015111501740523400233370ustar00rootroot00000000000000{ "body": { "homes": [ { "id": "91763b24c43d3e344f424e8c", "altitude": 112, "coordinates": [ 52.516263, 13.377726 ], "country": "DE", "timezone": "Europe/Berlin", "therm_setpoint_default_duration": 180, "therm_mode": "schedule" } ], "user": { "email": "john@doe.com", "language": "de-DE", "locale": "de-DE", "feel_like_algorithm": 0, "unit_pressure": 0, "unit_system": 0, "unit_wind": 0, "id": "91763b24c43d3e344f424e8b" } }, "status": "ok", "time_exec": 0.056135892868042, "time_server": 1559171003 }pyatmo-9.2.1/fixtures/archive/home_data_no_homes.json000066400000000000000000000006611501740523400230350ustar00rootroot00000000000000{ "body": { "homes": [], "user": { "email": "john@doe.com", "language": "de-DE", "locale": "de-DE", "feel_like_algorithm": 0, "unit_pressure": 0, "unit_system": 0, "unit_wind": 0, "id": "91763b24c43d3e344f424e8b" } }, "status": "ok", "time_exec": 0.056135892868042, "time_server": 1559171003 }pyatmo-9.2.1/fixtures/archive/home_data_nohomename.json000066400000000000000000000371671501740523400233670ustar00rootroot00000000000000{ "body": { "homes": [ { "id": "91763b24c43d3e344f424e8b", "altitude": 112, "coordinates": [ 52.516263, 13.377726 ], "country": "DE", "timezone": "Europe/Berlin", "rooms": [ { "id": "2746182631", "name": "Livingroom", "type": "livingroom", "module_ids": [ "12:34:56:00:01:ae" ] }, { "id": "3688132631", "name": "Hall", "type": "custom", "module_ids": [ "12:34:56:00:f1:62" ] } ], "modules": [ { "id": "12:34:56:00:fa:d0", "type": "NAPlug", "name": "Thermostat", "setup_date": 1494963356, "modules_bridged": [ "12:34:56:00:01:ae" ] }, { "id": "12:34:56:00:01:ae", "type": "NATherm1", "name": "Livingroom", "setup_date": 1494963356, "room_id": "2746182631", "bridge": "12:34:56:00:fa:d0" }, { "id": "12:34:56:00:f1:62", "type": "NACamera", "name": "Hall", "setup_date": 1544828430, "room_id": "3688132631" } ], "therm_schedules": [ { "zones": [ { "type": 0, "name": "Comfort", "rooms_temp": [ { "temp": 21, "room_id": "2746182631" } ], "id": 0 }, { "type": 1, "name": "Night", "rooms_temp": [ { "temp": 17, "room_id": "2746182631" } ], "id": 1 }, { "type": 5, "name": "Eco", "rooms_temp": [ { "temp": 17, "room_id": "2746182631" } ], "id": 4 } ], "timetable": [ { "zone_id": 1, "m_offset": 0 }, { "zone_id": 0, "m_offset": 360 }, { "zone_id": 4, "m_offset": 420 }, { "zone_id": 0, "m_offset": 960 }, { "zone_id": 1, "m_offset": 1410 }, { "zone_id": 0, "m_offset": 1800 }, { "zone_id": 4, "m_offset": 1860 }, { "zone_id": 0, "m_offset": 2400 }, { "zone_id": 1, "m_offset": 2850 }, { "zone_id": 0, "m_offset": 3240 }, { "zone_id": 4, "m_offset": 3300 }, { "zone_id": 0, "m_offset": 3840 }, { "zone_id": 1, "m_offset": 4290 }, { "zone_id": 0, "m_offset": 4680 }, { "zone_id": 4, "m_offset": 4740 }, { "zone_id": 0, "m_offset": 5280 }, { "zone_id": 1, "m_offset": 5730 }, { "zone_id": 0, "m_offset": 6120 }, { "zone_id": 4, "m_offset": 6180 }, { "zone_id": 0, "m_offset": 6720 }, { "zone_id": 1, "m_offset": 7170 }, { "zone_id": 0, "m_offset": 7620 }, { "zone_id": 1, "m_offset": 8610 }, { "zone_id": 0, "m_offset": 9060 }, { "zone_id": 1, "m_offset": 10050 } ], "hg_temp": 7, "away_temp": 14, "name": "Default", "selected": true, "id": "591b54a2764ff4d50d8b5795", "type": "therm" } ], "therm_setpoint_default_duration": 120, "persons": [ { "id": "91827374-7e04-5298-83ad-a0cb8372dff1", "pseudo": "John Doe", "url": "https://netatmocameraimage.blob.core.windows.net/production/d74fad765b9100ef480720a9a4a95c24b808a89f8d1730fb69ecdf2bb8b72039d2c69928b029d67fc40cb2d7" }, { "id": "91827375-7e04-5298-83ae-a0cb8372dff2", "pseudo": "Jane Doe", "url": "https://netatmocameraimage.blob.core.windows.net/production/d74fad765b9100ef480720a9a4a95c24b808a89f8d1730039d2c69928b029d67fc40cb2d7fb69ecdf2bb8b72" }, { "id": "91827376-7e04-5298-83af-a0cb8372dff3", "pseudo": "Richard Doe", "url": "https://netatmocameraimage.blob.core.windows.net/production/d74fad765b9100ef480720a9a4a95c2d1730fb69ecdf2bb8b72039d2c69928b029d67fc40cb2d74b808a89f8" } ], "schedules": [ { "zones": [ { "type": 0, "name": "Komfort", "rooms_temp": [ { "temp": 21, "room_id": "2746182631" } ], "id": 0, "rooms": [ { "id": "2746182631", "therm_setpoint_temperature": 21 } ] }, { "type": 1, "name": "Nacht", "rooms_temp": [ { "temp": 17, "room_id": "2746182631" } ], "id": 1, "rooms": [ { "id": "2746182631", "therm_setpoint_temperature": 17 } ] }, { "type": 5, "name": "Eco", "rooms_temp": [ { "temp": 17, "room_id": "2746182631" } ], "id": 4, "rooms": [ { "id": "2746182631", "therm_setpoint_temperature": 17 } ] } ], "timetable": [ { "zone_id": 1, "m_offset": 0 }, { "zone_id": 0, "m_offset": 360 }, { "zone_id": 4, "m_offset": 420 }, { "zone_id": 0, "m_offset": 960 }, { "zone_id": 1, "m_offset": 1410 }, { "zone_id": 0, "m_offset": 1800 }, { "zone_id": 4, "m_offset": 1860 }, { "zone_id": 0, "m_offset": 2400 }, { "zone_id": 1, "m_offset": 2850 }, { "zone_id": 0, "m_offset": 3240 }, { "zone_id": 4, "m_offset": 3300 }, { "zone_id": 0, "m_offset": 3840 }, { "zone_id": 1, "m_offset": 4290 }, { "zone_id": 0, "m_offset": 4680 }, { "zone_id": 4, "m_offset": 4740 }, { "zone_id": 0, "m_offset": 5280 }, { "zone_id": 1, "m_offset": 5730 }, { "zone_id": 0, "m_offset": 6120 }, { "zone_id": 4, "m_offset": 6180 }, { "zone_id": 0, "m_offset": 6720 }, { "zone_id": 1, "m_offset": 7170 }, { "zone_id": 0, "m_offset": 7620 }, { "zone_id": 1, "m_offset": 8610 }, { "zone_id": 0, "m_offset": 9060 }, { "zone_id": 1, "m_offset": 10050 } ], "hg_temp": 7, "away_temp": 14, "name": "Default", "id": "591b54a2764ff4d50d8b5795", "selected": true, "type": "therm" } ], "therm_mode": "schedule" } ], "user": { "email": "john@doe.com", "language": "de-DE", "locale": "de-DE", "feel_like_algorithm": 0, "unit_pressure": 0, "unit_system": 0, "unit_wind": 0, "id": "91763b24c43d3e344f424e8b" } }, "status": "ok", "time_exec": 0.056135892868042, "time_server": 1559171003 }pyatmo-9.2.1/fixtures/archive/home_data_simple.json000066400000000000000000000556271501740523400225330ustar00rootroot00000000000000{ "body": { "homes": [ { "id": "91763b24c43d3e344f424e8b", "name": "MYHOME", "altitude": 112, "coordinates": [ 52.516263, 13.377726 ], "country": "DE", "timezone": "Europe/Berlin", "rooms": [ { "id": "2746182631", "name": "Livingroom", "type": "livingroom", "module_ids": [ "12:34:56:00:01:ae" ] }, { "id": "3688132631", "name": "Hall", "type": "custom", "module_ids": [ "12:34:56:00:f1:62" ] }, { "id": "2833524037", "name": "Entrada", "type": "lobby", "module_ids": [ "12:34:56:03:a5:54" ] }, { "id": "2940411577", "name": "Cocina", "type": "kitchen", "module_ids": [ "12:34:56:03:a0:ac" ] } ], "modules": [ { "id": "12:34:56:00:fa:d0", "type": "NAPlug", "name": "Thermostat", "setup_date": 1494963356, "modules_bridged": [ "12:34:56:00:01:ae", "12:34:56:03:a0:ac", "12:34:56:03:a5:54" ] }, { "id": "12:34:56:00:01:ae", "type": "NATherm1", "name": "Livingroom", "setup_date": 1494963356, "room_id": "2746182631", "bridge": "12:34:56:00:fa:d0" }, { "id": "12:34:56:03:a5:54", "type": "NRV", "name": "Valve1", "setup_date": 1554549767, "room_id": "2833524037", "bridge": "12:34:56:00:fa:d0" }, { "id": "12:34:56:03:a0:ac", "type": "NRV", "name": "Valve2", "setup_date": 1554554444, "room_id": "2940411577", "bridge": "12:34:56:00:fa:d0" }, { "id": "12:34:56:00:f1:62", "type": "NACamera", "name": "Hall", "setup_date": 1544828430, "room_id": "3688132631" } ], "therm_schedules": [ { "zones": [ { "type": 0, "name": "Comfort", "rooms_temp": [ { "temp": 21, "room_id": "2746182631" } ], "id": 0 }, { "type": 1, "name": "Night", "rooms_temp": [ { "temp": 17, "room_id": "2746182631" } ], "id": 1 }, { "type": 5, "name": "Eco", "rooms_temp": [ { "temp": 17, "room_id": "2746182631" } ], "id": 4 } ], "timetable": [ { "zone_id": 1, "m_offset": 0 }, { "zone_id": 0, "m_offset": 360 }, { "zone_id": 4, "m_offset": 420 }, { "zone_id": 0, "m_offset": 960 }, { "zone_id": 1, "m_offset": 1410 }, { "zone_id": 0, "m_offset": 1800 }, { "zone_id": 4, "m_offset": 1860 }, { "zone_id": 0, "m_offset": 2400 }, { "zone_id": 1, "m_offset": 2850 }, { "zone_id": 0, "m_offset": 3240 }, { "zone_id": 4, "m_offset": 3300 }, { "zone_id": 0, "m_offset": 3840 }, { "zone_id": 1, "m_offset": 4290 }, { "zone_id": 0, "m_offset": 4680 }, { "zone_id": 4, "m_offset": 4740 }, { "zone_id": 0, "m_offset": 5280 }, { "zone_id": 1, "m_offset": 5730 }, { "zone_id": 0, "m_offset": 6120 }, { "zone_id": 4, "m_offset": 6180 }, { "zone_id": 0, "m_offset": 6720 }, { "zone_id": 1, "m_offset": 7170 }, { "zone_id": 0, "m_offset": 7620 }, { "zone_id": 1, "m_offset": 8610 }, { "zone_id": 0, "m_offset": 9060 }, { "zone_id": 1, "m_offset": 10050 } ], "hg_temp": 7, "away_temp": 14, "name": "Default", "selected": true, "id": "591b54a2764ff4d50d8b5795", "type": "therm" }, { "zones": [ { "type": 0, "name": "Comfort", "rooms_temp": [ { "temp": 21, "room_id": "2746182631" } ], "id": 0 }, { "type": 1, "name": "Night", "rooms_temp": [ { "temp": 17, "room_id": "2746182631" } ], "id": 1 }, { "type": 5, "name": "Eco", "rooms_temp": [ { "temp": 17, "room_id": "2746182631" } ], "id": 4 } ], "timetable": [ { "zone_id": 1, "m_offset": 0 }, { "zone_id": 0, "m_offset": 360 }, { "zone_id": 4, "m_offset": 420 }, { "zone_id": 0, "m_offset": 960 }, { "zone_id": 1, "m_offset": 1410 }, { "zone_id": 0, "m_offset": 1800 }, { "zone_id": 4, "m_offset": 1860 }, { "zone_id": 0, "m_offset": 2400 }, { "zone_id": 1, "m_offset": 2850 }, { "zone_id": 0, "m_offset": 3240 }, { "zone_id": 4, "m_offset": 3300 }, { "zone_id": 0, "m_offset": 3840 }, { "zone_id": 1, "m_offset": 4290 }, { "zone_id": 0, "m_offset": 4680 }, { "zone_id": 4, "m_offset": 4740 }, { "zone_id": 0, "m_offset": 5280 }, { "zone_id": 1, "m_offset": 5730 }, { "zone_id": 0, "m_offset": 6120 }, { "zone_id": 4, "m_offset": 6180 }, { "zone_id": 0, "m_offset": 6720 }, { "zone_id": 1, "m_offset": 7170 }, { "zone_id": 0, "m_offset": 7620 }, { "zone_id": 1, "m_offset": 8610 }, { "zone_id": 0, "m_offset": 9060 }, { "zone_id": 1, "m_offset": 10050 } ], "hg_temp": 7, "away_temp": 14, "name": "Winter", "id": "b1b54a2f45795764f59d50d8", "type": "therm" } ], "therm_setpoint_default_duration": 120, "persons": [ { "id": "91827374-7e04-5298-83ad-a0cb8372dff1", "pseudo": "John Doe", "url": "https://netatmocameraimage.blob.core.windows.net/production/d74fad765b9100ef480720a9a4a95c24b808a89f8d1730fb69ecdf2bb8b72039d2c69928b029d67fc40cb2d7" }, { "id": "91827375-7e04-5298-83ae-a0cb8372dff2", "pseudo": "Jane Doe", "url": "https://netatmocameraimage.blob.core.windows.net/production/d74fad765b9100ef480720a9a4a95c24b808a89f8d1730039d2c69928b029d67fc40cb2d7fb69ecdf2bb8b72" }, { "id": "91827376-7e04-5298-83af-a0cb8372dff3", "pseudo": "Richard Doe", "url": "https://netatmocameraimage.blob.core.windows.net/production/d74fad765b9100ef480720a9a4a95c2d1730fb69ecdf2bb8b72039d2c69928b029d67fc40cb2d74b808a89f8" } ], "schedules": [ { "zones": [ { "type": 0, "name": "Komfort", "rooms_temp": [ { "temp": 21, "room_id": "2746182631" } ], "id": 0, "rooms": [ { "id": "2746182631", "therm_setpoint_temperature": 21 } ] }, { "type": 1, "name": "Nacht", "rooms_temp": [ { "temp": 17, "room_id": "2746182631" } ], "id": 1, "rooms": [ { "id": "2746182631", "therm_setpoint_temperature": 17 } ] }, { "type": 5, "name": "Eco", "rooms_temp": [ { "temp": 17, "room_id": "2746182631" } ], "id": 4, "rooms": [ { "id": "2746182631", "therm_setpoint_temperature": 17 } ] } ], "timetable": [ { "zone_id": 1, "m_offset": 0 }, { "zone_id": 0, "m_offset": 360 }, { "zone_id": 4, "m_offset": 420 }, { "zone_id": 0, "m_offset": 960 }, { "zone_id": 1, "m_offset": 1410 }, { "zone_id": 0, "m_offset": 1800 }, { "zone_id": 4, "m_offset": 1860 }, { "zone_id": 0, "m_offset": 2400 }, { "zone_id": 1, "m_offset": 2850 }, { "zone_id": 0, "m_offset": 3240 }, { "zone_id": 4, "m_offset": 3300 }, { "zone_id": 0, "m_offset": 3840 }, { "zone_id": 1, "m_offset": 4290 }, { "zone_id": 0, "m_offset": 4680 }, { "zone_id": 4, "m_offset": 4740 }, { "zone_id": 0, "m_offset": 5280 }, { "zone_id": 1, "m_offset": 5730 }, { "zone_id": 0, "m_offset": 6120 }, { "zone_id": 4, "m_offset": 6180 }, { "zone_id": 0, "m_offset": 6720 }, { "zone_id": 1, "m_offset": 7170 }, { "zone_id": 0, "m_offset": 7620 }, { "zone_id": 1, "m_offset": 8610 }, { "zone_id": 0, "m_offset": 9060 }, { "zone_id": 1, "m_offset": 10050 } ], "hg_temp": 7, "away_temp": 14, "name": "Default", "id": "591b54a2764ff4d50d8b5795", "selected": true, "type": "therm" } ], "therm_mode": "schedule" }, { "id": "91763b24c43d3e344f424e8c", "altitude": 112, "coordinates": [ 52.516263, 13.377726 ], "country": "DE", "timezone": "Europe/Berlin", "therm_setpoint_default_duration": 180, "therm_mode": "schedule" } ], "user": { "email": "john@doe.com", "language": "de-DE", "locale": "de-DE", "feel_like_algorithm": 0, "unit_pressure": 0, "unit_system": 0, "unit_wind": 0, "id": "91763b24c43d3e344f424e8b" } }, "status": "ok", "time_exec": 0.056135892868042, "time_server": 1559171003 }pyatmo-9.2.1/fixtures/archive/home_status_empty.json000066400000000000000000000001051501740523400227670ustar00rootroot00000000000000{ "status": "ok", "time_server": 1559292039, "body": {} }pyatmo-9.2.1/fixtures/archive/home_status_error_and_data.json000066400000000000000000000074701501740523400246110ustar00rootroot00000000000000{ "status": "ok", "time_server": 1559292039, "body": { "home": { "modules": [ { "id": "12:34:56:00:fa:d0", "type": "NAPlug", "firmware_revision": 174, "rf_strength": 107, "wifi_strength": 42 }, { "id": "12:34:56:00:01:ae", "reachable": true, "type": "NATherm1", "firmware_revision": 65, "rf_strength": 58, "battery_level": 3793, "boiler_valve_comfort_boost": false, "boiler_status": false, "anticipating": false, "bridge": "12:34:56:00:fa:d0", "battery_state": "high" }, { "id": "12:34:56:03:a5:54", "reachable": true, "type": "NRV", "firmware_revision": 79, "rf_strength": 51, "battery_level": 3025, "bridge": "12:34:56:00:fa:d0", "battery_state": "full" }, { "id": "12:34:56:03:a0:ac", "reachable": true, "type": "NRV", "firmware_revision": 79, "rf_strength": 59, "battery_level": 3029, "bridge": "12:34:56:00:fa:d0", "battery_state": "full" } ], "rooms": [ { "id": "2746182631", "reachable": true, "therm_measured_temperature": 19.8, "therm_setpoint_temperature": 12, "therm_setpoint_mode": "away", "therm_setpoint_start_time": 1559229567, "therm_setpoint_end_time": 0 }, { "id": "2940411577", "reachable": true, "therm_measured_temperature": 27, "heating_power_request": 0, "therm_setpoint_temperature": 7, "therm_setpoint_mode": "hg", "therm_setpoint_start_time": 0, "therm_setpoint_end_time": 0, "anticipating": false, "open_window": false }, { "id": "2833524037", "reachable": true, "therm_measured_temperature": 24.5, "heating_power_request": 0, "therm_setpoint_temperature": 7, "therm_setpoint_mode": "hg", "therm_setpoint_start_time": 0, "therm_setpoint_end_time": 0, "anticipating": false, "open_window": false } ], "id": "91763b24c43d3e344f424e8b", "persons": [ { "id": "91827374-7e04-5298-83ad-a0cb8372dff1", "last_seen": 1557071156, "out_of_sight": true }, { "id": "91827375-7e04-5298-83ae-a0cb8372dff2", "last_seen": 1559282761, "out_of_sight": false }, { "id": "91827376-7e04-5298-83af-a0cb8372dff3", "last_seen": 1559224132, "out_of_sight": true } ] }, "errors": [ { "code": 6, "id": "12:34:56:00:f1:62" } ] } }pyatmo-9.2.1/fixtures/archive/home_status_error_invalid_id.json000066400000000000000000000001141501740523400251440ustar00rootroot00000000000000{ "error": { "code": 21, "message": "Invalid id" } }pyatmo-9.2.1/fixtures/archive/home_status_error_missing_home_id.json000066400000000000000000000001211501740523400261750ustar00rootroot00000000000000{ "error": { "code": 10, "message": "Missing home_id" } }pyatmo-9.2.1/fixtures/archive/home_status_error_missing_parameters.json000066400000000000000000000001241501740523400267370ustar00rootroot00000000000000{ "error": { "code": 10, "message": "Missing parameters" } }pyatmo-9.2.1/fixtures/archive/home_status_error_mode_not_authorized.json000066400000000000000000000001251501740523400271060ustar00rootroot00000000000000{ "error": { "code": 21, "message": "mode not authorized" } }pyatmo-9.2.1/fixtures/archive/invalid_grant.json000066400000000000000000000000401501740523400220350ustar00rootroot00000000000000{ "error": "invalid_grant" }pyatmo-9.2.1/fixtures/archive/oauth2_token.json000066400000000000000000000006361501740523400216310ustar00rootroot00000000000000{ "access_token": "91763b24c43d3e344f424e8b|880b55a08c758e87ff8755a00c6b8a12", "refresh_token": "91763b24c43d3e344f424e8b|87ff8755a00c6b8a120b55a08c758e93", "scope": [ "read_station", "read_camera", "access_camera", "read_thermostat", "write_thermostat", "read_presence", "access_presence" ], "expires_in": 10800, "expire_in": 10800 }pyatmo-9.2.1/fixtures/archive/public_data_error_mongo.json000066400000000000000000000002631501740523400241020ustar00rootroot00000000000000{ "error": { "message": "failed to connect to server [localhost:27020] on first connect [MongoError: connect ECONNREFUSED 127.0.0.1:27020]", "code": 0 } } pyatmo-9.2.1/fixtures/archive/public_data_simple.json000066400000000000000000000263141501740523400230500ustar00rootroot00000000000000{ "status": "ok", "time_server": 1560248397, "time_exec": 0, "body": [ { "_id": "70:ee:50:36:94:7c", "place": { "location": [ 8.791382999999996, 50.2136394 ], "timezone": "Europe/Berlin", "country": "DE", "altitude": 132 }, "mark": 14, "measures": { "02:00:00:36:f2:94": { "res": { "1560248022": [ 21.4, 62 ] }, "type": [ "temperature", "humidity" ] }, "70:ee:50:36:94:7c": { "res": { "1560248030": [ 1010.6 ] }, "type": [ "pressure" ] }, "05:00:00:05:33:84": { "rain_60min": 0.2, "rain_24h": 12.322000000000001, "rain_live": 0.5, "rain_timeutc": 1560248022 } }, "modules": [ "05:00:00:05:33:84", "02:00:00:36:f2:94" ], "module_types": { "05:00:00:05:33:84": "NAModule3", "02:00:00:36:f2:94": "NAModule1" } }, { "_id": "70:ee:50:1f:68:9e", "place": { "location": [ 8.795445200000017, 50.2130169 ], "timezone": "Europe/Berlin", "country": "DE", "altitude": 125 }, "mark": 14, "measures": { "02:00:00:1f:82:28": { "res": { "1560248312": [ 21.1, 69 ] }, "type": [ "temperature", "humidity" ] }, "70:ee:50:1f:68:9e": { "res": { "1560248344": [ 1007.3 ] }, "type": [ "pressure" ] }, "05:00:00:02:bb:6e": { "rain_60min": 0, "rain_24h": 9.999, "rain_live": 0, "rain_timeutc": 1560248344 } }, "modules": [ "02:00:00:1f:82:28", "05:00:00:02:bb:6e" ], "module_types": { "02:00:00:1f:82:28": "NAModule1", "05:00:00:02:bb:6e": "NAModule3" } }, { "_id": "70:ee:50:27:25:b0", "place": { "location": [ 8.7807159, 50.1946167 ], "timezone": "Europe/Berlin", "country": "DE", "altitude": 112 }, "mark": 14, "measures": { "02:00:00:27:19:b2": { "res": { "1560247889": [ 23.2, 60 ] }, "type": [ "temperature", "humidity" ] }, "70:ee:50:27:25:b0": { "res": { "1560247907": [ 1012.8 ] }, "type": [ "pressure" ] }, "05:00:00:03:5d:2e": { "rain_60min": 0, "rain_24h": 11.716000000000001, "rain_live": 0, "rain_timeutc": 1560247896 } }, "modules": [ "02:00:00:27:19:b2", "05:00:00:03:5d:2e" ], "module_types": { "02:00:00:27:19:b2": "NAModule1", "05:00:00:03:5d:2e": "NAModule3" } }, { "_id": "70:ee:50:04:ed:7a", "place": { "location": [ 8.785034, 50.192169 ], "timezone": "Europe/Berlin", "country": "DE", "altitude": 112 }, "mark": 14, "measures": { "02:00:00:04:c2:2e": { "res": { "1560248137": [ 19.8, 76 ] }, "type": [ "temperature", "humidity" ] }, "70:ee:50:04:ed:7a": { "res": { "1560248152": [ 1005.4 ] }, "type": [ "pressure" ] } }, "modules": [ "02:00:00:04:c2:2e" ], "module_types": { "02:00:00:04:c2:2e": "NAModule1" } }, { "_id": "70:ee:50:27:9f:2c", "place": { "location": [ 8.785342, 50.193573 ], "timezone": "Europe/Berlin", "country": "DE", "altitude": 116 }, "mark": 1, "measures": { "02:00:00:27:aa:70": { "res": { "1560247821": [ 25.5, 56 ] }, "type": [ "temperature", "humidity" ] }, "70:ee:50:27:9f:2c": { "res": { "1560247853": [ 1010.6 ] }, "type": [ "pressure" ] } }, "modules": [ "02:00:00:27:aa:70" ], "module_types": { "02:00:00:27:aa:70": "NAModule1" } }, { "_id": "70:ee:50:01:20:fa", "place": { "location": [ 8.7953, 50.195241 ], "timezone": "Europe/Berlin", "country": "DE", "altitude": 119 }, "mark": 1, "measures": { "02:00:00:00:f7:ba": { "res": { "1560247831": [ 27.4, 58 ] }, "type": [ "temperature", "humidity" ] }, "70:ee:50:01:20:fa": { "res": { "1560247876": [ 1014.4 ] }, "type": [ "pressure" ] } }, "modules": [ "02:00:00:00:f7:ba" ], "module_types": { "02:00:00:00:f7:ba": "NAModule1" } }, { "_id": "70:ee:50:3c:02:78", "place": { "location": [ 8.795953681700666, 50.19530139868166 ], "timezone": "Europe/Berlin", "country": "DE", "altitude": 119 }, "mark": 7, "measures": { "02:00:00:3c:21:f2": { "res": { "1560248225": [ 23.3, 58 ] }, "type": [ "temperature", "humidity" ] }, "70:ee:50:3c:02:78": { "res": { "1560248270": [ 1011.7 ] }, "type": [ "pressure" ] } }, "modules": [ "02:00:00:3c:21:f2" ], "module_types": { "02:00:00:3c:21:f2": "NAModule1" } }, { "_id": "70:ee:50:36:a9:fc", "place": { "location": [ 8.801164269110814, 50.19596181704958 ], "timezone": "Europe/Berlin", "country": "DE", "altitude": 113 }, "mark": 14, "measures": { "02:00:00:36:a9:50": { "res": { "1560248145": [ 20.1, 67 ] }, "type": [ "temperature", "humidity" ] }, "70:ee:50:36:a9:fc": { "res": { "1560248191": [ 1010 ] }, "type": [ "pressure" ] }, "05:00:00:02:92:82": { "rain_60min": 0, "rain_24h": 11.009, "rain_live": 0, "rain_timeutc": 1560248184 }, "06:00:00:03:19:76": { "wind_strength": 15, "wind_angle": 17, "gust_strength": 31, "gust_angle": 217, "wind_timeutc": 1560248190 } }, "modules": [ "05:00:00:02:92:82", "02:00:00:36:a9:50", "06:00:00:03:19:76" ], "module_types": { "05:00:00:02:92:82": "NAModule3", "02:00:00:36:a9:50": "NAModule1", "06:00:00:03:19:76": "NAModule2" } } ] }pyatmo-9.2.1/fixtures/archive/thermostat_data_simple.json000066400000000000000000000255241501740523400237660ustar00rootroot00000000000000{ "body": { "devices": [ { "_id": "12:34:56:00:fa:d0", "firmware": 174, "last_bilan": { "y": 2019, "m": 4 }, "last_setup": 1494963356, "last_status_store": 1559297986, "place": { "altitude": 112, "city": "Berlin", "country": "DE", "improveLocProposed": true, "location": [ 52.516263, 13.377726 ], "timezone": "Europe/Berlin", "trust_location": true }, "plug_connected_boiler": 1, "type": "NAPlug", "udp_conn": true, "wifi_status": 42, "modules": [ { "_id": "12:34:56:00:01:ae", "module_name": "Livingroom", "type": "NATherm1", "firmware": 65, "last_message": 1559297976, "rf_status": 59, "battery_vp": 3798, "therm_orientation": 3, "therm_relay_cmd": 0, "anticipating": false, "battery_percent": 53, "event_history": { "boiler_not_responding_events": [ { "K": 1506103090 }, { "K": 1514496738 }, { "K": 1514583682 }, { "K": 1518695843 }, { "K": 1518813960 } ], "boiler_responding_events": [ { "K": 1506281109 }, { "K": 1514552830 }, { "K": 1514757686 }, { "K": 1518798339 }, { "K": 1518965265 } ] }, "setpoint_history": [ { "setpoint": { "setpoint_mode": "hg" }, "timestamp": 1559229554 }, { "setpoint": { "setpoint_mode": "program" }, "timestamp": 1559229565 }, { "setpoint": { "setpoint_mode": "away" }, "timestamp": 1559229567 } ], "last_therm_seen": 1559297976, "setpoint": { "setpoint_mode": "away" }, "therm_program_list": [ { "zones": [ { "type": 0, "name": "Comfort", "id": 0, "temp": 21 }, { "type": 1, "name": "Night", "id": 1, "temp": 17 }, { "type": 5, "name": "Eco", "id": 4, "temp": 17 }, { "type": 2, "id": 2, "temp": 14 }, { "type": 3, "id": 3, "temp": 7 } ], "timetable": [ { "m_offset": 0, "id": 1 }, { "m_offset": 360, "id": 0 }, { "m_offset": 420, "id": 4 }, { "m_offset": 960, "id": 0 }, { "m_offset": 1410, "id": 1 }, { "m_offset": 1800, "id": 0 }, { "m_offset": 1860, "id": 4 }, { "m_offset": 2400, "id": 0 }, { "m_offset": 2850, "id": 1 }, { "m_offset": 3240, "id": 0 }, { "m_offset": 3300, "id": 4 }, { "m_offset": 3840, "id": 0 }, { "m_offset": 4290, "id": 1 }, { "m_offset": 4680, "id": 0 }, { "m_offset": 4740, "id": 4 }, { "m_offset": 5280, "id": 0 }, { "m_offset": 5730, "id": 1 }, { "m_offset": 6120, "id": 0 }, { "m_offset": 6180, "id": 4 }, { "m_offset": 6720, "id": 0 }, { "m_offset": 7170, "id": 1 }, { "m_offset": 7620, "id": 0 }, { "m_offset": 8610, "id": 1 }, { "m_offset": 9060, "id": 0 }, { "m_offset": 10050, "id": 1 } ], "name": "Default", "program_id": "591b54a2764ff4d50d8b5795", "selected": true } ], "measured": { "time": 1559297836, "temperature": 19.8, "setpoint_temp": 12 } } ], "station_name": "Thermostat", "last_plug_seen": 1559297986 } ], "user": { "mail": "john@doe.com", "administrative": { "lang": "de-DE", "reg_locale": "de-DE", "country": "DE", "unit": 0, "windunit": 0, "pressureunit": 0, "feel_like_algo": 0 } } }, "status": "ok", "time_exec": 0.12061500549316, "time_server": 1559300497 }pyatmo-9.2.1/fixtures/archive/too_many_connections.json000066400000000000000000000000471501740523400234520ustar00rootroot00000000000000{ "error": "too_many_connections" }pyatmo-9.2.1/fixtures/archive/weatherstation_data_simple.json000066400000000000000000000551761501740523400246430ustar00rootroot00000000000000{ "body": { "devices": [ { "_id": "12:34:56:37:11:ca", "cipher_id": "enc:16:zjiZF/q8jTScXVdDa/kvhUAIUPGeYszaD1ClEf8byAJkRjxc5oth7cAocrMUIApX", "date_setup": 1544558432, "last_setup": 1544558432, "type": "NAMain", "last_status_store": 1559413181, "module_name": "NetatmoIndoor", "firmware": 137, "last_upgrade": 1544558433, "wifi_status": 45, "reachable": true, "co2_calibrating": false, "station_name": "MyStation", "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure" ], "place": { "altitude": 664, "city": "Frankfurt", "country": "DE", "timezone": "Europe/Berlin", "location": [ 52.516263, 13.377726 ] }, "dashboard_data": { "time_utc": 1559413171, "Temperature": 24.6, "CO2": 749, "Humidity": 36, "Noise": 37, "Pressure": 1017.3, "AbsolutePressure": 939.7, "min_temp": 23.4, "max_temp": 25.6, "date_min_temp": 1559371924, "date_max_temp": 1559411964, "temp_trend": "stable", "pressure_trend": "down" }, "modules": [ { "_id": "12:34:56:36:fc:de", "type": "NAModule1", "module_name": "NetatmoOutdoor", "data_type": [ "Temperature", "Humidity" ], "last_setup": 1544558433, "reachable": true, "dashboard_data": { "time_utc": 1559413157, "Temperature": 28.6, "Humidity": 24, "min_temp": 16.9, "max_temp": 30.3, "date_min_temp": 1559365579, "date_max_temp": 1559404698, "temp_trend": "down" }, "firmware": 46, "last_message": 1559413177, "last_seen": 1559413157, "rf_status": 65, "battery_vp": 5738, "battery_percent": 87 }, { "_id": "12:34:56:07:bb:3e", "type": "NAModule4", "module_name": "Kitchen", "data_type": [ "Temperature", "CO2", "Humidity" ], "last_setup": 1548956696, "reachable": true, "dashboard_data": { "time_utc": 1559413125, "Temperature": 28, "CO2": 503, "Humidity": 26, "min_temp": 25, "max_temp": 28, "date_min_temp": 1559371577, "date_max_temp": 1559412561, "temp_trend": "up" }, "firmware": 44, "last_message": 1559413177, "last_seen": 1559413177, "rf_status": 73, "battery_vp": 5687, "battery_percent": 83 }, { "_id": "12:34:56:07:bb:0e", "type": "NAModule4", "module_name": "Livingroom", "data_type": [ "Temperature", "CO2", "Humidity" ], "last_setup": 1548957209, "reachable": true, "dashboard_data": { "time_utc": 1559413093, "Temperature": 26.4, "CO2": 451, "Humidity": 31, "min_temp": 25.1, "max_temp": 26.4, "date_min_temp": 1559365290, "date_max_temp": 1559413093, "temp_trend": "stable" }, "firmware": 44, "last_message": 1559413177, "last_seen": 1559413093, "rf_status": 84, "battery_vp": 5626, "battery_percent": 79 }, { "_id": "12:34:56:03:1b:e4", "type": "NAModule2", "module_name": "Garden", "data_type": [ "Wind" ], "last_setup": 1549193862, "reachable": true, "dashboard_data": { "time_utc": 1559413170, "WindStrength": 4, "WindAngle": 217, "GustStrength": 9, "GustAngle": 206, "max_wind_str": 21, "max_wind_angle": 217, "date_max_wind_str": 1559386669 }, "firmware": 19, "last_message": 1559413177, "last_seen": 1559413177, "rf_status": 59, "battery_vp": 5689, "battery_percent": 85 }, { "_id": "12:34:56:05:51:20", "type": "NAModule3", "module_name": "Yard", "data_type": [ "Rain" ], "last_setup": 1549194580, "reachable": true, "dashboard_data": { "time_utc": 1559413170, "Rain": 0, "sum_rain_24": 0, "sum_rain_1": 0 }, "firmware": 8, "last_message": 1559413177, "last_seen": 1559413170, "rf_status": 67, "battery_vp": 5860, "battery_percent": 93 } ] }, { "_id": "12 :34: 56:36:fd:3c", "station_name": "Valley Road", "date_setup": 1545897146, "last_setup": 1545897146, "type": "NAMain", "last_status_store": 1581835369, "firmware": 137, "last_upgrade": 1545897125, "wifi_status": 53, "reachable": true, "co2_calibrating": false, "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure" ], "place": { "altitude": 69, "city": "Valley", "country": "AU", "timezone": "Australia/Hobart", "location": [ 148.444226, -41.721282 ] }, "read_only": true, "dashboard_data": { "time_utc": 1581835330, "Temperature": 22.4, "CO2": 471, "Humidity": 46, "Noise": 47, "Pressure": 1011.5, "AbsolutePressure": 1002.8, "min_temp": 18.1, "max_temp": 22.5, "date_max_temp": 1581829891, "date_min_temp": 1581794878, "temp_trend": "stable", "pressure_trend": "stable" }, "modules": [ { "_id": "12 :34: 56:36:e6:c0", "type": "NAModule1", "module_name": "Module", "data_type": [ "Temperature", "Humidity" ], "last_setup": 1545897146, "battery_percent": 22, "reachable": false, "firmware": 46, "last_message": 1572497781, "last_seen": 1572497742, "rf_status": 88, "battery_vp": 4118 }, { "_id": "12:34:56:05:25:6e", "type": "NAModule3", "module_name": "Rain Gauge", "data_type": [ "Rain" ], "last_setup": 1553997427, "battery_percent": 82, "reachable": true, "firmware": 8, "last_message": 1581835362, "last_seen": 1581835354, "rf_status": 78, "battery_vp": 5594, "dashboard_data": { "time_utc": 1581835329, "Rain": 0, "sum_rain_1": 0, "sum_rain_24": 0 } } ] }, { "_id": "12:34:56:32:a7:60", "home_name": "Ateljen", "date_setup": 1566714693, "last_setup": 1566714693, "type": "NAMain", "last_status_store": 1588481079, "module_name": "Indoor", "firmware": 177, "last_upgrade": 1566714694, "wifi_status": 50, "reachable": true, "co2_calibrating": false, "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure" ], "place": { "altitude": 93, "city": "Gothenburg", "country": "SE", "timezone": "Europe/Stockholm", "location": [ 11.6136629, 57.7006827 ] }, "dashboard_data": { "time_utc": 1588481073, "Temperature": 18.2, "CO2": 542, "Humidity": 45, "Noise": 45, "Pressure": 1013, "AbsolutePressure": 1001.9, "min_temp": 18.2, "max_temp": 19.5, "date_max_temp": 1588456861, "date_min_temp": 1588479561, "temp_trend": "stable", "pressure_trend": "up" }, "modules": [ { "_id": "12:34:56:32:db:06", "type": "NAModule1", "last_setup": 1587635819, "data_type": [ "Temperature", "Humidity" ], "battery_percent": 100, "reachable": false, "firmware": 255, "last_message": 0, "last_seen": 0, "rf_status": 255, "battery_vp": 65535 } ] }, { "_id": "12:34:56:1c:68:2e", "station_name": "Bol\u00e5s", "date_setup": 1470935400, "last_setup": 1470935400, "type": "NAMain", "last_status_store": 1588481399, "module_name": "Inne - Nere", "firmware": 177, "last_upgrade": 1470935401, "wifi_status": 13, "reachable": true, "co2_calibrating": false, "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure" ], "place": { "altitude": 93, "city": "Gothenburg", "country": "SE", "timezone": "Europe/Stockholm", "location": [ 11.6136629, 57.7006827 ] }, "dashboard_data": { "time_utc": 1588481387, "Temperature": 20.8, "CO2": 674, "Humidity": 41, "Noise": 34, "Pressure": 1012.1, "AbsolutePressure": 1001, "min_temp": 20.8, "max_temp": 22.2, "date_max_temp": 1588456859, "date_min_temp": 1588480176, "temp_trend": "stable", "pressure_trend": "up" }, "modules": [ { "_id": "12:34:56:02:b3:da", "type": "NAModule3", "module_name": "Regnm\u00e4tare", "last_setup": 1470937706, "data_type": [ "Rain" ], "battery_percent": 81, "reachable": true, "firmware": 12, "last_message": 1588481393, "last_seen": 1588481386, "rf_status": 67, "battery_vp": 5582, "dashboard_data": { "time_utc": 1588481386, "Rain": 0, "sum_rain_1": 0, "sum_rain_24": 0.1 } }, { "_id": "12:34:56:03:76:60", "type": "NAModule4", "module_name": "Inne - Uppe", "last_setup": 1470938089, "data_type": [ "Temperature", "CO2", "Humidity" ], "battery_percent": 14, "reachable": true, "firmware": 50, "last_message": 1588481393, "last_seen": 1588481374, "rf_status": 70, "battery_vp": 4448, "dashboard_data": { "time_utc": 1588481374, "Temperature": 19.6, "CO2": 696, "Humidity": 41, "min_temp": 19.6, "max_temp": 20.5, "date_max_temp": 1588456817, "date_min_temp": 1588481374, "temp_trend": "stable" } }, { "_id": "12:34:56:32:db:06", "type": "NAModule1", "module_name": "Ute", "last_setup": 1566326027, "data_type": [ "Temperature", "Humidity" ], "battery_percent": 81, "reachable": true, "firmware": 50, "last_message": 1588481393, "last_seen": 1588481380, "rf_status": 61, "battery_vp": 5544, "dashboard_data": { "time_utc": 1588481380, "Temperature": 6.4, "Humidity": 91, "min_temp": 3.6, "max_temp": 6.4, "date_max_temp": 1588481380, "date_min_temp": 1588471383, "temp_trend": "up" } } ] }, { "_id": "12:34:56:1d:68:2e", "date_setup": 1470935500, "last_setup": 1470935500, "type": "NAMain", "last_status_store": 1588481399, "module_name": "Basisstation", "firmware": 177, "last_upgrade": 1470935401, "wifi_status": 13, "reachable": true, "co2_calibrating": false, "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure" ], "place": { "altitude": 93, "city": "Gothenburg", "country": "SE", "timezone": "Europe/Stockholm", "location": [ 11.6136629, 57.7006827 ] }, "dashboard_data": { "time_utc": 1588481387, "Temperature": 20.8, "CO2": 674, "Humidity": 41, "Noise": 34, "Pressure": 1012.1, "AbsolutePressure": 1001, "min_temp": 20.8, "max_temp": 22.2, "date_max_temp": 1588456859, "date_min_temp": 1588480176, "temp_trend": "stable", "pressure_trend": "up" }, "modules": [] }, { "_id": "12:34:56:58:c8:54", "date_setup": 1605594014, "last_setup": 1605594014, "type": "NAMain", "last_status_store": 1605878352, "firmware": 178, "wifi_status": 47, "reachable": true, "co2_calibrating": false, "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure" ], "place": { "altitude": 65, "city": "Njurunda District", "country": "SE", "timezone": "Europe/Stockholm", "location": [ 17.123456, 62.123456 ] }, "station_name": "Njurunda (Indoor)", "home_id": "5fb36b9ec68fd10c6467ca65", "home_name": "Njurunda", "dashboard_data": { "time_utc": 1605878349, "Temperature": 19.7, "CO2": 993, "Humidity": 40, "Noise": 40, "Pressure": 1015.6, "AbsolutePressure": 1007.8, "min_temp": 19.7, "max_temp": 20.4, "date_max_temp": 1605826917, "date_min_temp": 1605873207, "temp_trend": "stable", "pressure_trend": "up" }, "modules": [ { "_id": "12:34:56:58:e6:38", "type": "NAModule1", "last_setup": 1605594034, "data_type": [ "Temperature", "Humidity" ], "battery_percent": 100, "reachable": true, "firmware": 50, "last_message": 1605878347, "last_seen": 1605878328, "rf_status": 62, "battery_vp": 6198, "dashboard_data": { "time_utc": 1605878328, "Temperature": 0.6, "Humidity": 77, "min_temp": -2.1, "max_temp": 1.5, "date_max_temp": 1605865920, "date_min_temp": 1605826904, "temp_trend": "down" } } ] } ], "user": { "mail": "john@doe.com", "administrative": { "lang": "de-DE", "reg_locale": "de-DE", "country": "DE", "unit": 0, "windunit": 0, "pressureunit": 0, "feel_like_algo": 0 } } }, "status": "ok", "time_exec": 0.91107702255249, "time_server": 1559413602 }pyatmo-9.2.1/fixtures/archive/weatherstation_data_unreachable_station.json000066400000000000000000000245331501740523400273550ustar00rootroot00000000000000{ "body": { "devices": [ { "_id": "12:34:56:37:11:ca", "cipher_id": "enc:16:zjiZF/q8jTScXVdDa/kvhUAIUPGeYszaD1ClEf8byAJkRjxc5oth7cAocrMUIApX", "date_setup": 1544558432, "last_setup": 1544558432, "type": "NAMain", "last_status_store": 1559413181, "module_name": "NetatmoIndoor", "firmware": 137, "last_upgrade": 1544558433, "wifi_status": 45, "reachable": true, "co2_calibrating": false, "station_name": "MyStation", "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure" ], "place": { "altitude": 664, "city": "Frankfurt", "country": "DE", "timezone": "Europe/Berlin", "location": [ 52.516263, 13.377726 ] }, "dashboard_data": { "time_utc": 1559413171, "Temperature": 24.6, "CO2": 749, "Humidity": 36, "Noise": 37, "Pressure": 1017.3, "AbsolutePressure": 939.7, "min_temp": 23.4, "max_temp": 25.6, "date_min_temp": 1559371924, "date_max_temp": 1559411964, "temp_trend": "stable", "pressure_trend": "down" }, "modules": [ { "_id": "12:34:56:36:fc:de", "type": "NAModule1", "module_name": "NetatmoOutdoor", "data_type": [ "Temperature", "Humidity" ], "last_setup": 1544558433, "reachable": true, "dashboard_data": { "time_utc": 1559413157, "Temperature": 28.6, "Humidity": 24, "min_temp": 16.9, "max_temp": 30.3, "date_min_temp": 1559365579, "date_max_temp": 1559404698, "temp_trend": "down" }, "firmware": 46, "last_message": 1559413177, "last_seen": 1559413157, "rf_status": 65, "battery_vp": 5738, "battery_percent": 87 }, { "_id": "12:34:56:07:bb:3e", "type": "NAModule4", "module_name": "Kitchen", "data_type": [ "Temperature", "CO2", "Humidity" ], "last_setup": 1548956696, "reachable": true, "dashboard_data": { "time_utc": 1559413125, "Temperature": 28, "CO2": 503, "Humidity": 26, "min_temp": 25, "max_temp": 28, "date_min_temp": 1559371577, "date_max_temp": 1559412561, "temp_trend": "up" }, "firmware": 44, "last_message": 1559413177, "last_seen": 1559413177, "rf_status": 73, "battery_vp": 5687, "battery_percent": 83 }, { "_id": "12:34:56:07:bb:0e", "type": "NAModule4", "module_name": "Livingroom", "data_type": [ "Temperature", "CO2", "Humidity" ], "last_setup": 1548957209, "reachable": true, "dashboard_data": { "time_utc": 1559413093, "Temperature": 26.4, "CO2": 451, "Humidity": 31, "min_temp": 25.1, "max_temp": 26.4, "date_min_temp": 1559365290, "date_max_temp": 1559413093, "temp_trend": "stable" }, "firmware": 44, "last_message": 1559413177, "last_seen": 1559413093, "rf_status": 84, "battery_vp": 5626, "battery_percent": 79 }, { "_id": "12:34:56:03:1b:e4", "type": "NAModule2", "module_name": "Garden", "data_type": [ "Wind" ], "last_setup": 1549193862, "reachable": true, "dashboard_data": { "time_utc": 1559413170, "WindStrength": 4, "WindAngle": 217, "GustStrength": 9, "GustAngle": 206, "max_wind_str": 21, "max_wind_angle": 217, "date_max_wind_str": 1559386669 }, "firmware": 19, "last_message": 1559413177, "last_seen": 1559413177, "rf_status": 59, "battery_vp": 5689, "battery_percent": 85 }, { "_id": "12:34:56:05:51:20", "type": "NAModule3", "module_name": "Yard", "data_type": [ "Rain" ], "last_setup": 1549194580, "reachable": true, "dashboard_data": { "time_utc": 1559413170, "Rain": 0, "sum_rain_24": 0, "sum_rain_1": 0 }, "firmware": 8, "last_message": 1559413177, "last_seen": 1559413170, "rf_status": 67, "battery_vp": 5860, "battery_percent": 93 } ] }, { "_id": "12:34:56:00:aa:01", "station_name": "MyRemoteStation", "date_setup": 1499189962, "last_setup": 1499189962, "type": "NAMain", "last_status_store": 1554506294, "module_name": "Indoor", "firmware": 132, "last_upgrade": 1499189915, "wifi_status": 46, "reachable": false, "co2_calibrating": false, "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure" ], "place": { "altitude": 6, "city": "Harstad", "country": "NO", "timezone": "Europe/Oslo", "location": [ 59.895000, 10.620000 ] }, "modules": [ { "_id": "12:34:56:00:aa:02", "type": "NAModule1", "module_name": "Outdoor", "data_type": [ "Temperature", "Humidity" ], "last_setup": 1499189902, "battery_percent": 17, "reachable": false, "firmware": 44, "last_message": 1536805739, "last_seen": 1536696388, "rf_status": 87, "battery_vp": 4018, "main_device": "12:34:56:00:aa:01" }, { "_id": "12:34:56:00:aa:03", "type": "NAModule2", "module_name": "Wind Gauge", "data_type": [ "Wind" ], "last_setup": 1499190606, "battery_percent": 3, "reachable": false, "firmware": 18, "last_message": 1537259554, "last_seen": 1537259554, "rf_status": 74, "battery_vp": 4013, "main_device": "12:34:56:00:aa:01" } ] } ], "user": { "mail": "john@doe.com", "administrative": { "lang": "de-DE", "reg_locale": "de-DE", "country": "DE", "unit": 0, "windunit": 0, "pressureunit": 0, "feel_like_algo": 0 } } }, "status": "ok", "time_exec": 0.91107702255249, "time_server": 1559413602 }pyatmo-9.2.1/fixtures/archive/weatherstation_measure.json000066400000000000000000000014121501740523400240020ustar00rootroot00000000000000{ "body": { "1544558433": [ 28.1 ], "1544558449": [ 28.4 ], "1544558504": [ 27 ], "1544558807": [ 24 ], "1544559062": [ 23.8 ], "1544559211": [ 26.1 ], "1544559308": [ 24.9 ], "1544559415": [ 24.6 ], "1544559576": [ 24.2 ], "1544559974": [ 26.9 ], "1544560021": [ 27.1 ], "1544560058": [ 27.4 ], "1544560361": [ 26 ] }, "status": "ok", "time_exec": 0.33915495872498, "time_server": 1560590041 }pyatmo-9.2.1/fixtures/getevents.json000066400000000000000000000151741501740523400176150ustar00rootroot00000000000000{ "body": { "home": { "id": "91763b24c43d3e344f424e8b", "events": [ { "id": "11111111111111111f7763a6d", "type": "outdoor", "time": 1645794709, "module_id": "12:34:56:10:b9:0e", "video_id": "11111111-2222-3333-4444-b42f0fc4cfad", "video_status": "available", "subevents": [ { "id": "11111111-2222-3333-4444-013560107fce", "type": "human", "time": 1645794709, "verified": true, "offset": 0, "snapshot": { "url": "https://netatmocameraimage.blob.core.windows.net/production/000000a722374" }, "vignette": { "url": "https://netatmocameraimage.blob.core.windows.net/production/0000009625c0f" }, "message": "Person erfasst" }, { "id": "11111111-2222-3333-4444-0b0bc962df43", "type": "vehicle", "time": 1645794716, "verified": true, "offset": 15, "snapshot": { "url": "https://netatmocameraimage.blob.core.windows.net/production/00000033f9f96" }, "vignette": { "url": "https://netatmocameraimage.blob.core.windows.net/production/000000cba08af" }, "message": "Fahrzeug erfasst" }, { "id": "11111111-2222-3333-4444-129e72195968", "type": "human", "time": 1645794716, "verified": true, "offset": 15, "snapshot": { "filename": "vod/11111/events/22222/snapshot_129e72195968.jpg" }, "vignette": { "filename": "vod/11111/events/22222/vignette_129e72195968.jpg" }, "message": "Person erfasst" }, { "id": "11111111-2222-3333-4444-dae4d7e4f24e", "type": "human", "time": 1645794718, "verified": true, "offset": 17, "snapshot": { "filename": "vod/11111/events/22222/snapshot_dae4d7e4f24e.jpg" }, "vignette": { "filename": "vod/11111/events/22222/vignette_dae4d7e4f24e.jpg" }, "message": "Person erfasst" } ] }, { "id": "1111111111111111e7e40c353", "type": "connection", "time": 1645784799, "module_id": "12:34:56:10:b9:0e", "message": "Front verbunden" }, { "id": "11111111111111144e3115860", "type": "boot", "time": 1645784775, "module_id": "12:34:56:10:b9:0e", "message": "Front gestartet" }, { "id": "11111111111111169804049ca", "type": "disconnection", "time": 1645773806, "module_id": "12:34:56:10:b9:0e", "message": "Front getrennt" }, { "id": "1111111111111117cb8147ffd", "type": "outdoor", "time": 1645712826, "module_id": "12:34:56:10:b9:0e", "video_id": "11111111-2222-3333-4444-5091e1903f8d", "video_status": "available", "subevents": [ { "id": "11111111-2222-3333-4444-b7d28e3ccc38", "type": "human", "time": 1645712826, "verified": true, "offset": 0, "snapshot": { "url": "https://netatmocameraimage.blob.core.windows.net/production/000000a0ca642" }, "vignette": { "url": "https://netatmocameraimage.blob.core.windows.net/production/00000031b0ed4" }, "message": "Person erfasst" } ] }, { "id": "1111111111111119df3d2de6", "type": "person_home", "time": 1645902000, "module_id": "12:34:56:00:f1:62", "message": "Home Assistant Cloud definiert John Doe und Jane Doe als \"Zu Hause\"" }, { "id": "1111111111111112c91b3628", "type": "person", "time": 1645901266, "module_id": "12:34:56:00:f1:62", "snapshot": { "url": "https://netatmocameraimage.blob.core.windows.net/production/0000081d4f42875d9" }, "video_id": "11111111-2222-3333-4444-314d161525db", "video_status": "available", "message": "John Doe gesehen", "person_id": "91827374-7e04-5298-83ad-a0cb8372dff1", "out_of_sight": false }, { "id": "1111111111111115166b1283", "type": "tag_open", "time": 1645897638, "module_id": "12:34:56:00:86:99", "message": "Window Hall: immer noch offen" } ] } }, "status": "ok", "time_exec": 0.24369096755981445, "time_server": 1645897231 }pyatmo-9.2.1/fixtures/gethomecoachsdata.json000066400000000000000000000153641501740523400212550ustar00rootroot00000000000000{ "body": { "devices": [ { "_id": "12:34:56:26:69:0c", "cipher_id": "enc:16:1UqwQlYV5AY2pfyEi5H47dmmFOOL3mCUo+KAkchL4A2CLI5u0e45Xr5jeAswO+XO", "date_setup": 1544560184, "last_setup": 1544560184, "type": "NHC", "last_status_store": 1558268332, "firmware": 45, "last_upgrade": 1544560186, "wifi_status": 58, "reachable": false, "co2_calibrating": false, "station_name": "Bedroom", "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure", "health_idx" ], "place": { "city": "Frankfurt", "country": "DE", "timezone": "Europe/Berlin", "location": [ 52.516263, 13.377726 ] } }, { "_id": "12:34:56:25:cf:a8", "cipher_id": "enc:16:A+Jm0yFWBwUyKinFDutPZK7I2PuHN1fqaE9oB/KF+McbFs3oN9CKpR/dYbqL4om2", "date_setup": 1544562192, "last_setup": 1544562192, "type": "NHC", "last_status_store": 1559198922, "firmware": 45, "last_upgrade": 1544562194, "wifi_status": 41, "reachable": true, "co2_calibrating": false, "station_name": "Kitchen", "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure", "health_idx" ], "place": { "city": "Frankfurt", "country": "DE", "timezone": "Europe/Berlin", "location": [ 52.516263, 13.377726 ] } }, { "_id": "12:34:56:26:65:14", "cipher_id": "enc:16:7kK6ZzG4L7NgfZZ6+dMvNxw4l6vXu+88SEJkCUklNdPa4KYIHmsfa1moOilEK61i", "date_setup": 1544564061, "last_setup": 1544564061, "type": "NHC", "last_status_store": 1559067159, "firmware": 45, "last_upgrade": 1544564302, "wifi_status": 66, "reachable": true, "co2_calibrating": false, "station_name": "Livingroom", "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure", "health_idx" ], "place": { "city": "Frankfurt", "country": "DE", "timezone": "Europe/Berlin", "location": [ 52.516263, 13.377726 ] } }, { "_id": "12:34:56:3e:c5:46", "station_name": "Parents Bedroom", "date_setup": 1570732241, "last_setup": 1570732241, "type": "NHC", "last_status_store": 1572073818, "module_name": "Indoor", "firmware": 45, "wifi_status": 67, "reachable": true, "co2_calibrating": false, "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure", "health_idx" ], "place": { "city": "Frankfurt", "country": "DE", "timezone": "Europe/Berlin", "location": [ 52.516263, 13.377726 ] }, "dashboard_data": { "time_utc": 1572073816, "Temperature": 20.3, "CO2": 494, "Humidity": 63, "Noise": 42, "Pressure": 1014.5, "AbsolutePressure": 1004.1, "health_idx": 1, "min_temp": 20.3, "max_temp": 21.6, "date_max_temp": 1572059333, "date_min_temp": 1572073816 } }, { "_id": "12:34:56:26:68:92", "station_name": "Baby Bedroom", "date_setup": 1571342643, "last_setup": 1571342643, "type": "NHC", "last_status_store": 1572073995, "module_name": "Indoor", "firmware": 45, "wifi_status": 68, "reachable": true, "co2_calibrating": false, "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure", "health_idx" ], "place": { "city": "Frankfurt", "country": "DE", "timezone": "Europe/Berlin", "location": [ 52.516263, 13.377726 ] }, "dashboard_data": { "time_utc": 1572073994, "Temperature": 21.6, "CO2": 1053, "Humidity": 66, "Noise": 45, "Pressure": 1021.4, "AbsolutePressure": 1011, "health_idx": 1, "min_temp": 20.9, "max_temp": 21.6, "date_max_temp": 1572073690, "date_min_temp": 1572064254 } } ], "user": { "mail": "john@doe.com", "administrative": { "lang": "de-DE", "reg_locale": "de-DE", "country": "DE", "unit": 0, "windunit": 0, "pressureunit": 0, "feel_like_algo": 0 } } }, "status": "ok", "time_exec": 0.095954179763794, "time_server": 1559463229 }1c1d1694c91210991f1b006755f6bde04cf29a93.paxheader00006660000000000000000000000261150174052340020266xustar00rootroot00000000000000177 path=pyatmo-9.2.1/fixtures/getmeasure_sum_energy_buy_from_grid,sum_energy_buy_from_grid$0,sum_energy_buy_from_grid$1,sum_energy_buy_from_grid$2_12_34_56_00_00_a1_4c_da.json 1c1d1694c91210991f1b006755f6bde04cf29a93.data000066400000000000000000000315701501740523400171330ustar00rootroot00000000000000{ "body": [ { "beg_time": 1644049789, "step_time": 3600, "value": [ [ null, 197 ,null, null], [null, 262 ,null, null], [null, 168 ,null, null], [null, 219 ,null, null], [null, 224 ,null, null], [null, 299 ,null, null], [null, 343 ,null, null], [null, 443 ,null, null], [null, 317 ,null, null], [null, 229 ,null, null], [null, 147 ,null, null], [null, 178 ,null, null], [null, 340 ,null, null], [null, 536 ,null, null], [null, 471 ,null, null], [null, 397 ,null, null], [null, 290 ,null, null], [null, 302 ,null, null], [null, 309 ,null, null], [null, 219 ,null, null], [null, 154 ,null, null], [null, 163 ,null, null], [null, 146 ,null, null], [null, 189 ,null, null], [null, 256 ,null, null], [null, 162 ,null, null], [null, 1288 ,null, null], [null, 256 ,null, null], [null, 709 ,null, null], [null, 310 ,null, null], [null, 379 ,null, null], [null, 296 ,null, null], [null, 230 ,null, null], [null, 505 ,null, null], [null, 362 ,null, null], [null, 611 ,null, null], [null, 597 ,null, null], [null, 505 ,null, null], [null, 431 ,null, null], [null, 1538 ,null, null], [null, 265 ,null, null], [null, 187 ,null, null], [null, 162 ,null, null], [null, 150 ,null, null], [null, 155 ,null, null], [null, 147 ,null, null], [null, 211 ,null, null], [null, 211 ,null, null], [null, 272 ,null, null], [null, 271 ,null, null], [null, 331 ,null, null], [null, 180 ,null, null], [null, 184 ,null, null], [null, 182 ,null, null], [null, 232 ,null, null], [null, 288 ,null, null], [null, 266 ,null, null], [null, 256 ,null, null], [null, 249 ,null, null], [null, 372 ,null, null], [null, 379 ,null, null], [null, 585 ,null, null], [null, 387 ,null, null], [null, 277 ,null, null], [null, 223 ,null, null], [null, 202 ,null, null], [null, 163 ,null, null], [null, 143 ,null, null], [null, 158 ,null, null], [null, 145 ,null, null], [null, 232 ,null, null], [null, 231 ,null, null], [null, 160 ,null, null], [null, 261 ,null, null], [null, 376 ,null, null], [null, 216 ,null, null], [null, 202 ,null, null], [null, 295 ,null, null], [null, 310 ,null, null], [null, 235 ,null, null], [null, 188 ,null, null], [null, 269 ,null, null], [null, 250 ,null, null], [null, 334 ,null, null], [null, 434 ,null, null], [null, 353 ,null, null], [null, 279 ,null, null], [null, 266 ,null, null], [null, 226 ,null, null], [null, 179 ,null, null], [null, 149 ,null, null], [null, 146 ,null, null], [null, 143 ,null, null], [null, 136 ,null, null], [null, 173 ,null, null], [null, 221 ,null, null], [null, 190 ,null, null], [null, 177 ,null, null], [null, 290 ,null, null], [null, 352 ,null, null], [null, 252 ,null, null], [null, 284 ,null, null], [null, 173 ,null, null], [null, 165 ,null, null], [null, 144 ,null, null], [null, 175 ,null, null], [null, 268 ,null, null], [null, 363 ,null, null], [null, 544 ,null, null], [null, 515 ,null, null], [null, 525 ,null, null], [null, 431 ,null, null], [null, 225 ,null, null], [null, 183 ,null, null], [null, 178 ,null, null], [null, 155 ,null, null], [null, 170 ,null, null], [null, 156 ,null, null], [null, 169 ,null, null], [null, 226 ,null, null], [null, 255 ,null, null], [null, 273 ,null, null], [null, 466 ,null, null], [null, 406 ,null, null], [null, 333 ,null, null], [null, 194 ,null, null], [null, 234 ,null, null], [null, 271 ,null, null], [null, 238 ,null, null], [null, 221 ,null, null], [null, 205 ,null, null], [null, 258 ,null, null], [null, 430 ,null, null], [null, 446 ,null, null], [null, 390 ,null, null], [null, 306 ,null, null], [null, 223 ,null, null], [null, 165 ,null, null], [null, 154 ,null, null], [null, 147 ,null, null], [null, 155 ,null, null], [null, 140 ,null, null], [null, 153 ,null, null], [null, 228 ,null, null], [null, 237 ,null, null], [null, 201 ,null, null], [null, 183 ,null, null], [null, 194 ,null, null], [null, 135 ,null, null], [null, 206 ,null, null], [null, 215 ,null, null], [null, 147 ,null, null], [null, 159 ,null, null], [null, 185 ,null, null], [null, 168 ,null, null], [null, 257 ,null, null], [null, 262 ,null, null], [null, 141 ,null, null], [null, 151 ,null, null], [null, 157 ,null, null], [null, 133 ,null, null], [null, 147 ,null, null], [null, 135 ,null, null], [null, 139 ,null, null], [null, 136 ,null, null], [null, 127 ,null, null], [null, 169 ,null, null], [null, 259, null, null ] ] } ], "status": "ok", "time_exec": 0.5533828735351562, "time_server": 1647935044 } 3e11402ef9fbb9a2e47a347e9c1af2d87701f522.paxheader00006660000000000000000000000261150174052340020510xustar00rootroot00000000000000177 path=pyatmo-9.2.1/fixtures/getmeasure_sum_energy_buy_from_grid,sum_energy_buy_from_grid$0,sum_energy_buy_from_grid$1,sum_energy_buy_from_grid$2_98_76_54_32_10_00_00_69.json 3e11402ef9fbb9a2e47a347e9c1af2d87701f522.data000066400000000000000000000065261501740523400173600ustar00rootroot00000000000000{ "body": [ { "beg_time": 1721772900, "step_time": 1800, "value": [ [ null, 20, null, null ], [ null, 19, null, null ], [ null, 16, null, null ], [ null, 11, null, null ], [ null, 18, null, null ], [ null, 14, null, null ], [ null, 14, null, null ], [ null, 64, null, null ], [ null, 100, null, null ], [ null, 58, null, null ], [ null, 39, null, null ], [ null, 24, null, null ], [ null, 19, null, null ], [ null, 19, null, null ], [ null, 712, null, null ], [ null, 724, null, null ], [ null, 711, null, null ], [ null, 498, 212, null ], [ null, null, 717, null ], [ null, null, 714, null ], [ null, null, 714, null ], [ null, null, 711, null ], [ null, null, 706, null ], [ null, null, 704, null ], [ null, null, 706, null ], [ null, null, 709, null ], [ null, null, 714, null ], [ null, null, 712, null ], [ null, null, 238, 477 ], [ null, null, null, 714 ], [ null, null, null, 722 ], [ null, null, null, 713 ], [ null, null, null, 709 ], [ null, null, null, 714 ], [ null, null, 477, 241 ], [ null, null, 710, null ], [ null, null, 710, null ], [ null, null, 707, null ], [ null, null, 16, null ] ] } ], "status": "ok", "time_exec": 0.025647878646850586, "time_server": 1721852913 }pyatmo-9.2.1/fixtures/getpublicdata.json000066400000000000000000000157671501740523400204310ustar00rootroot00000000000000{ "status": "ok", "time_server": 1560248397, "time_exec": 0, "body": [ { "_id": "70:ee:50:36:94:7c", "place": { "location": [8.791382999999996, 50.2136394], "timezone": "Europe/Berlin", "country": "DE", "altitude": 132 }, "mark": 14, "measures": { "02:00:00:36:f2:94": { "res": { "1560248022": [21.4, 62] }, "type": ["temperature", "humidity"] }, "70:ee:50:36:94:7c": { "res": { "1560248030": [1010.6] }, "type": ["pressure"] }, "05:00:00:05:33:84": { "rain_60min": 0.2, "rain_24h": 12.322000000000001, "rain_live": 0.5, "rain_timeutc": 1560248022 } }, "modules": ["05:00:00:05:33:84", "02:00:00:36:f2:94"], "module_types": { "05:00:00:05:33:84": "NAModule3", "02:00:00:36:f2:94": "NAModule1" } }, { "_id": "70:ee:50:1f:68:9e", "place": { "location": [8.795445200000017, 50.2130169], "timezone": "Europe/Berlin", "country": "DE", "altitude": 125 }, "mark": 14, "measures": { "02:00:00:1f:82:28": { "res": { "1560248312": [21.1, 69] }, "type": ["temperature", "humidity"] }, "70:ee:50:1f:68:9e": { "res": { "1560248344": [1007.3] }, "type": ["pressure"] }, "05:00:00:02:bb:6e": { "rain_60min": 0, "rain_24h": 9.999, "rain_live": 0, "rain_timeutc": 1560248344 } }, "modules": ["02:00:00:1f:82:28", "05:00:00:02:bb:6e"], "module_types": { "02:00:00:1f:82:28": "NAModule1", "05:00:00:02:bb:6e": "NAModule3" } }, { "_id": "70:ee:50:27:25:b0", "place": { "location": [8.7807159, 50.1946167], "timezone": "Europe/Berlin", "country": "DE", "altitude": 112 }, "mark": 14, "measures": { "02:00:00:27:19:b2": { "res": { "1560247889": [23.2, 60] }, "type": ["temperature", "humidity"] }, "70:ee:50:27:25:b0": { "res": { "1560247907": [1012.8] }, "type": ["pressure"] }, "05:00:00:03:5d:2e": { "rain_60min": 0, "rain_24h": 11.716000000000001, "rain_live": 0, "rain_timeutc": 1560247896 } }, "modules": ["02:00:00:27:19:b2", "05:00:00:03:5d:2e"], "module_types": { "02:00:00:27:19:b2": "NAModule1", "05:00:00:03:5d:2e": "NAModule3" } }, { "_id": "70:ee:50:04:ed:7a", "place": { "location": [8.785034, 50.192169], "timezone": "Europe/Berlin", "country": "DE", "altitude": 112 }, "mark": 14, "measures": { "02:00:00:04:c2:2e": { "res": { "1560248137": [19.8, 76] }, "type": ["temperature", "humidity"] }, "70:ee:50:04:ed:7a": { "res": { "1560248152": [1005.4] }, "type": ["pressure"] } }, "modules": ["02:00:00:04:c2:2e"], "module_types": { "02:00:00:04:c2:2e": "NAModule1" } }, { "_id": "70:ee:50:27:9f:2c", "place": { "location": [8.785342, 50.193573], "timezone": "Europe/Berlin", "country": "DE", "altitude": 116 }, "mark": 1, "measures": { "02:00:00:27:aa:70": { "res": { "1560247821": [25.5, 56] }, "type": ["temperature", "humidity"] }, "70:ee:50:27:9f:2c": { "res": { "1560247853": [1010.6] }, "type": ["pressure"] } }, "modules": ["02:00:00:27:aa:70"], "module_types": { "02:00:00:27:aa:70": "NAModule1" } }, { "_id": "70:ee:50:01:20:fa", "place": { "location": [8.7953, 50.195241], "timezone": "Europe/Berlin", "country": "DE", "altitude": 119 }, "mark": 1, "measures": { "02:00:00:00:f7:ba": { "res": { "1560247831": [27.4, 58] }, "type": ["temperature", "humidity"] }, "70:ee:50:01:20:fa": { "res": { "1560247876": [1014.4] }, "type": ["pressure"] } }, "modules": ["02:00:00:00:f7:ba"], "module_types": { "02:00:00:00:f7:ba": "NAModule1" } }, { "_id": "70:ee:50:3c:02:78", "place": { "location": [8.795953681700666, 50.19530139868166], "timezone": "Europe/Berlin", "country": "DE", "altitude": 119 }, "mark": 7, "measures": { "02:00:00:3c:21:f2": { "res": { "1560248225": [23.3, 58] }, "type": ["temperature", "humidity"] }, "70:ee:50:3c:02:78": { "res": { "1560248270": [1011.7] }, "type": ["pressure"] } }, "modules": ["02:00:00:3c:21:f2"], "module_types": { "02:00:00:3c:21:f2": "NAModule1" } }, { "_id": "70:ee:50:36:a9:fc", "place": { "location": [8.801164269110814, 50.19596181704958], "timezone": "Europe/Berlin", "country": "DE", "altitude": 113 }, "mark": 14, "measures": { "02:00:00:36:a9:50": { "res": { "1560248145": [20.1, 67] }, "type": ["temperature", "humidity"] }, "70:ee:50:36:a9:fc": { "res": { "1560248191": [1010] }, "type": ["pressure"] }, "05:00:00:02:92:82": { "rain_60min": 0, "rain_24h": 11.009, "rain_live": 0, "rain_timeutc": 1560248184 }, "06:00:00:03:19:76": { "wind_strength": 15, "wind_angle": 17, "gust_strength": 31, "gust_angle": 217, "wind_timeutc": 1560248190 } }, "modules": [ "05:00:00:02:92:82", "02:00:00:36:a9:50", "06:00:00:03:19:76" ], "module_types": { "05:00:00:02:92:82": "NAModule3", "02:00:00:36:a9:50": "NAModule1", "06:00:00:03:19:76": "NAModule2" } } ] } pyatmo-9.2.1/fixtures/getstationsdata.json000066400000000000000000000512741501740523400210100ustar00rootroot00000000000000{ "body": { "devices": [ { "_id": "12:34:56:37:11:ca", "cipher_id": "enc:16:zjiZF/q8jTScXVdDa/kvhUAIUPGeYszaD1ClEf8byAJkRjxc5oth7cAocrMUIApX", "date_setup": 1544558432, "last_setup": 1544558432, "type": "NAMain", "last_status_store": 1559413181, "module_name": "NetatmoIndoor", "firmware": 137, "last_upgrade": 1544558433, "wifi_status": 45, "reachable": true, "co2_calibrating": false, "station_name": "MyStation", "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure" ], "place": { "altitude": 664, "city": "Frankfurt", "country": "DE", "timezone": "Europe/Berlin", "location": [ 52.516263, 13.377726 ] }, "dashboard_data": { "time_utc": 1559413171, "Temperature": 24.6, "CO2": 749, "Humidity": 36, "Noise": 37, "Pressure": 1017.3, "AbsolutePressure": 939.7, "min_temp": 23.4, "max_temp": 25.6, "date_min_temp": 1559371924, "date_max_temp": 1559411964, "temp_trend": "stable", "pressure_trend": "down" }, "modules": [ { "_id": "12:34:56:36:fc:de", "type": "NAModule1", "module_name": "NetatmoOutdoor", "data_type": [ "Temperature", "Humidity" ], "last_setup": 1544558433, "reachable": true, "dashboard_data": { "time_utc": 1559413157, "Temperature": 28.6, "Humidity": 24, "min_temp": 16.9, "max_temp": 30.3, "date_min_temp": 1559365579, "date_max_temp": 1559404698, "temp_trend": "down" }, "firmware": 46, "last_message": 1559413177, "last_seen": 1559413157, "rf_status": 65, "battery_vp": 5738, "battery_percent": 87 }, { "_id": "12:34:56:07:bb:3e", "type": "NAModule4", "module_name": "Kitchen", "data_type": [ "Temperature", "CO2", "Humidity" ], "last_setup": 1548956696, "reachable": true, "dashboard_data": { "time_utc": 1559413125, "Temperature": 28, "CO2": 503, "Humidity": 26, "min_temp": 25, "max_temp": 28, "date_min_temp": 1559371577, "date_max_temp": 1559412561, "temp_trend": "up" }, "firmware": 44, "last_message": 1559413177, "last_seen": 1559413177, "rf_status": 73, "battery_vp": 5687, "battery_percent": 83 }, { "_id": "12:34:56:07:bb:0e", "type": "NAModule4", "module_name": "Livingroom", "data_type": [ "Temperature", "CO2", "Humidity" ], "last_setup": 1548957209, "reachable": true, "dashboard_data": { "time_utc": 1559413093, "Temperature": 26.4, "CO2": 451, "Humidity": 31, "min_temp": 25.1, "max_temp": 26.4, "date_min_temp": 1559365290, "date_max_temp": 1559413093, "temp_trend": "stable" }, "firmware": 44, "last_message": 1559413177, "last_seen": 1559413093, "rf_status": 84, "battery_vp": 5626, "battery_percent": 79 }, { "_id": "12:34:56:03:1b:e5", "type": "NAModule2", "module_name": "Garden", "data_type": [ "Wind" ], "last_setup": 1549193862, "reachable": true, "dashboard_data": { "time_utc": 1559413170, "WindStrength": 4, "WindAngle": 217, "GustStrength": 9, "GustAngle": 206, "max_wind_str": 21, "max_wind_angle": 217, "date_max_wind_str": 1559386669 }, "firmware": 19, "last_message": 1559413177, "last_seen": 1559413177, "rf_status": 59, "battery_vp": 5689, "battery_percent": 85 }, { "_id": "12:34:56:05:51:20", "type": "NAModule3", "module_name": "Yard", "data_type": [ "Rain" ], "last_setup": 1549194580, "reachable": true, "dashboard_data": { "time_utc": 1559413170, "Rain": 0, "sum_rain_24": 0, "sum_rain_1": 0 }, "firmware": 8, "last_message": 1559413177, "last_seen": 1559413170, "rf_status": 67, "battery_vp": 5860, "battery_percent": 93 } ] }, { "_id": "12 :34: 56:36:fd:3c", "station_name": "Valley Road", "date_setup": 1545897146, "last_setup": 1545897146, "type": "NAMain", "last_status_store": 1581835369, "firmware": 137, "last_upgrade": 1545897125, "wifi_status": 53, "reachable": true, "co2_calibrating": false, "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure" ], "place": { "altitude": 69, "city": "Valley", "country": "AU", "timezone": "Australia/Hobart", "location": [ 148.444226, -41.721282 ] }, "read_only": true, "dashboard_data": { "time_utc": 1581835330, "Temperature": 22.4, "CO2": 471, "Humidity": 46, "Noise": 47, "Pressure": 1011.5, "AbsolutePressure": 1002.8, "min_temp": 18.1, "max_temp": 22.5, "date_max_temp": 1581829891, "date_min_temp": 1581794878, "temp_trend": "stable", "pressure_trend": "stable" }, "modules": [ { "_id": "12 :34: 56:36:e6:c0", "type": "NAModule1", "module_name": "Module", "data_type": [ "Temperature", "Humidity" ], "last_setup": 1545897146, "battery_percent": 22, "reachable": false, "firmware": 46, "last_message": 1572497781, "last_seen": 1572497742, "rf_status": 88, "battery_vp": 4118 }, { "_id": "12:34:56:05:25:6e", "type": "NAModule3", "module_name": "Rain Gauge", "data_type": [ "Rain" ], "last_setup": 1553997427, "battery_percent": 82, "reachable": true, "firmware": 8, "last_message": 1581835362, "last_seen": 1581835354, "rf_status": 78, "battery_vp": 5594, "dashboard_data": { "time_utc": 1581835329, "Rain": 0, "sum_rain_1": 0, "sum_rain_24": 0 } } ] }, { "_id": "12:34:56:32:a7:60", "home_name": "Ateljen", "date_setup": 1566714693, "last_setup": 1566714693, "type": "NAMain", "last_status_store": 1588481079, "module_name": "Indoor", "firmware": 177, "last_upgrade": 1566714694, "wifi_status": 50, "reachable": true, "co2_calibrating": false, "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure" ], "place": { "altitude": 93, "city": "Gothenburg", "country": "SE", "timezone": "Europe/Stockholm", "location": [ 11.6136629, 57.7006827 ] }, "dashboard_data": { "time_utc": 1588481073, "Temperature": 18.2, "CO2": 542, "Humidity": 45, "Noise": 45, "Pressure": 1013, "AbsolutePressure": 1001.9, "min_temp": 18.2, "max_temp": 19.5, "date_max_temp": 1588456861, "date_min_temp": 1588479561, "temp_trend": "stable", "pressure_trend": "up" }, "modules": [ { "_id": "12:34:56:32:db:06", "type": "NAModule1", "last_setup": 1587635819, "data_type": [ "Temperature", "Humidity" ], "battery_percent": 100, "reachable": false, "firmware": 255, "last_message": 0, "last_seen": 0, "rf_status": 255, "battery_vp": 65535 } ] }, { "_id": "12:34:56:1c:68:2e", "station_name": "Bol\u00e5s", "date_setup": 1470935400, "last_setup": 1470935400, "type": "NAMain", "last_status_store": 1588481399, "module_name": "Inne - Nere", "firmware": 177, "last_upgrade": 1470935401, "wifi_status": 13, "reachable": true, "co2_calibrating": false, "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure" ], "place": { "altitude": 93, "city": "Gothenburg", "country": "SE", "timezone": "Europe/Stockholm", "location": [ 11.6136629, 57.7006827 ] }, "dashboard_data": { "time_utc": 1588481387, "Temperature": 20.8, "CO2": 674, "Humidity": 41, "Noise": 34, "Pressure": 1012.1, "AbsolutePressure": 1001, "min_temp": 20.8, "max_temp": 22.2, "date_max_temp": 1588456859, "date_min_temp": 1588480176, "temp_trend": "stable", "pressure_trend": "up" }, "modules": [ { "_id": "12:34:56:02:b3:da", "type": "NAModule3", "module_name": "Regnm\u00e4tare", "last_setup": 1470937706, "data_type": [ "Rain" ], "battery_percent": 81, "reachable": true, "firmware": 12, "last_message": 1588481393, "last_seen": 1588481386, "rf_status": 67, "battery_vp": 5582, "dashboard_data": { "time_utc": 1588481386, "Rain": 0, "sum_rain_1": 0, "sum_rain_24": 0.1 } }, { "_id": "12:34:56:03:76:60", "type": "NAModule4", "module_name": "Inne - Uppe", "last_setup": 1470938089, "data_type": [ "Temperature", "CO2", "Humidity" ], "battery_percent": 14, "reachable": true, "firmware": 50, "last_message": 1588481393, "last_seen": 1588481374, "rf_status": 70, "battery_vp": 4448, "dashboard_data": { "time_utc": 1588481374, "Temperature": 19.6, "CO2": 696, "Humidity": 41, "min_temp": 19.6, "max_temp": 20.5, "date_max_temp": 1588456817, "date_min_temp": 1588481374, "temp_trend": "stable" } }, { "_id": "12:34:56:32:db:06", "type": "NAModule1", "module_name": "Ute", "last_setup": 1566326027, "data_type": [ "Temperature", "Humidity" ], "battery_percent": 81, "reachable": true, "firmware": 50, "last_message": 1588481393, "last_seen": 1588481380, "rf_status": 61, "battery_vp": 5544, "dashboard_data": { "time_utc": 1588481380, "Temperature": 6.4, "Humidity": 91, "min_temp": 3.6, "max_temp": 6.4, "date_max_temp": 1588481380, "date_min_temp": 1588471383, "temp_trend": "up" } } ] }, { "_id": "12:34:56:1d:68:2e", "date_setup": 1470935500, "last_setup": 1470935500, "type": "NAMain", "last_status_store": 1588481399, "module_name": "Basisstation", "firmware": 177, "last_upgrade": 1470935401, "wifi_status": 13, "reachable": true, "co2_calibrating": false, "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure" ], "place": { "altitude": 93, "city": "Gothenburg", "country": "SE", "timezone": "Europe/Stockholm", "location": [ 11.6136629, 57.7006827 ] }, "dashboard_data": { "time_utc": 1588481387, "Temperature": 20.8, "CO2": 674, "Humidity": 41, "Noise": 34, "Pressure": 1012.1, "AbsolutePressure": 1001, "min_temp": 20.8, "max_temp": 22.2, "date_max_temp": 1588456859, "date_min_temp": 1588480176, "temp_trend": "stable", "pressure_trend": "up" }, "modules": [] }, { "_id": "12:34:56:80:bb:26", "station_name": "MYHOME (Palier)", "date_setup": 1558709904, "last_setup": 1558709904, "type": "NAMain", "last_status_store": 1644582700, "module_name": "Palier", "firmware": 181, "last_upgrade": 1558709906, "wifi_status": 57, "reachable": true, "co2_calibrating": false, "data_type": [ "Temperature", "CO2", "Humidity", "Noise", "Pressure" ], "place": { "altitude": 329, "city": "Someplace", "country": "FR", "timezone": "Europe/Paris", "location": [ 6.1234567, 46.123456 ] }, "home_id": "91763b24c43d3e344f424e8b", "home_name": "MYHOME", "dashboard_data": { "time_utc": 1644582694, "Temperature": 21.1, "CO2": 1339, "Humidity": 45, "Noise": 35, "Pressure": 1026.8, "AbsolutePressure": 974.5, "min_temp": 21, "max_temp": 21.8, "date_max_temp": 1644534255, "date_min_temp": 1644550420, "temp_trend": "stable", "pressure_trend": "up" }, "modules": [ { "_id": "12:34:56:80:1c:42", "type": "NAModule1", "module_name": "Outdoor", "last_setup": 1558709954, "data_type": [ "Temperature", "Humidity" ], "battery_percent": 27, "reachable": false, "firmware": 50, "last_message": 1644582699, "last_seen": 1644582699, "rf_status": 68, "battery_vp": 4678 }, { "_id": "12:34:56:80:c1:ea", "type": "NAModule3", "module_name": "Rain", "last_setup": 1563734531, "data_type": [ "Rain" ], "battery_percent": 21, "reachable": true, "firmware": 12, "last_message": 1644582699, "last_seen": 1644582699, "rf_status": 79, "battery_vp": 4256, "dashboard_data": { "time_utc": 1644582686, "Rain": 3.7, "sum_rain_1": 0, "sum_rain_24": 6.9 } }, { "_id": "12:34:56:80:44:92", "type": "NAModule4", "module_name": "Bedroom", "last_setup": 1575915890, "data_type": [ "Temperature", "CO2", "Humidity" ], "battery_percent": 28, "reachable": true, "firmware": 51, "last_message": 1644582699, "last_seen": 1644582654, "rf_status": 67, "battery_vp": 4695, "dashboard_data": { "time_utc": 1644582654, "Temperature": 19.3, "CO2": 1076, "Humidity": 53, "min_temp": 19.2, "max_temp": 19.7, "date_max_temp": 1644534243, "date_min_temp": 1644553418, "temp_trend": "stable" } }, { "_id": "12:34:56:80:7e:18", "type": "NAModule4", "module_name": "Bathroom", "last_setup": 1575915955, "data_type": [ "Temperature", "CO2", "Humidity" ], "battery_percent": 55, "reachable": true, "firmware": 51, "last_message": 1644582699, "last_seen": 1644582654, "rf_status": 59, "battery_vp": 5184, "dashboard_data": { "time_utc": 1644582654, "Temperature": 19.4, "CO2": 1930, "Humidity": 55, "min_temp": 19.4, "max_temp": 21.8, "date_max_temp": 1644534224, "date_min_temp": 1644582039, "temp_trend": "stable" } }, { "_id": "12:34:56:03:1b:e4", "type": "NAModule2", "module_name": "Garden", "data_type": [ "Wind" ], "last_setup": 1549193862, "reachable": true, "dashboard_data": { "time_utc": 1559413170, "WindStrength": 4, "WindAngle": 217, "GustStrength": 9, "GustAngle": 206, "max_wind_str": 21, "max_wind_angle": 217, "date_max_wind_str": 1559386669 }, "firmware": 19, "last_message": 1559413177, "last_seen": 1559413177, "rf_status": 59, "battery_vp": 5689, "battery_percent": 85 } ] }, { "_id": "00:11:22:2c:be:c8", "station_name": "Zuhause (Kinderzimmer)", "type": "NAMain", "last_status_store": 1649146022, "reachable": true, "favorite": true, "data_type": [ "Pressure" ], "place": { "altitude": 127, "city": "Wiesbaden", "country": "DE", "timezone": "Europe/Berlin", "location": [ 8.238054275512695, 50.07585525512695 ] }, "read_only": true, "dashboard_data": { "time_utc": 1649146022, "Pressure": 1015.6, "AbsolutePressure": 1000.4, "pressure_trend": "stable" }, "modules": [ { "_id": "00:11:22:2c:ce:b6", "type": "NAModule1", "data_type": [ "Temperature", "Humidity" ], "reachable": true, "last_message": 1649146022, "last_seen": 1649145996, "dashboard_data": { "time_utc": 1649145996, "Temperature": 7.8, "Humidity": 87, "min_temp": 6.5, "max_temp": 7.8, "date_max_temp": 1649145996, "date_min_temp": 1649118465, "temp_trend": "up" } } ] } ], "user": { "mail": "john@doe.com", "administrative": { "lang": "de-DE", "reg_locale": "de-DE", "country": "DE", "unit": 0, "windunit": 0, "pressureunit": 0, "feel_like_algo": 0 } } }, "status": "ok", "time_exec": 0.91107702255249, "time_server": 1559413602 } pyatmo-9.2.1/fixtures/home_multi_status_error_disconnected.json000066400000000000000000000003561501740523400253050ustar00rootroot00000000000000{ "status":"ok", "body":{ "errors":[ { "code":6, "id":"aa:aa:aa:aa:aa:aa" } ], "home":{ "id":"aaaaaaaaaaabbbbbbbbbbccc" } }, "time_server":1559292039 }pyatmo-9.2.1/fixtures/home_status_error_disconnected.json000066400000000000000000000003561501740523400240730ustar00rootroot00000000000000{ "status":"ok", "body":{ "errors":[ { "code":6, "id":"12:34:56:00:fa:d0" } ], "home":{ "id":"91763b24c43d3e344f424e8b" } }, "time_server":1559292039 }pyatmo-9.2.1/fixtures/home_status_error_invalid_schedule_id.json000066400000000000000000000001571501740523400254060ustar00rootroot00000000000000{ "error": { "code": 21, "message": "schedule is not therm schedule" } }pyatmo-9.2.1/fixtures/home_status_error_mode_is_missing.json000066400000000000000000000001211501740523400245670ustar00rootroot00000000000000{ "error": { "code": 10, "message": "mode is missing" } }pyatmo-9.2.1/fixtures/home_status_simple.json000066400000000000000000000102311501740523400215020ustar00rootroot00000000000000{ "status": "ok", "time_server": 1559292039, "body": { "home": { "modules": [ { "id": "12:34:56:00:f1:62", "type": "NACamera", "monitoring": "on", "sd_status": 4, "alim_status": 2, "locked": false, "vpn_url": "https://prodvpn-eu-2.netatmo.net/restricted/10.255.123.45/609e27de5699fb18147ab47d06846631/MTRPn_BeWCav5RBq4U1OMDruTW4dkQ0NuMwNDAw11g,,", "is_local": true }, { "id": "12:34:56:00:fa:d0", "type": "NAPlug", "firmware_revision": 174, "rf_strength": 107, "wifi_strength": 42 }, { "id": "12:34:56:00:01:ae", "reachable": true, "type": "NATherm1", "firmware_revision": 65, "rf_strength": 58, "battery_level": 3780, "boiler_valve_comfort_boost": false, "boiler_status": true, "anticipating": false, "bridge": "12:34:56:00:fa:d0", "battery_state": "high" }, { "id": "12:34:56:03:a5:54", "reachable": true, "type": "NRV", "firmware_revision": 79, "rf_strength": 51, "battery_level": 3025, "bridge": "12:34:56:00:fa:d0", "battery_state": "full" }, { "id": "12:34:56:03:a0:ac", "reachable": true, "type": "NRV", "firmware_revision": 79, "rf_strength": 59, "battery_level": 3029, "bridge": "12:34:56:00:fa:d0", "battery_state": "full" } ], "rooms": [ { "id": "2746182631", "reachable": true, "therm_measured_temperature": 19.8, "therm_setpoint_temperature": 12, "therm_setpoint_mode": "away", "therm_setpoint_start_time": 1559229567, "therm_setpoint_end_time": 0 }, { "id": "2940411577", "reachable": true, "therm_measured_temperature": 27, "heating_power_request": 0, "therm_setpoint_temperature": 7, "therm_setpoint_mode": "hg", "therm_setpoint_start_time": 0, "therm_setpoint_end_time": 0, "anticipating": false, "open_window": false }, { "id": "2833524037", "reachable": true, "therm_measured_temperature": 24.5, "heating_power_request": 0, "therm_setpoint_temperature": 7, "therm_setpoint_mode": "hg", "therm_setpoint_start_time": 0, "therm_setpoint_end_time": 0, "anticipating": false, "open_window": false } ], "id": "91763b24c43d3e344f424e8b", "persons": [ { "id": "91827374-7e04-5298-83ad-a0cb8372dff1", "last_seen": 1557071156, "out_of_sight": true }, { "id": "91827375-7e04-5298-83ae-a0cb8372dff2", "last_seen": 1559282761, "out_of_sight": false }, { "id": "91827376-7e04-5298-83af-a0cb8372dff3", "last_seen": 1559224132, "out_of_sight": true } ] } } }pyatmo-9.2.1/fixtures/homesdata.json000066400000000000000000000704751501740523400175630ustar00rootroot00000000000000{ "body": { "homes": [ { "id": "91763b24c43d3e344f424e8b", "name": "MYHOME", "altitude": 112, "coordinates": [ 52.516263, 13.377726 ], "country": "DE", "timezone": "Europe/Berlin", "rooms": [ { "id": "2746182631", "name": "Livingroom", "type": "livingroom", "module_ids": [ "12:34:56:00:01:ae" ] }, { "id": "3688132631", "name": "Hall", "type": "custom", "module_ids": [ "12:34:56:00:f1:62", "12:34:56:00:f1:63", "12:34:56:10:f1:66", "12:34:56:00:e3:9b", "0009999992", "0009999993", "12:34:56:00:01:01:01:b8" ] }, { "id": "2833524037", "name": "Entrada", "type": "lobby", "module_ids": [ "12:34:56:03:a5:54", "12:34:56:00:01:01:01:b6#1", "12:34:56:00:01:01:01:b6#2" ] }, { "id": "2940411577", "name": "Cocina", "type": "kitchen", "module_ids": [ "12:34:56:03:a0:ac", "12:34:56:00:01:01:01:b7" ] }, { "id": "222452125", "name": "Bureau", "type": "electrical_cabinet", "module_ids": [ "12:34:56:20:f5:44", "12:34:56:20:f5:8c" ], "modules": [ "12:34:56:20:f5:44", "12:34:56:20:f5:8c" ], "therm_relay": "12:34:56:20:f5:44", "true_temperature_available": true }, { "id": "100007519", "name": "Cabinet", "type": "electrical_cabinet", "module_ids": [ "12:34:56:00:16:0e", "12:34:56:00:16:0e#0", "12:34:56:00:16:0e#1", "12:34:56:00:16:0e#2", "12:34:56:00:16:0e#3", "12:34:56:00:16:0e#4", "12:34:56:00:16:0e#5", "12:34:56:00:16:0e#6", "12:34:56:00:16:0e#7", "12:34:56:00:16:0e#8", "12:34:56:00:01:01:01:b9" ] }, { "id": "1002003001", "name": "Corridor", "type": "corridor", "module_ids": [ "10:20:30:bd:b8:1e" ] }, { "id": "100007520", "name": "Toilettes", "type": "toilets", "module_ids": [ "00:11:22:33:00:11:45:fe" ] }, { "id": "2299431568", "name": "Garage", "type": "garage", "module_ids": [ "12:34:56:00:01:01:01:b5" ], "modules": [ "12:34:56:00:01:01:01:b5" ] } ], "modules": [ { "id": "12:34:56:00:fa:d0", "type": "NAPlug", "name": "Thermostat", "setup_date": 1494963356, "modules_bridged": [ "12:34:56:00:01:ae", "12:34:56:03:a0:ac", "12:34:56:03:a5:54" ] }, { "id": "12:34:56:00:01:ae", "type": "NATherm1", "name": "Livingroom", "setup_date": 1494963356, "room_id": "2746182631", "bridge": "12:34:56:00:fa:d0" }, { "id": "12:34:56:03:a5:54", "type": "NRV", "name": "Valve1", "setup_date": 1554549767, "room_id": "2833524037", "bridge": "12:34:56:00:fa:d0" }, { "id": "12:34:56:03:a0:ac", "type": "NRV", "name": "Valve2", "setup_date": 1554554444, "room_id": "2940411577", "bridge": "12:34:56:00:fa:d0" }, { "id": "12:34:56:00:f1:62", "type": "NACamera", "name": "Hall", "setup_date": 1544828430, "room_id": "3688132631", "modules_bridged": [ "12:34:56:00:86:99", "12:34:56:00:e3:9b" ] }, { "id": "12:34:56:00:f1:63", "type": "NPC", "name": "Hall", "setup_date": 1544828430, "room_id": "3688132631", "modules_bridged": [ "12:34:56:00:86:99", "12:34:56:00:e3:9b" ] }, { "id": "12:34:56:10:f1:66", "type": "NDB", "name": "Netatmo-Doorbell", "setup_date": 1602691361, "room_id": "3688132631", "reachable": true, "hk_device_id": "123456007df1", "customer_id": "1000010", "network_lock": false, "quick_display_zone": 62 }, { "id": "12:34:56:10:b9:0e", "type": "NOC", "name": "Front", "setup_date": 1509290599, "reachable": true, "customer_id": "A00010", "network_lock": false, "use_pincode": false }, { "id": "12:34:56:20:f5:44", "type": "OTH", "name": "Modulating Relay", "setup_date": 1607443936, "room_id": "222452125", "reachable": true, "modules_bridged": [ "12:34:56:20:f5:8c" ], "hk_device_id": "12:34:56:20:d0:c5", "capabilities": [ { "name": "automatism", "available": true } ], "max_modules_nb": 21 }, { "id": "12:34:56:20:f5:8c", "type": "OTM", "name": "Bureau Modulate", "setup_date": 1607443939, "room_id": "222452125", "bridge": "12:34:56:20:f5:44" }, { "id": "12:34:56:30:d5:d4", "type": "NBG", "name": "module iDiamant", "setup_date": 1562262465, "room_id": "222452125", "modules_bridged": [ "0009999992", "0009999993" ] }, { "id": "0009999992", "type": "NBR", "name": "Entrance Blinds", "setup_date": 1578551339, "room_id": "3688132631", "bridge": "12:34:56:30:d5:d4" }, { "id": "0009999993", "type": "NBO", "name": "Bubendorff blind", "setup_date": 1594132017, "room_id": "3688132631", "bridge": "12:34:56:30:d5:d4" }, { "id": "12:34:56:80:bb:26", "type": "NAMain", "name": "Villa", "setup_date": 1419453350, "room_id": "4122897288", "reachable": true, "modules_bridged": [ "12:34:56:80:44:92", "12:34:56:80:7e:18", "12:34:56:80:1c:42", "12:34:56:80:c1:ea" ], "customer_id": "C00016", "hardware_version": 251, "public_ext_data": false, "public_ext_counter": 0, "alarm_config": { "default_alarm": [ { "db_alarm_number": 0 }, { "db_alarm_number": 1 }, { "db_alarm_number": 2 }, { "db_alarm_number": 6 }, { "db_alarm_number": 4 }, { "db_alarm_number": 5 }, { "db_alarm_number": 7 }, { "db_alarm_number": 22 } ], "personnalized": [ { "threshold": 20, "data_type": 1, "direction": 0, "db_alarm_number": 8 }, { "threshold": 17, "data_type": 1, "direction": 1, "db_alarm_number": 9 }, { "threshold": 65, "data_type": 4, "direction": 0, "db_alarm_number": 16 }, { "threshold": 19, "data_type": 8, "direction": 0, "db_alarm_number": 22 } ] }, "module_offset": { "12:34:56:80:bb:26": { "a": 0.1 }, "03:00:00:03:1b:0e": { "a": 0 } } }, { "id": "12:34:56:80:1c:42", "type": "NAModule1", "name": "Outdoor", "setup_date": 1448565785, "bridge": "12:34:56:80:bb:26" }, { "id": "12:34:56:80:c1:ea", "type": "NAModule3", "name": "Rain", "setup_date": 1591770206, "bridge": "12:34:56:80:bb:26" }, { "id": "12:34:56:80:44:92", "type": "NAModule4", "name": "Bedroom", "setup_date": 1484997703, "bridge": "12:34:56:80:bb:26" }, { "id": "12:34:56:80:7e:18", "type": "NAModule4", "name": "Bathroom", "setup_date": 1543579864, "bridge": "12:34:56:80:bb:26" }, { "id": "12:34:56:03:1b:e4", "type": "NAModule2", "name": "Garden", "setup_date": 1543579864, "bridge": "12:34:56:80:bb:26" }, { "id": "12:34:56:80:60:40", "type": "NLG", "name": "Prise Control", "setup_date": 1641841257, "room_id": "1310352496", "modules_bridged": [ "12:34:56:80:00:12:ac:f2", "12:34:56:80:00:c3:69:3c", "12:34:56:80:00:c3:69:3d", "12:34:56:80:00:c3:69:3e", "12:34:56:00:00:a1:4c:da", "12:34:56:00:01:01:01:a1", "00:11:22:33:00:11:45:fe", "12:34:56:00:01:01:01:b1", "12:34:56:00:01:01:01:b2", "12:34:56:00:01:01:01:b3", "12:34:56:00:01:01:01:b4", "12:34:56:00:01:01:01:b5", "12:34:56:00:01:01:01:b6", "12:34:56:00:01:01:01:b7", "12:34:56:00:01:01:01:b8", "12:34:56:00:01:01:01:b9" ] }, { "id": "12:34:56:80:00:12:ac:f2", "type": "NLP", "name": "Prise", "setup_date": 1641841262, "room_id": "1310352496", "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:80:00:c3:69:3c", "type": "NLT", "name": "Commande sans fil", "setup_date": 1641841262, "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:80:00:c3:69:3e", "type": "NLD", "name": "Entrance command", "setup_date": 1610500885, "room_id": "3688132631", "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:80:00:c3:69:3d", "type": "Z3V", "name": "Entrance shutter", "setup_date": 1578551339, "room_id": "3688132631", "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:86:99", "type": "NACamDoorTag", "name": "Window Hall", "setup_date": 1581177375, "bridge": "12:34:56:00:f1:62", "category": "window" }, { "id": "12:34:56:00:e3:9b", "type": "NIS", "setup_date": 1620479901, "bridge": "12:34:56:00:f1:62", "name": "Sirene in hall" }, { "id": "12:34:56:00:16:0e", "type": "NLE", "name": "Écocompteur", "setup_date": 1644496884, "room_id": "100007519", "modules_bridged": [ "12:34:56:00:16:0e#0", "12:34:56:00:16:0e#1", "12:34:56:00:16:0e#2", "12:34:56:00:16:0e#3", "12:34:56:00:16:0e#4", "12:34:56:00:16:0e#5", "12:34:56:00:16:0e#6", "12:34:56:00:16:0e#7", "12:34:56:00:16:0e#8" ] }, { "id": "12:34:56:00:16:0e#0", "type": "NLE", "name": "Line 1", "setup_date": 1644496886, "room_id": "100007519", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:16:0e#1", "type": "NLE", "name": "Line 2", "setup_date": 1644496886, "room_id": "100007519", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:16:0e#2", "type": "NLE", "name": "Line 3", "setup_date": 1644496886, "room_id": "100007519", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:16:0e#3", "type": "NLE", "name": "Line 4", "setup_date": 1644496886, "room_id": "100007519", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:16:0e#4", "type": "NLE", "name": "Line 5", "setup_date": 1644496886, "room_id": "100007519", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:16:0e#5", "type": "NLE", "name": "Total", "setup_date": 1644496886, "room_id": "100007519", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:16:0e#6", "type": "NLE", "name": "Gas", "setup_date": 1644496886, "room_id": "100007519", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:16:0e#7", "type": "NLE", "name": "Hot water", "setup_date": 1644496886, "room_id": "100007519", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:16:0e#8", "type": "NLE", "name": "Cold water", "setup_date": 1644496886, "room_id": "100007519", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:00:a1:4c:da", "type": "NLPC", "name": "Consumption meter", "setup_date": 1638376602, "room_id": "100008999", "bridge": "12:34:56:80:60:40" }, { "id": "10:20:30:bd:b8:1e", "type": "BNS", "name": "Smarther", "setup_date": 1638022197, "room_id": "1002003001" }, { "id": "00:11:22:33:00:11:45:fe", "type": "NLF", "on": false, "brightness": 63, "firmware_revision": 57, "last_seen": 1657086939, "power": 0, "reachable": true, "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:01:01:01:a1", "type": "NLFN", "name": "Bathroom light", "setup_date": 1598367404, "room_id": "1002003001", "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:01:01:01:b1", "type": "NLLF", "name": "Centralized ventilation controler", "setup_date": 1598367504, "room_id": "1002003001", "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:01:01:01:b2", "type": "NLL", "name": "NLL", "setup_date": 1673019934, "room_id": "1002003001", "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:01:01:01:b3", "type": "NLV", "name": "NLV", "setup_date": 1673019934, "room_id": "1002003001", "bridge": "12:34:56:80:60:40", "appliance_type": "rolling_shutter" }, { "id": "12:34:56:00:01:01:01:b4", "type": "NLLV", "name": "NLLV", "setup_date": 1673019934, "room_id": "1002003001", "bridge": "12:34:56:80:60:40", "appliance_type": "rolling_shutter" }, { "id": "12:34:56:00:01:01:01:b5", "type": "NLJ", "name": "Garage door", "setup_date": 1743159238, "room_id": "2299431568", "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:01:01:01:b6", "type": "NLIS", "setup_date": 1673019934, "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:01:01:01:b6#1", "type": "NLIS", "name": "NLIS droite", "setup_date": 1673019934, "room_id": "2833524037", "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:01:01:01:b6#2", "type": "NLIS", "name": "NLIS gauche", "setup_date": 1673019934, "room_id": "2833524037", "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:01:01:01:b7", "type": "NLPT", "name": "NLPT", "setup_date": 1673019934, "room_id": "2940411577", "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:01:01:01:b8", "type": "NLPD", "name": "NLPD", "setup_date": 1673019934, "room_id": "3688132631", "bridge": "12:34:56:80:60:40", "appliance_type": "other" }, { "id": "12:34:56:00:01:01:01:b9", "type": "NLPO", "name": "NLPO", "setup_date": 1673019934, "room_id": "100007519", "bridge": "12:34:56:80:60:40", "appliance_type": "other" } ], "schedules": [ { "zones": [ { "type": 0, "name": "Comfort", "rooms": [ { "therm_setpoint_temperature": 21, "id": "2746182631" }, { "therm_setpoint_temperature": 22, "id": "2746182632" } ], "id": 0 }, { "type": 1, "name": "Night", "rooms": [ { "therm_setpoint_temperature": 17, "id": "2746182631" }, { "therm_setpoint_temperature": 18, "id": "2746182632" } ], "id": 1 }, { "type": 5, "name": "Eco", "rooms": [ { "therm_setpoint_temperature": 18, "id": "2746182631" }, { "therm_setpoint_temperature": 19, "id": "2746182632" } ], "id": 4 } ], "timetable": [ { "zone_id": 1, "m_offset": 0 }, { "zone_id": 0, "m_offset": 360 }, { "zone_id": 4, "m_offset": 420 }, { "zone_id": 0, "m_offset": 960 }, { "zone_id": 1, "m_offset": 1410 }, { "zone_id": 0, "m_offset": 1800 }, { "zone_id": 4, "m_offset": 1860 }, { "zone_id": 0, "m_offset": 2400 }, { "zone_id": 1, "m_offset": 2850 }, { "zone_id": 0, "m_offset": 3240 }, { "zone_id": 4, "m_offset": 3300 }, { "zone_id": 0, "m_offset": 3840 }, { "zone_id": 1, "m_offset": 4290 }, { "zone_id": 0, "m_offset": 4680 }, { "zone_id": 4, "m_offset": 4740 }, { "zone_id": 0, "m_offset": 5280 }, { "zone_id": 1, "m_offset": 5730 }, { "zone_id": 0, "m_offset": 6120 }, { "zone_id": 4, "m_offset": 6180 }, { "zone_id": 0, "m_offset": 6720 }, { "zone_id": 1, "m_offset": 7170 }, { "zone_id": 0, "m_offset": 7620 }, { "zone_id": 1, "m_offset": 8610 }, { "zone_id": 0, "m_offset": 9060 }, { "zone_id": 1, "m_offset": 10050 } ], "hg_temp": 7, "away_temp": 14, "name": "Default", "selected": true, "id": "591b54a2764ff4d50d8b5795", "type": "cooling" }, { "zones": [ { "type": 0, "name": "Comfort", "rooms": [ { "therm_setpoint_temperature": 21, "id": "2746182631" }, { "therm_setpoint_temperature": 22, "id": "2746182632" } ], "id": 0 }, { "type": 1, "name": "Night", "rooms": [ { "therm_setpoint_temperature": 17, "id": "2746182631" }, { "therm_setpoint_temperature": 18, "id": "2746182632" } ], "id": 1 }, { "type": 5, "name": "Eco", "rooms": [ { "therm_setpoint_temperature": 18, "id": "2746182631" }, { "therm_setpoint_temperature": 19, "id": "2746182632" } ], "id": 4 } ], "timetable": [ { "zone_id": 1, "m_offset": 0 }, { "zone_id": 0, "m_offset": 360 }, { "zone_id": 4, "m_offset": 420 }, { "zone_id": 0, "m_offset": 960 }, { "zone_id": 1, "m_offset": 1410 }, { "zone_id": 0, "m_offset": 1800 }, { "zone_id": 4, "m_offset": 1860 }, { "zone_id": 0, "m_offset": 2400 }, { "zone_id": 1, "m_offset": 2850 }, { "zone_id": 0, "m_offset": 3240 }, { "zone_id": 4, "m_offset": 3300 }, { "zone_id": 0, "m_offset": 3840 }, { "zone_id": 1, "m_offset": 4290 }, { "zone_id": 0, "m_offset": 4680 }, { "zone_id": 4, "m_offset": 4740 }, { "zone_id": 0, "m_offset": 5280 }, { "zone_id": 1, "m_offset": 5730 }, { "zone_id": 0, "m_offset": 6120 }, { "zone_id": 4, "m_offset": 6180 }, { "zone_id": 0, "m_offset": 6720 }, { "zone_id": 1, "m_offset": 7170 }, { "zone_id": 0, "m_offset": 7620 }, { "zone_id": 1, "m_offset": 8610 }, { "zone_id": 0, "m_offset": 9060 }, { "zone_id": 1, "m_offset": 10050 } ], "hg_temp": 7, "away_temp": 14, "name": "Winter", "id": "b1b54a2f45795764f59d50d8", "type": "therm" } ], "therm_setpoint_default_duration": 120, "temperature_control_mode": "cooling", "cooling_mode": "schedule", "persons": [ { "id": "91827374-7e04-5298-83ad-a0cb8372dff1", "pseudo": "John Doe", "url": "https://netatmocameraimage.blob.core.windows.net/production/d74fad765b9100ef480720a9a4a95c24b808a89f8d1730fb69ecdf2bb8b72039d2c69928b029d67fc40cb2d7" }, { "id": "91827375-7e04-5298-83ae-a0cb8372dff2", "pseudo": "Jane Doe", "url": "https://netatmocameraimage.blob.core.windows.net/production/d74fad765b9100ef480720a9a4a95c24b808a89f8d1730039d2c69928b029d67fc40cb2d7fb69ecdf2bb8b72" }, { "id": "91827376-7e04-5298-83af-a0cb8372dff3", "pseudo": "Richard Doe", "url": "https://netatmocameraimage.blob.core.windows.net/production/d74fad765b9100ef480720a9a4a95c2d1730fb69ecdf2bb8b72039d2c69928b029d67fc40cb2d74b808a89f8" } ], "therm_mode": "schedule" }, { "id": "91763b24c43d3e344f424e8c", "altitude": 112, "coordinates": [ 52.516263, 13.377726 ], "country": "DE", "timezone": "Europe/Berlin", "therm_setpoint_default_duration": 180, "therm_mode": "schedule" } ], "user": { "email": "john@doe.com", "language": "de-DE", "locale": "de-DE", "feel_like_algorithm": 0, "unit_pressure": 0, "unit_system": 0, "unit_wind": 0, "all_linked": false, "type": "netatmo", "id": "91763b24c43d3e344f424e8b" } }, "status": "ok", "time_exec": 0.056135892868042, "time_server": 1559171003 }pyatmo-9.2.1/fixtures/homesdata_empty.json000066400000000000000000000000541501740523400207630ustar00rootroot00000000000000{ "body": { "homes": [] } } pyatmo-9.2.1/fixtures/homesdata_emtpy_home.json000066400000000000000000000217731501740523400220060ustar00rootroot00000000000000{ "body": { "homes": [ { "id": "111111111111111111111401", "name": "Home with no modules", "altitude": 9, "coordinates": [ 1.23456789, 50.0987654 ], "country": "BE", "timezone": "Europe/Brussels", "rooms": [ { "id": "1111111401", "name": "Livingroom", "type": "livingroom" } ], "temperature_control_mode": "heating", "therm_mode": "away", "therm_setpoint_default_duration": 120, "cooling_mode": "schedule", "schedules": [ { "away_temp": 14, "hg_temp": 7, "name": "Week", "timetable": [ { "zone_id": 1, "m_offset": 0 }, { "zone_id": 6, "m_offset": 420 }, { "zone_id": 4, "m_offset": 450 }, { "zone_id": 5, "m_offset": 720 }, { "zone_id": 4, "m_offset": 780 }, { "zone_id": 0, "m_offset": 960 }, { "zone_id": 1, "m_offset": 1320 }, { "zone_id": 6, "m_offset": 1860 }, { "zone_id": 4, "m_offset": 1890 }, { "zone_id": 5, "m_offset": 2160 }, { "zone_id": 4, "m_offset": 2220 }, { "zone_id": 0, "m_offset": 2400 }, { "zone_id": 1, "m_offset": 2760 }, { "zone_id": 6, "m_offset": 3300 }, { "zone_id": 4, "m_offset": 3330 }, { "zone_id": 5, "m_offset": 3600 }, { "zone_id": 4, "m_offset": 3660 }, { "zone_id": 0, "m_offset": 3840 }, { "zone_id": 1, "m_offset": 4200 }, { "zone_id": 6, "m_offset": 4740 }, { "zone_id": 4, "m_offset": 4770 }, { "zone_id": 5, "m_offset": 5040 }, { "zone_id": 4, "m_offset": 5100 }, { "zone_id": 0, "m_offset": 5280 }, { "zone_id": 1, "m_offset": 5640 }, { "zone_id": 6, "m_offset": 6180 }, { "zone_id": 4, "m_offset": 6210 }, { "zone_id": 5, "m_offset": 6480 }, { "zone_id": 4, "m_offset": 6540 }, { "zone_id": 0, "m_offset": 6720 }, { "zone_id": 1, "m_offset": 7080 }, { "zone_id": 6, "m_offset": 7620 }, { "zone_id": 5, "m_offset": 7800 }, { "zone_id": 0, "m_offset": 8100 }, { "zone_id": 1, "m_offset": 8550 }, { "zone_id": 6, "m_offset": 9060 }, { "zone_id": 5, "m_offset": 9240 }, { "zone_id": 0, "m_offset": 9540 }, { "zone_id": 1, "m_offset": 9990 } ], "zones": [ { "type": 0, "name": "Comfort", "rooms_temp": [], "id": 0, "rooms": [] }, { "type": 1, "name": "Nacht", "rooms_temp": [], "id": 1, "rooms": [] }, { "type": 5, "name": "Eco", "rooms_temp": [], "id": 4, "rooms": [] }, { "type": 4, "name": "Tussenin", "rooms_temp": [], "id": 5, "rooms": [] }, { "type": 4, "name": "Ochtend", "rooms_temp": [], "id": 6, "rooms": [] } ], "id": "700000000000000000000401", "selected": true, "type": "therm" } ] } ], "user": { "email": "john@doe.com", "language": "de-DE", "locale": "de-DE", "feel_like_algorithm": 0, "unit_pressure": 0, "unit_system": 0, "unit_wind": 0, "id": "91763b24c43d3e344f424e8b" } }, "status": "ok", "time_exec": 0.056135892868042, "time_server": 1559171003 }pyatmo-9.2.1/fixtures/homesdata_multi.json000066400000000000000000006073331501740523400207740ustar00rootroot00000000000000{ "body": { "homes": [ { "id": "aaaaaaaaaaabbbbbbbbbbccc", "name": "A BIG HOME", "altitude": 284, "coordinates": [ 26.234678, 83.234678 ], "country": "FR", "timezone": "Europe/Paris", "rooms": [ { "id": "3707962039", "name": "Cuisine", "type": "kitchen", "module_ids": [ "98:76:54:32:10:00:00:03", "98:76:54:32:10:00:00:05", "98:76:54:32:10:00:00:06", "98:76:54:32:10:00:00:07", "98:76:54:32:10:00:00:09", "98:76:54:32:10:00:00:28", "98:76:54:32:10:00:00:37", "98:76:54:32:10:00:00:38", "98:76:54:32:10:00:00:40", "98:76:54:32:10:00:00:50" ] }, { "id": "596817675", "name": "Vestibule", "type": "lobby", "module_ids": [ "98:76:54:32:10:00:00:01", "98:76:54:32:10:00:00:02", "98:76:54:32:10:00:00:08", "98:76:54:32:10:00:00:13", "98:76:54:32:10:00:00:14", "98:76:54:32:10:00:00:15", "98:76:54:32:10:00:00:16", "98:76:54:32:10:00:00:27", "98:76:54:32:10:00:00:29", "98:76:54:32:10:00:00:32", "98:76:54:32:10:00:00:36", "98:76:54:32:10:00:00:39" ] }, { "id": "1462100035", "name": "Salon", "type": "livingroom", "module_ids": [ "98:76:54:32:10:00:00:04", "98:76:54:32:10:00:00:24#1", "98:76:54:32:10:00:00:34", "98:76:54:32:10:00:00:52", "98:76:54:32:10:00:00:60", "98:76:54:32:10:00:00:63", "98:76:54:32:10:00:00:66", "98:76:54:32:10:00:00:73", "98:76:54:32:10:00:00:75" ] }, { "id": "3435163850", "name": "Chambre A", "type": "bedroom", "module_ids": [ "98:76:54:32:10:00:00:26", "98:76:54:32:10:00:00:51" ] }, { "id": "737850817", "name": "Extérieur", "type": "outdoor", "module_ids": [ "98:76:54:32:10:00:00:10", "98:76:54:32:10:00:00:41", "98:76:54:32:10:00:00:42", "98:76:54:32:10:00:00:53", "98:76:54:32:10:00:00:54", "98:76:54:32:10:00:00:55", "98:76:54:32:10:00:00:56" ] }, { "id": "842662884", "name": "Bibliothèque", "type": "home_office", "module_ids": [ "98:76:54:32:10:00:00:11", "98:76:54:32:10:00:00:12", "98:76:54:32:10:00:00:24#2", "98:76:54:32:10:00:00:25" ] }, { "id": "3194154910", "name": "Salle à manger", "type": "dining_room", "module_ids": [ "98:76:54:32:10:00:00:30", "98:76:54:32:10:00:00:31", "98:76:54:32:10:00:00:33", "98:76:54:32:10:00:00:72" ] }, { "id": "2370728183", "name": "Atelier", "type": "custom", "module_ids": [ "98:76:54:32:10:00:00:18", "98:76:54:32:10:00:00:23" ] }, { "id": "2042969726", "name": "Chambre B", "type": "bedroom", "module_ids": [ "98:76:54:32:10:00:00:19", "98:76:54:32:10:00:00:20", "98:76:54:32:10:00:00:46" ] }, { "id": "2754296835", "name": "Placard Technique", "type": "electrical_cabinet", "module_ids": [ "aa:aa:aa:aa:aa:aa", "98:76:54:32:10:00:00:22", "98:76:54:32:10:00:00:48", "98:76:54:32:10:00:00:59", "98:76:54:32:10:00:00:67", "98:76:54:32:10:00:00:68", "98:76:54:32:10:00:00:69", "98:76:54:32:10:00:00:77", "98:76:54:32:10:00:00:78", "98:76:54:32:10:00:00:79" ] }, { "id": "1662974901", "name": "Dressing", "type": "custom", "module_ids": [ "98:76:54:32:10:00:00:21", "98:76:54:32:10:00:00:35" ] }, { "id": "873035982", "name": "Chambre C", "type": "bedroom", "module_ids": [ "98:76:54:32:10:00:00:17", "98:76:54:32:10:00:00:43", "98:76:54:32:10:00:00:76" ] }, { "id": "3795659199", "name": "Chambre D", "type": "bedroom", "module_ids": [ "98:76:54:32:10:00:00:57" ] }, { "id": "2102454491", "name": "Buanderie", "type": "custom", "module_ids": [ "98:76:54:32:10:00:00:45" ] }, { "id": "93888250", "name": "Salle de bains Des Enfants", "type": "bathroom", "module_ids": [ "98:76:54:32:10:00:00:44" ] }, { "id": "3497055021", "name": "Chambre Brice", "type": "bedroom", "module_ids": [ "98:76:54:32:10:00:00:47", "98:76:54:32:10:00:00:74" ] }, { "id": "2061006239", "name": "Pool house", "type": "custom", "module_ids": [ "98:76:54:32:10:00:00:58", "98:76:54:32:10:00:00:61", "98:76:54:32:10:00:00:62", "98:76:54:32:10:00:00:64", "98:76:54:32:10:00:00:65", "98:76:54:32:10:00:00:71" ] }, { "id": "927970817", "name": "Salle de bains Des Parents", "type": "bathroom", "module_ids": [ "98:76:54:32:10:00:00:49" ] }, { "id": "1641945290", "name": "Salle de bains D’Arthur", "type": "bathroom", "module_ids": [ "98:76:54:32:10:00:00:70" ] } ], "modules": [ { "id": "aa:aa:aa:aa:aa:aa", "type": "NLG", "name": "Legrand Gateway", "setup_date": 1572624665, "room_id": "2754296835", "modules_bridged": [ "98:76:54:32:10:00:00:01", "98:76:54:32:10:00:00:02", "98:76:54:32:10:00:00:03", "98:76:54:32:10:00:00:04", "98:76:54:32:10:00:00:05", "98:76:54:32:10:00:00:06", "98:76:54:32:10:00:00:07", "98:76:54:32:10:00:00:08", "98:76:54:32:10:00:00:09", "98:76:54:32:10:00:00:10", "98:76:54:32:10:00:00:11", "98:76:54:32:10:00:00:12", "98:76:54:32:10:00:00:13", "98:76:54:32:10:00:00:14", "98:76:54:32:10:00:00:15", "98:76:54:32:10:00:00:16", "98:76:54:32:10:00:00:17", "98:76:54:32:10:00:00:18", "98:76:54:32:10:00:00:19", "98:76:54:32:10:00:00:20", "98:76:54:32:10:00:00:21", "98:76:54:32:10:00:00:22", "98:76:54:32:10:00:00:23", "98:76:54:32:10:00:00:24", "98:76:54:32:10:00:00:24#1", "98:76:54:32:10:00:00:24#2", "98:76:54:32:10:00:00:25", "98:76:54:32:10:00:00:26", "98:76:54:32:10:00:00:27", "98:76:54:32:10:00:00:28", "98:76:54:32:10:00:00:29", "98:76:54:32:10:00:00:30", "98:76:54:32:10:00:00:31", "98:76:54:32:10:00:00:32", "98:76:54:32:10:00:00:33", "98:76:54:32:10:00:00:34", "98:76:54:32:10:00:00:35", "98:76:54:32:10:00:00:36", "98:76:54:32:10:00:00:37", "98:76:54:32:10:00:00:38", "98:76:54:32:10:00:00:39", "98:76:54:32:10:00:00:40", "98:76:54:32:10:00:00:41", "98:76:54:32:10:00:00:42", "98:76:54:32:10:00:00:43", "98:76:54:32:10:00:00:44", "98:76:54:32:10:00:00:45", "98:76:54:32:10:00:00:46", "98:76:54:32:10:00:00:47", "98:76:54:32:10:00:00:48", "98:76:54:32:10:00:00:49", "98:76:54:32:10:00:00:50", "98:76:54:32:10:00:00:51", "98:76:54:32:10:00:00:52", "98:76:54:32:10:00:00:53", "98:76:54:32:10:00:00:54", "98:76:54:32:10:00:00:55", "98:76:54:32:10:00:00:03#1", "98:76:54:32:10:00:00:03#2", "98:76:54:32:10:00:00:07#1", "98:76:54:32:10:00:00:07#2", "98:76:54:32:10:00:00:08#1", "98:76:54:32:10:00:00:08#2", "98:76:54:32:10:00:00:28#1", "98:76:54:32:10:00:00:28#2", "98:76:54:32:10:00:00:29#1", "98:76:54:32:10:00:00:29#2", "98:76:54:32:10:00:00:30#1", "98:76:54:32:10:00:00:30#2", "98:76:54:32:10:00:00:50#1", "98:76:54:32:10:00:00:50#2", "98:76:54:32:10:00:00:56", "98:76:54:32:10:00:00:57", "98:76:54:32:10:00:00:58", "98:76:54:32:10:00:00:59", "98:76:54:32:10:00:00:60", "98:76:54:32:10:00:00:61", "98:76:54:32:10:00:00:62", "98:76:54:32:10:00:00:63", "98:76:54:32:10:00:00:63#1", "98:76:54:32:10:00:00:63#2", "98:76:54:32:10:00:00:64", "98:76:54:32:10:00:00:64#1", "98:76:54:32:10:00:00:64#2", "98:76:54:32:10:00:00:65", "98:76:54:32:10:00:00:65#1", "98:76:54:32:10:00:00:65#2", "98:76:54:32:10:00:00:66", "98:76:54:32:10:00:00:66#1", "98:76:54:32:10:00:00:66#2", "98:76:54:32:10:00:00:67", "98:76:54:32:10:00:00:68", "98:76:54:32:10:00:00:69", "98:76:54:32:10:00:00:70", "98:76:54:32:10:00:00:71", "98:76:54:32:10:00:00:72", "98:76:54:32:10:00:00:73", "98:76:54:32:10:00:00:74", "98:76:54:32:10:00:00:75", "98:76:54:32:10:00:00:76", "98:76:54:32:10:00:00:77", "98:76:54:32:10:00:00:78", "98:76:54:32:10:00:00:79" ] }, { "id": "98:76:54:32:10:00:00:01", "type": "NLP", "name": "Buffet", "setup_date": 1572624686, "room_id": "596817675", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "light" }, { "id": "98:76:54:32:10:00:00:02", "type": "NLT", "name": "Commande entrée sortie principale", "setup_date": 1572624686, "room_id": "596817675", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:03", "type": "NLD", "name": "Boutons Cuisine Haut", "setup_date": 1572629067, "room_id": "3707962039", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:04", "type": "NLV", "name": "volet", "setup_date": 1572798965, "room_id": "1462100035", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:05", "type": "NLM", "name": "Verrière", "setup_date": 1574591975, "room_id": "3707962039", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:06", "type": "NLM", "name": "ilot", "setup_date": 1574591975, "room_id": "3707962039", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:07", "type": "NLD", "name": "Bouton Cuisine milieu", "setup_date": 1574592863, "room_id": "3707962039", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:08", "type": "NLD", "name": "Entrée Bouton Portail et dehors", "setup_date": 1574593140, "room_id": "596817675", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:09", "type": "NLT", "name": "Bouton pour exterieur porte fenetre", "setup_date": 1605358560, "room_id": "3707962039", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:10", "type": "NLM", "name": "Olivier", "setup_date": 1605359274, "room_id": "737850817", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:11", "type": "NLP", "name": "Lampadaire", "setup_date": 1605369621, "room_id": "842662884", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "light" }, { "id": "98:76:54:32:10:00:00:12", "type": "NLT", "name": "Bouton Bibliotheque", "setup_date": 1607175439, "room_id": "842662884", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:13", "type": "NLF", "name": "Couloir enfants", "setup_date": 1612299365, "room_id": "596817675", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:14", "type": "NLT", "name": "Couloir enfants 2", "setup_date": 1612299777, "room_id": "596817675", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:15", "type": "NLT", "name": "Couloir enfants 3", "setup_date": 1612299852, "room_id": "596817675", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:16", "type": "NLT", "name": "Couloir enfants 1", "setup_date": 1613565493, "room_id": "596817675", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:17", "type": "NLF", "name": "Lumière C", "setup_date": 1617390843, "room_id": "873035982", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:18", "type": "NLM", "name": "Néon", "setup_date": 1643544945, "room_id": "2370728183", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:19", "type": "NLT", "name": "Couloir A interrupteur", "setup_date": 1643794135, "room_id": "2042969726", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:20", "type": "NLF", "name": "Couloir A", "setup_date": 1643794453, "room_id": "2042969726", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:21", "type": "NLPT", "name": "Dressing", "setup_date": 1643809582, "room_id": "1662974901", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:22", "type": "NLPM", "name": "Onduleur Serveurs Mais Local Technique", "setup_date": 1643911516, "room_id": "2754296835", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "other" }, { "id": "98:76:54:32:10:00:00:23", "type": "NLT", "name": "Interrupteur neon", "setup_date": 1644008400, "room_id": "2370728183", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:24", "type": "NLIS", "setup_date": 1645651106, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:24#1", "type": "NLIS", "name": "Niche", "setup_date": 1645651106, "room_id": "1462100035", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:24#2", "type": "NLIS", "name": "Escalier", "setup_date": 1645651106, "room_id": "842662884", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:25", "type": "NLT", "name": "Bouton Escalier", "setup_date": 1645651356, "room_id": "842662884", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:26", "type": "NLPT", "name": "Lumière Chambre E", "setup_date": 1645657974, "room_id": "3435163850", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:27", "type": "NLPT", "name": "Entrée", "setup_date": 1645658118, "room_id": "596817675", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:28", "type": "NLD", "name": "Bouton cuisine bas", "setup_date": 1645659939, "room_id": "3707962039", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:29", "type": "NLD", "name": "Bouton double entrée porte", "setup_date": 1645660346, "room_id": "596817675", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:30", "type": "NLD", "name": "Bouton double salle à manger", "setup_date": 1645660684, "room_id": "3194154910", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:31", "type": "NLF", "name": "Placard", "setup_date": 1645662093, "room_id": "3194154910", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:32", "type": "NLT", "name": "Bouton plafond entrée couloir", "setup_date": 1645662629, "room_id": "596817675", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:33", "type": "NLPT", "name": "Table", "setup_date": 1645889017, "room_id": "3194154910", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:34", "type": "NLPT", "name": "Baie Vitrée", "setup_date": 1645889069, "room_id": "1462100035", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:35", "type": "NLC", "name": "Radiateur Dressing", "setup_date": 1645894862, "room_id": "1662974901", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "radiator" }, { "id": "98:76:54:32:10:00:00:36", "type": "NLC", "name": "Radiateur Entrée", "setup_date": 1645899253, "room_id": "596817675", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "radiator" }, { "id": "98:76:54:32:10:00:00:37", "type": "NLC", "name": "Radiateur Cuisine Dressing", "setup_date": 1645902157, "room_id": "3707962039", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "radiator" }, { "id": "98:76:54:32:10:00:00:38", "type": "NLC", "name": "Radiateur Cuisine Entrée", "setup_date": 1645902199, "room_id": "3707962039", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "radiator" }, { "id": "98:76:54:32:10:00:00:39", "type": "NLT", "name": "Commande sans fil couloir enfant pour entrée", "setup_date": 1646074736, "room_id": "596817675", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:40", "type": "NLPT", "name": "Couloir Parents", "setup_date": 1646568523, "room_id": "3707962039", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:41", "type": "NLPT", "name": "Jardin", "setup_date": 1646568567, "room_id": "737850817", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:42", "type": "NLPT", "name": "Facade", "setup_date": 1646568594, "room_id": "737850817", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:43", "type": "NLC", "name": "Radiateur FF", "setup_date": 1646581781, "room_id": "873035982", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "radiator" }, { "id": "98:76:54:32:10:00:00:44", "type": "NLC", "name": "Radiateur Salle De Bain Enfants", "setup_date": 1646828219, "room_id": "93888250", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "radiator" }, { "id": "98:76:54:32:10:00:00:45", "type": "NLC", "name": "Radiateur Buanderie", "setup_date": 1646828251, "room_id": "2102454491", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "radiator" }, { "id": "98:76:54:32:10:00:00:46", "type": "NLC", "name": "Radiateur A", "setup_date": 1646828278, "room_id": "2042969726", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "radiator" }, { "id": "98:76:54:32:10:00:00:47", "type": "NLC", "name": "Radiateur B", "setup_date": 1646828308, "room_id": "3497055021", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "radiator" }, { "id": "98:76:54:32:10:00:00:48", "type": "NLM", "name": "Cam Porte", "setup_date": 1653579677, "room_id": "2754296835", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:49", "type": "NLC", "name": "Radiateur Sèche Serviette E", "setup_date": 1667205824, "room_id": "927970817", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "radiator" }, { "id": "98:76:54:32:10:00:00:50", "type": "NLAO", "name": "Porte vitree sans pile", "setup_date": 1668001531, "room_id": "3707962039", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:51", "type": "NLC", "name": "Radiateur E", "setup_date": 1668339519, "room_id": "3435163850", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "radiator" }, { "id": "98:76:54:32:10:00:00:52", "type": "NLM", "name": "Meurtrières", "setup_date": 1671560972, "room_id": "1462100035", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:53", "type": "NLPT", "name": "Parking", "setup_date": 1672948768, "room_id": "737850817", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:54", "type": "NLM", "name": "Barbecue", "setup_date": 1672948768, "room_id": "737850817", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:55", "type": "NLAO", "name": "Bouton sans pile cuisine ete", "setup_date": 1672949735, "room_id": "737850817", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:03#1", "type": "NLD", "setup_date": 1673873611, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:03#2", "type": "NLD", "setup_date": 1673873611, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:07#1", "type": "NLD", "setup_date": 1673873611, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:07#2", "type": "NLD", "setup_date": 1673873611, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:08#1", "type": "NLD", "setup_date": 1673873611, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:08#2", "type": "NLD", "setup_date": 1673873611, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:28#1", "type": "NLD", "setup_date": 1673873611, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:28#2", "type": "NLD", "setup_date": 1673873611, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:29#1", "type": "NLD", "setup_date": 1673873611, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:29#2", "type": "NLD", "setup_date": 1673873611, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:30#1", "type": "NLD", "setup_date": 1673873611, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:30#2", "type": "NLD", "setup_date": 1673873611, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:50#1", "type": "NLAO", "setup_date": 1673873611, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:50#2", "type": "NLAO", "setup_date": 1673873611, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:56", "type": "NLM", "name": "Piscine", "setup_date": 1691244631, "room_id": "737850817", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:57", "type": "NLC", "name": "Radiateur DD", "setup_date": 1692093769, "room_id": "3795659199", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "radiator" }, { "id": "98:76:54:32:10:00:00:58", "type": "NLM", "name": "Salle de bain", "setup_date": 1692094781, "room_id": "2061006239", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:59", "type": "NLP", "name": "Prise Pool House Relais Zigbee", "setup_date": 1692095384, "room_id": "2754296835", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "router" }, { "id": "98:76:54:32:10:00:00:60", "type": "NLPT", "name": "Plafonnier", "setup_date": 1692095856, "room_id": "1462100035", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:61", "type": "NLPT", "name": "Terrasse Piscine", "setup_date": 1693848343, "room_id": "2061006239", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:62", "type": "NLPT", "name": "Lumière", "setup_date": 1693848357, "room_id": "2061006239", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:63", "type": "NLD", "name": "Salon Commande Double Haut", "setup_date": 1694336106, "room_id": "1462100035", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:63#1", "type": "NLD", "setup_date": 1694336106, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:63#2", "type": "NLD", "setup_date": 1694336106, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:64", "type": "NLD", "name": "Commande Pool House Gauche", "setup_date": 1694336110, "room_id": "2061006239", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:64#1", "type": "NLD", "setup_date": 1694336110, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:64#2", "type": "NLD", "setup_date": 1694336110, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:65", "type": "NLD", "name": "Commande Pool House Droite", "setup_date": 1694336143, "room_id": "2061006239", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:65#1", "type": "NLD", "setup_date": 1694336143, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:65#2", "type": "NLD", "setup_date": 1694336143, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:66", "type": "NLD", "name": "Commande Double Bas", "setup_date": 1698577707, "room_id": "1462100035", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:66#1", "type": "NLD", "setup_date": 1698577707, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:66#2", "type": "NLD", "setup_date": 1698577707, "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:67", "type": "NLPO", "name": "Cumulus Parents", "setup_date": 1699128857, "room_id": "2754296835", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "water_heater" }, { "id": "98:76:54:32:10:00:00:68", "type": "NLPO", "name": "Cumulus DD", "setup_date": 1699132798, "room_id": "2754296835", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "water_heater" }, { "id": "98:76:54:32:10:00:00:69", "type": "NLPC", "name": "Compteur Filtration Local Technique", "setup_date": 1711797163, "room_id": "2754296835", "bridge": "00:04:74:22:52:38" }, { "id": "98:76:54:32:10:00:00:70", "type": "NLC", "name": "Radiateur Sèche Serviette A", "setup_date": 1702133314, "room_id": "1641945290", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "radiator" }, { "id": "98:76:54:32:10:00:00:71", "type": "NLPO", "name": "Cumulus Pool House", "setup_date": 1702135239, "room_id": "2061006239", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "water_heater" }, { "id": "98:76:54:32:10:00:00:72", "type": "NLC", "name": "Radiateur Sol Salle À Manger", "setup_date": 1707332251, "room_id": "3194154910", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "radiator_without_pilot_wire" }, { "id": "98:76:54:32:10:00:00:73", "type": "NLC", "name": "Radiateur Sol Salon", "setup_date": 1707332251, "room_id": "1462100035", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "radiator_without_pilot_wire" }, { "id": "98:76:54:32:10:00:00:74", "type": "NLP", "name": "Setup PC B", "setup_date": 1707332620, "room_id": "3497055021", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "router" }, { "id": "98:76:54:32:10:00:00:75", "type": "NLPM", "name": "Setup TV Apple TV Switch Salon", "setup_date": 1707333771, "room_id": "1462100035", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "multimedia" }, { "id": "98:76:54:32:10:00:00:76", "type": "NLP", "name": "Mesure PC Switch C", "setup_date": 1707335636, "room_id": "873035982", "bridge": "aa:aa:aa:aa:aa:aa", "appliance_type": "router" }, { "id": "98:76:54:32:10:00:00:77", "type": "NLPC", "name": "Compteur Plaque Sèche-Linge PC Buanderie Plan Cuisine", "setup_date": 1707339526, "room_id": "2754296835", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:78", "type": "NLPC", "name": "Compteur Congel Micro-onde Frigo PC WC", "setup_date": 1708185348, "room_id": "2754296835", "bridge": "aa:aa:aa:aa:aa:aa" }, { "id": "98:76:54:32:10:00:00:79", "type": "NLPC", "name": "Compteur Lave-linge Four Lave Lave-Vaisselle PC TV Chambre ", "setup_date": 1708185369, "room_id": "2754296835", "bridge": "aa:aa:aa:aa:aa:aa" } ], "temperature_control_mode": "heating", "therm_mode": "schedule", "therm_setpoint_default_duration": 180, "schedules": [ { "timetable": [ { "zone_id": 1, "m_offset": 0 }, { "zone_id": 0, "m_offset": 360 }, { "zone_id": 1, "m_offset": 510 }, { "zone_id": 5, "m_offset": 960 }, { "zone_id": 1, "m_offset": 1200 }, { "zone_id": 2, "m_offset": 1260 }, { "zone_id": 1, "m_offset": 1380 }, { "zone_id": 0, "m_offset": 1800 }, { "zone_id": 1, "m_offset": 1950 }, { "zone_id": 5, "m_offset": 2400 }, { "zone_id": 1, "m_offset": 2640 }, { "zone_id": 2, "m_offset": 2700 }, { "zone_id": 1, "m_offset": 2820 }, { "zone_id": 0, "m_offset": 3240 }, { "zone_id": 1, "m_offset": 3390 }, { "zone_id": 5, "m_offset": 3840 }, { "zone_id": 1, "m_offset": 4080 }, { "zone_id": 2, "m_offset": 4140 }, { "zone_id": 1, "m_offset": 4260 }, { "zone_id": 0, "m_offset": 4680 }, { "zone_id": 1, "m_offset": 4830 }, { "zone_id": 5, "m_offset": 5280 }, { "zone_id": 1, "m_offset": 5520 }, { "zone_id": 2, "m_offset": 5580 }, { "zone_id": 1, "m_offset": 5700 }, { "zone_id": 0, "m_offset": 6120 }, { "zone_id": 1, "m_offset": 6270 }, { "zone_id": 5, "m_offset": 6720 }, { "zone_id": 1, "m_offset": 6960 }, { "zone_id": 2, "m_offset": 7020 }, { "zone_id": 1, "m_offset": 7140 }, { "zone_id": 0, "m_offset": 7560 }, { "zone_id": 1, "m_offset": 7710 }, { "zone_id": 5, "m_offset": 8160 }, { "zone_id": 1, "m_offset": 8400 }, { "zone_id": 2, "m_offset": 8460 }, { "zone_id": 1, "m_offset": 8580 }, { "zone_id": 0, "m_offset": 9000 }, { "zone_id": 1, "m_offset": 9150 }, { "zone_id": 5, "m_offset": 9600 }, { "zone_id": 1, "m_offset": 9840 }, { "zone_id": 2, "m_offset": 9900 }, { "zone_id": 1, "m_offset": 10020 } ], "zones": [ { "name": "Comfort", "id": 0, "type": 0, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "comfort" }, { "room_id": "2042969726", "therm_setpoint_fp": "comfort" }, { "room_id": "3497055021", "therm_setpoint_fp": "comfort" }, { "room_id": "3435163850", "therm_setpoint_fp": "comfort" }, { "room_id": "873035982", "therm_setpoint_fp": "comfort" }, { "room_id": "1662974901", "therm_setpoint_fp": "comfort" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "comfort" }, { "room_id": "3795659199", "therm_setpoint_fp": "comfort" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "comfort" } ], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "comfort" }, { "id": "2042969726", "therm_setpoint_fp": "comfort" }, { "id": "3497055021", "therm_setpoint_fp": "comfort" }, { "id": "3435163850", "therm_setpoint_fp": "comfort" }, { "id": "873035982", "therm_setpoint_fp": "comfort" }, { "id": "1662974901", "therm_setpoint_fp": "comfort" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "comfort" }, { "id": "3795659199", "therm_setpoint_fp": "comfort" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "comfort" } ] }, { "name": "Comfort+", "id": 3, "type": 8, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "comfort" }, { "room_id": "2042969726", "therm_setpoint_fp": "comfort" }, { "room_id": "3497055021", "therm_setpoint_fp": "comfort" }, { "room_id": "3435163850", "therm_setpoint_fp": "comfort" }, { "room_id": "873035982", "therm_setpoint_fp": "comfort" }, { "room_id": "1662974901", "therm_setpoint_fp": "comfort" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "comfort" }, { "room_id": "3795659199", "therm_setpoint_fp": "comfort" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "comfort" } ], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "comfort" }, { "id": "2042969726", "therm_setpoint_fp": "comfort" }, { "id": "3497055021", "therm_setpoint_fp": "comfort" }, { "id": "3435163850", "therm_setpoint_fp": "comfort" }, { "id": "873035982", "therm_setpoint_fp": "comfort" }, { "id": "1662974901", "therm_setpoint_fp": "comfort" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "comfort" }, { "id": "3795659199", "therm_setpoint_fp": "comfort" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "comfort" } ] }, { "name": "Éco", "id": 4, "type": 5, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "away" }, { "room_id": "2042969726", "therm_setpoint_fp": "away" }, { "room_id": "3497055021", "therm_setpoint_fp": "away" }, { "room_id": "3435163850", "therm_setpoint_fp": "away" }, { "room_id": "873035982", "therm_setpoint_fp": "away" }, { "room_id": "1662974901", "therm_setpoint_fp": "away" }, { "room_id": "93888250", "therm_setpoint_fp": "away" }, { "room_id": "596817675", "therm_setpoint_fp": "away" }, { "room_id": "3795659199", "therm_setpoint_fp": "away" }, { "room_id": "927970817", "therm_setpoint_fp": "away" }, { "room_id": "1641945290", "therm_setpoint_fp": "away" }, { "room_id": "2102454491", "therm_setpoint_fp": "away" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "away" }, { "id": "2042969726", "therm_setpoint_fp": "away" }, { "id": "3497055021", "therm_setpoint_fp": "away" }, { "id": "3435163850", "therm_setpoint_fp": "away" }, { "id": "873035982", "therm_setpoint_fp": "away" }, { "id": "1662974901", "therm_setpoint_fp": "away" }, { "id": "93888250", "therm_setpoint_fp": "away" }, { "id": "596817675", "therm_setpoint_fp": "away" }, { "id": "3795659199", "therm_setpoint_fp": "away" }, { "id": "927970817", "therm_setpoint_fp": "away" }, { "id": "1641945290", "therm_setpoint_fp": "away" }, { "id": "2102454491", "therm_setpoint_fp": "away" } ] }, { "name": "Nuit", "id": 1, "type": 1, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "away" }, { "room_id": "2042969726", "therm_setpoint_fp": "away" }, { "room_id": "3497055021", "therm_setpoint_fp": "away" }, { "room_id": "3435163850", "therm_setpoint_fp": "away" }, { "room_id": "873035982", "therm_setpoint_fp": "away" }, { "room_id": "1662974901", "therm_setpoint_fp": "away" }, { "room_id": "93888250", "therm_setpoint_fp": "frost_guard" }, { "room_id": "596817675", "therm_setpoint_fp": "away" }, { "room_id": "3795659199", "therm_setpoint_fp": "away" }, { "room_id": "927970817", "therm_setpoint_fp": "frost_guard" }, { "room_id": "1641945290", "therm_setpoint_fp": "frost_guard" }, { "room_id": "2102454491", "therm_setpoint_fp": "away" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "away" }, { "id": "2042969726", "therm_setpoint_fp": "away" }, { "id": "3497055021", "therm_setpoint_fp": "away" }, { "id": "3435163850", "therm_setpoint_fp": "away" }, { "id": "873035982", "therm_setpoint_fp": "away" }, { "id": "1662974901", "therm_setpoint_fp": "away" }, { "id": "93888250", "therm_setpoint_fp": "frost_guard" }, { "id": "596817675", "therm_setpoint_fp": "away" }, { "id": "3795659199", "therm_setpoint_fp": "away" }, { "id": "927970817", "therm_setpoint_fp": "frost_guard" }, { "id": "1641945290", "therm_setpoint_fp": "frost_guard" }, { "id": "2102454491", "therm_setpoint_fp": "away" } ] }, { "name": "Confort sauf chambres parents", "id": 5, "type": 4, "rooms_temp": [ { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "1662974901", "therm_setpoint_fp": "comfort" }, { "room_id": "2042969726", "therm_setpoint_fp": "comfort" }, { "room_id": "3435163850", "therm_setpoint_fp": "comfort" }, { "room_id": "3497055021", "therm_setpoint_fp": "comfort" }, { "room_id": "3707962039", "therm_setpoint_fp": "comfort" }, { "room_id": "3795659199", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "comfort" }, { "room_id": "873035982", "therm_setpoint_fp": "comfort" }, { "room_id": "927970817", "therm_setpoint_fp": "frost_guard" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "comfort" } ], "modules": [], "rooms": [ { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "1662974901", "therm_setpoint_fp": "comfort" }, { "id": "2042969726", "therm_setpoint_fp": "comfort" }, { "id": "3435163850", "therm_setpoint_fp": "comfort" }, { "id": "3497055021", "therm_setpoint_fp": "comfort" }, { "id": "3707962039", "therm_setpoint_fp": "comfort" }, { "id": "3795659199", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "comfort" }, { "id": "873035982", "therm_setpoint_fp": "comfort" }, { "id": "927970817", "therm_setpoint_fp": "frost_guard" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "comfort" } ] }, { "name": "Chambre parents only", "id": 2, "type": 4, "rooms_temp": [ { "room_id": "1641945290", "therm_setpoint_fp": "frost_guard" }, { "room_id": "1662974901", "therm_setpoint_fp": "comfort" }, { "room_id": "2042969726", "therm_setpoint_fp": "away" }, { "room_id": "3435163850", "therm_setpoint_fp": "comfort" }, { "room_id": "3497055021", "therm_setpoint_fp": "away" }, { "room_id": "3707962039", "therm_setpoint_fp": "away" }, { "room_id": "3795659199", "therm_setpoint_fp": "away" }, { "room_id": "596817675", "therm_setpoint_fp": "away" }, { "room_id": "873035982", "therm_setpoint_fp": "away" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "93888250", "therm_setpoint_fp": "frost_guard" }, { "room_id": "2102454491", "therm_setpoint_fp": "comfort" } ], "modules": [], "rooms": [ { "id": "1641945290", "therm_setpoint_fp": "frost_guard" }, { "id": "1662974901", "therm_setpoint_fp": "comfort" }, { "id": "2042969726", "therm_setpoint_fp": "away" }, { "id": "3435163850", "therm_setpoint_fp": "comfort" }, { "id": "3497055021", "therm_setpoint_fp": "away" }, { "id": "3707962039", "therm_setpoint_fp": "away" }, { "id": "3795659199", "therm_setpoint_fp": "away" }, { "id": "596817675", "therm_setpoint_fp": "away" }, { "id": "873035982", "therm_setpoint_fp": "away" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "93888250", "therm_setpoint_fp": "frost_guard" }, { "id": "2102454491", "therm_setpoint_fp": "comfort" } ] } ], "name": "Planning Hiver", "default": false, "away_temp": 12, "hg_temp": 7, "id": "61fa621cdd99943657260882", "type": "therm", "selected": true }, { "timetable": [ { "zone_id": 2, "m_offset": 0 } ], "zones": [ { "name": "Comfort", "id": 0, "type": 0, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "comfort" }, { "room_id": "2042969726", "therm_setpoint_fp": "comfort" }, { "room_id": "3497055021", "therm_setpoint_fp": "comfort" }, { "room_id": "3435163850", "therm_setpoint_fp": "comfort" }, { "room_id": "873035982", "therm_setpoint_fp": "comfort" }, { "room_id": "1662974901", "therm_setpoint_fp": "comfort" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "comfort" }, { "room_id": "3795659199", "therm_setpoint_fp": "comfort" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "comfort" } ], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "comfort" }, { "id": "2042969726", "therm_setpoint_fp": "comfort" }, { "id": "3497055021", "therm_setpoint_fp": "comfort" }, { "id": "3435163850", "therm_setpoint_fp": "comfort" }, { "id": "873035982", "therm_setpoint_fp": "comfort" }, { "id": "1662974901", "therm_setpoint_fp": "comfort" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "comfort" }, { "id": "3795659199", "therm_setpoint_fp": "comfort" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "comfort" } ] }, { "name": "Comfort+", "id": 3, "type": 8, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "comfort" }, { "room_id": "2042969726", "therm_setpoint_fp": "comfort" }, { "room_id": "3497055021", "therm_setpoint_fp": "comfort" }, { "room_id": "3435163850", "therm_setpoint_fp": "comfort" }, { "room_id": "873035982", "therm_setpoint_fp": "comfort" }, { "room_id": "1662974901", "therm_setpoint_fp": "comfort" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "comfort" }, { "room_id": "3795659199", "therm_setpoint_fp": "comfort" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "comfort" } ], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "comfort" }, { "id": "2042969726", "therm_setpoint_fp": "comfort" }, { "id": "3497055021", "therm_setpoint_fp": "comfort" }, { "id": "3435163850", "therm_setpoint_fp": "comfort" }, { "id": "873035982", "therm_setpoint_fp": "comfort" }, { "id": "1662974901", "therm_setpoint_fp": "comfort" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "comfort" }, { "id": "3795659199", "therm_setpoint_fp": "comfort" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "comfort" } ] }, { "name": "Éco", "id": 4, "type": 5, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "away" }, { "room_id": "2042969726", "therm_setpoint_fp": "away" }, { "room_id": "3497055021", "therm_setpoint_fp": "away" }, { "room_id": "3435163850", "therm_setpoint_fp": "away" }, { "room_id": "873035982", "therm_setpoint_fp": "away" }, { "room_id": "1662974901", "therm_setpoint_fp": "away" }, { "room_id": "93888250", "therm_setpoint_fp": "away" }, { "room_id": "596817675", "therm_setpoint_fp": "away" }, { "room_id": "3795659199", "therm_setpoint_fp": "away" }, { "room_id": "927970817", "therm_setpoint_fp": "away" }, { "room_id": "1641945290", "therm_setpoint_fp": "away" }, { "room_id": "2102454491", "therm_setpoint_fp": "away" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "away" }, { "id": "2042969726", "therm_setpoint_fp": "away" }, { "id": "3497055021", "therm_setpoint_fp": "away" }, { "id": "3435163850", "therm_setpoint_fp": "away" }, { "id": "873035982", "therm_setpoint_fp": "away" }, { "id": "1662974901", "therm_setpoint_fp": "away" }, { "id": "93888250", "therm_setpoint_fp": "away" }, { "id": "596817675", "therm_setpoint_fp": "away" }, { "id": "3795659199", "therm_setpoint_fp": "away" }, { "id": "927970817", "therm_setpoint_fp": "away" }, { "id": "1641945290", "therm_setpoint_fp": "away" }, { "id": "2102454491", "therm_setpoint_fp": "away" } ] }, { "name": "Nuit", "id": 1, "type": 1, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "room_id": "2042969726", "therm_setpoint_fp": "frost_guard" }, { "room_id": "3497055021", "therm_setpoint_fp": "frost_guard" }, { "room_id": "3435163850", "therm_setpoint_fp": "frost_guard" }, { "room_id": "873035982", "therm_setpoint_fp": "frost_guard" }, { "room_id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "room_id": "93888250", "therm_setpoint_fp": "away" }, { "room_id": "596817675", "therm_setpoint_fp": "away" }, { "room_id": "3795659199", "therm_setpoint_fp": "frost_guard" }, { "room_id": "927970817", "therm_setpoint_fp": "away" }, { "room_id": "1641945290", "therm_setpoint_fp": "away" }, { "room_id": "2102454491", "therm_setpoint_fp": "frost_guard" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "id": "2042969726", "therm_setpoint_fp": "frost_guard" }, { "id": "3497055021", "therm_setpoint_fp": "frost_guard" }, { "id": "3435163850", "therm_setpoint_fp": "frost_guard" }, { "id": "873035982", "therm_setpoint_fp": "frost_guard" }, { "id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "id": "93888250", "therm_setpoint_fp": "away" }, { "id": "596817675", "therm_setpoint_fp": "away" }, { "id": "3795659199", "therm_setpoint_fp": "frost_guard" }, { "id": "927970817", "therm_setpoint_fp": "away" }, { "id": "1641945290", "therm_setpoint_fp": "away" }, { "id": "2102454491", "therm_setpoint_fp": "frost_guard" } ] }, { "name": "Off", "id": 2, "type": 4, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "room_id": "2042969726", "therm_setpoint_fp": "frost_guard" }, { "room_id": "3497055021", "therm_setpoint_fp": "frost_guard" }, { "room_id": "3435163850", "therm_setpoint_fp": "frost_guard" }, { "room_id": "873035982", "therm_setpoint_fp": "frost_guard" }, { "room_id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "comfort" }, { "room_id": "3795659199", "therm_setpoint_fp": "frost_guard" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "frost_guard" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "id": "2042969726", "therm_setpoint_fp": "frost_guard" }, { "id": "3497055021", "therm_setpoint_fp": "frost_guard" }, { "id": "3435163850", "therm_setpoint_fp": "frost_guard" }, { "id": "873035982", "therm_setpoint_fp": "frost_guard" }, { "id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "comfort" }, { "id": "3795659199", "therm_setpoint_fp": "frost_guard" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "frost_guard" } ] } ], "name": "Planning ete", "default": false, "away_temp": 12, "hg_temp": 7, "id": "625a76ceec2cce72075ac55a", "type": "therm" }, { "timetable": [ { "zone_id": 0, "m_offset": 0 } ], "zones": [ { "name": "Comfort", "id": 0, "type": 0, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "comfort" }, { "room_id": "2042969726", "therm_setpoint_fp": "comfort" }, { "room_id": "3497055021", "therm_setpoint_fp": "comfort" }, { "room_id": "3435163850", "therm_setpoint_fp": "comfort" }, { "room_id": "873035982", "therm_setpoint_fp": "comfort" }, { "room_id": "1662974901", "therm_setpoint_fp": "comfort" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "comfort" }, { "room_id": "3795659199", "therm_setpoint_fp": "comfort" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "comfort" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "comfort" }, { "id": "2042969726", "therm_setpoint_fp": "comfort" }, { "id": "3497055021", "therm_setpoint_fp": "comfort" }, { "id": "3435163850", "therm_setpoint_fp": "comfort" }, { "id": "873035982", "therm_setpoint_fp": "comfort" }, { "id": "1662974901", "therm_setpoint_fp": "comfort" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "comfort" }, { "id": "3795659199", "therm_setpoint_fp": "comfort" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "comfort" } ] }, { "name": "Night", "id": 1, "type": 1, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "away" }, { "room_id": "2042969726", "therm_setpoint_fp": "away" }, { "room_id": "3497055021", "therm_setpoint_fp": "away" }, { "room_id": "3435163850", "therm_setpoint_fp": "away" }, { "room_id": "873035982", "therm_setpoint_fp": "away" }, { "room_id": "1662974901", "therm_setpoint_fp": "away" }, { "room_id": "93888250", "therm_setpoint_fp": "away" }, { "room_id": "596817675", "therm_setpoint_fp": "away" }, { "room_id": "3795659199", "therm_setpoint_fp": "away" }, { "room_id": "927970817", "therm_setpoint_fp": "away" }, { "room_id": "1641945290", "therm_setpoint_fp": "away" }, { "room_id": "2102454491", "therm_setpoint_fp": "away" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "away" }, { "id": "2042969726", "therm_setpoint_fp": "away" }, { "id": "3497055021", "therm_setpoint_fp": "away" }, { "id": "3435163850", "therm_setpoint_fp": "away" }, { "id": "873035982", "therm_setpoint_fp": "away" }, { "id": "1662974901", "therm_setpoint_fp": "away" }, { "id": "93888250", "therm_setpoint_fp": "away" }, { "id": "596817675", "therm_setpoint_fp": "away" }, { "id": "3795659199", "therm_setpoint_fp": "away" }, { "id": "927970817", "therm_setpoint_fp": "away" }, { "id": "1641945290", "therm_setpoint_fp": "away" }, { "id": "2102454491", "therm_setpoint_fp": "away" } ] }, { "name": "Comfort+", "id": 3, "type": 8, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "comfort" }, { "room_id": "2042969726", "therm_setpoint_fp": "comfort" }, { "room_id": "3497055021", "therm_setpoint_fp": "comfort" }, { "room_id": "3435163850", "therm_setpoint_fp": "comfort" }, { "room_id": "873035982", "therm_setpoint_fp": "comfort" }, { "room_id": "1662974901", "therm_setpoint_fp": "comfort" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "comfort" }, { "room_id": "3795659199", "therm_setpoint_fp": "comfort" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "comfort" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "comfort" }, { "id": "2042969726", "therm_setpoint_fp": "comfort" }, { "id": "3497055021", "therm_setpoint_fp": "comfort" }, { "id": "3435163850", "therm_setpoint_fp": "comfort" }, { "id": "873035982", "therm_setpoint_fp": "comfort" }, { "id": "1662974901", "therm_setpoint_fp": "comfort" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "comfort" }, { "id": "3795659199", "therm_setpoint_fp": "comfort" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "comfort" } ] }, { "name": "Eco", "id": 4, "type": 5, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "away" }, { "room_id": "2042969726", "therm_setpoint_fp": "away" }, { "room_id": "3497055021", "therm_setpoint_fp": "away" }, { "room_id": "3435163850", "therm_setpoint_fp": "away" }, { "room_id": "873035982", "therm_setpoint_fp": "away" }, { "room_id": "1662974901", "therm_setpoint_fp": "away" }, { "room_id": "93888250", "therm_setpoint_fp": "away" }, { "room_id": "596817675", "therm_setpoint_fp": "away" }, { "room_id": "3795659199", "therm_setpoint_fp": "away" }, { "room_id": "927970817", "therm_setpoint_fp": "away" }, { "room_id": "1641945290", "therm_setpoint_fp": "away" }, { "room_id": "2102454491", "therm_setpoint_fp": "away" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "away" }, { "id": "2042969726", "therm_setpoint_fp": "away" }, { "id": "3497055021", "therm_setpoint_fp": "away" }, { "id": "3435163850", "therm_setpoint_fp": "away" }, { "id": "873035982", "therm_setpoint_fp": "away" }, { "id": "1662974901", "therm_setpoint_fp": "away" }, { "id": "93888250", "therm_setpoint_fp": "away" }, { "id": "596817675", "therm_setpoint_fp": "away" }, { "id": "3795659199", "therm_setpoint_fp": "away" }, { "id": "927970817", "therm_setpoint_fp": "away" }, { "id": "1641945290", "therm_setpoint_fp": "away" }, { "id": "2102454491", "therm_setpoint_fp": "away" } ] } ], "name": "Full", "default": false, "away_temp": 12, "hg_temp": 7, "id": "63a44ba0735ffc27410f2331", "type": "therm" }, { "timetable": [ { "zone_id": 4, "m_offset": 0 }, { "zone_id": 0, "m_offset": 300 }, { "zone_id": 4, "m_offset": 420 }, { "zone_id": 0, "m_offset": 855 }, { "zone_id": 4, "m_offset": 1140 }, { "zone_id": 0, "m_offset": 1740 }, { "zone_id": 4, "m_offset": 1860 }, { "zone_id": 0, "m_offset": 2295 }, { "zone_id": 4, "m_offset": 2580 }, { "zone_id": 0, "m_offset": 3180 }, { "zone_id": 4, "m_offset": 3300 }, { "zone_id": 0, "m_offset": 3735 }, { "zone_id": 4, "m_offset": 4020 }, { "zone_id": 0, "m_offset": 4620 }, { "zone_id": 4, "m_offset": 4740 }, { "zone_id": 0, "m_offset": 5175 }, { "zone_id": 4, "m_offset": 5460 }, { "zone_id": 0, "m_offset": 6060 }, { "zone_id": 4, "m_offset": 6180 }, { "zone_id": 0, "m_offset": 6615 }, { "zone_id": 4, "m_offset": 6900 }, { "zone_id": 0, "m_offset": 7500 }, { "zone_id": 4, "m_offset": 7620 }, { "zone_id": 0, "m_offset": 8055 }, { "zone_id": 4, "m_offset": 8340 }, { "zone_id": 0, "m_offset": 8940 }, { "zone_id": 4, "m_offset": 9060 }, { "zone_id": 0, "m_offset": 9495 }, { "zone_id": 4, "m_offset": 9780 } ], "zones": [ { "name": "Comfort", "id": 0, "type": 0, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "comfort" }, { "room_id": "2042969726", "therm_setpoint_fp": "comfort" }, { "room_id": "3497055021", "therm_setpoint_fp": "comfort" }, { "room_id": "3435163850", "therm_setpoint_fp": "comfort" }, { "room_id": "873035982", "therm_setpoint_fp": "comfort" }, { "room_id": "1662974901", "therm_setpoint_fp": "comfort" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "comfort" }, { "room_id": "3795659199", "therm_setpoint_fp": "comfort" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "comfort" } ], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "comfort" }, { "id": "2042969726", "therm_setpoint_fp": "comfort" }, { "id": "3497055021", "therm_setpoint_fp": "comfort" }, { "id": "3435163850", "therm_setpoint_fp": "comfort" }, { "id": "873035982", "therm_setpoint_fp": "comfort" }, { "id": "1662974901", "therm_setpoint_fp": "comfort" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "comfort" }, { "id": "3795659199", "therm_setpoint_fp": "comfort" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "comfort" } ] }, { "name": "Comfort+", "id": 3, "type": 8, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "comfort" }, { "room_id": "2042969726", "therm_setpoint_fp": "comfort" }, { "room_id": "3497055021", "therm_setpoint_fp": "comfort" }, { "room_id": "3435163850", "therm_setpoint_fp": "comfort" }, { "room_id": "873035982", "therm_setpoint_fp": "comfort" }, { "room_id": "1662974901", "therm_setpoint_fp": "comfort" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "comfort" }, { "room_id": "3795659199", "therm_setpoint_fp": "comfort" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "comfort" } ], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "comfort" }, { "id": "2042969726", "therm_setpoint_fp": "comfort" }, { "id": "3497055021", "therm_setpoint_fp": "comfort" }, { "id": "3435163850", "therm_setpoint_fp": "comfort" }, { "id": "873035982", "therm_setpoint_fp": "comfort" }, { "id": "1662974901", "therm_setpoint_fp": "comfort" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "comfort" }, { "id": "3795659199", "therm_setpoint_fp": "comfort" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "comfort" } ] }, { "name": "Éco", "id": 4, "type": 5, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "away" }, { "room_id": "2042969726", "therm_setpoint_fp": "away" }, { "room_id": "3497055021", "therm_setpoint_fp": "away" }, { "room_id": "3435163850", "therm_setpoint_fp": "away" }, { "room_id": "873035982", "therm_setpoint_fp": "away" }, { "room_id": "1662974901", "therm_setpoint_fp": "away" }, { "room_id": "93888250", "therm_setpoint_fp": "away" }, { "room_id": "596817675", "therm_setpoint_fp": "away" }, { "room_id": "3795659199", "therm_setpoint_fp": "away" }, { "room_id": "927970817", "therm_setpoint_fp": "away" }, { "room_id": "1641945290", "therm_setpoint_fp": "away" }, { "room_id": "2102454491", "therm_setpoint_fp": "away" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "away" }, { "id": "2042969726", "therm_setpoint_fp": "away" }, { "id": "3497055021", "therm_setpoint_fp": "away" }, { "id": "3435163850", "therm_setpoint_fp": "away" }, { "id": "873035982", "therm_setpoint_fp": "away" }, { "id": "1662974901", "therm_setpoint_fp": "away" }, { "id": "93888250", "therm_setpoint_fp": "away" }, { "id": "596817675", "therm_setpoint_fp": "away" }, { "id": "3795659199", "therm_setpoint_fp": "away" }, { "id": "927970817", "therm_setpoint_fp": "away" }, { "id": "1641945290", "therm_setpoint_fp": "away" }, { "id": "2102454491", "therm_setpoint_fp": "away" } ] }, { "name": "Nuit", "id": 1, "type": 1, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "room_id": "2042969726", "therm_setpoint_fp": "frost_guard" }, { "room_id": "3497055021", "therm_setpoint_fp": "frost_guard" }, { "room_id": "3435163850", "therm_setpoint_fp": "frost_guard" }, { "room_id": "873035982", "therm_setpoint_fp": "frost_guard" }, { "room_id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "room_id": "93888250", "therm_setpoint_fp": "away" }, { "room_id": "596817675", "therm_setpoint_fp": "away" }, { "room_id": "3795659199", "therm_setpoint_fp": "frost_guard" }, { "room_id": "927970817", "therm_setpoint_fp": "away" }, { "room_id": "1641945290", "therm_setpoint_fp": "away" }, { "room_id": "2102454491", "therm_setpoint_fp": "frost_guard" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "id": "2042969726", "therm_setpoint_fp": "frost_guard" }, { "id": "3497055021", "therm_setpoint_fp": "frost_guard" }, { "id": "3435163850", "therm_setpoint_fp": "frost_guard" }, { "id": "873035982", "therm_setpoint_fp": "frost_guard" }, { "id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "id": "93888250", "therm_setpoint_fp": "away" }, { "id": "596817675", "therm_setpoint_fp": "away" }, { "id": "3795659199", "therm_setpoint_fp": "frost_guard" }, { "id": "927970817", "therm_setpoint_fp": "away" }, { "id": "1641945290", "therm_setpoint_fp": "away" }, { "id": "2102454491", "therm_setpoint_fp": "frost_guard" } ] } ], "name": "Planning Hiver frileux", "default": false, "away_temp": 12, "hg_temp": 7, "id": "63c5b63b766611525b0b1e4d", "type": "therm" }, { "timetable": [ { "zone_id": 1, "m_offset": 0 }, { "zone_id": 0, "m_offset": 300 }, { "zone_id": 4, "m_offset": 420 }, { "zone_id": 0, "m_offset": 1020 }, { "zone_id": 1, "m_offset": 1140 }, { "zone_id": 0, "m_offset": 1740 }, { "zone_id": 4, "m_offset": 1860 }, { "zone_id": 0, "m_offset": 2460 }, { "zone_id": 1, "m_offset": 2580 }, { "zone_id": 0, "m_offset": 3180 }, { "zone_id": 4, "m_offset": 3300 }, { "zone_id": 0, "m_offset": 3900 }, { "zone_id": 1, "m_offset": 4020 }, { "zone_id": 0, "m_offset": 4620 }, { "zone_id": 4, "m_offset": 4740 }, { "zone_id": 0, "m_offset": 5340 }, { "zone_id": 1, "m_offset": 5460 }, { "zone_id": 0, "m_offset": 6060 }, { "zone_id": 4, "m_offset": 6180 }, { "zone_id": 0, "m_offset": 6780 }, { "zone_id": 1, "m_offset": 6900 }, { "zone_id": 0, "m_offset": 7560 }, { "zone_id": 4, "m_offset": 7680 }, { "zone_id": 0, "m_offset": 8220 }, { "zone_id": 1, "m_offset": 8340 }, { "zone_id": 0, "m_offset": 9000 }, { "zone_id": 4, "m_offset": 9120 }, { "zone_id": 0, "m_offset": 9660 }, { "zone_id": 1, "m_offset": 9780 } ], "zones": [ { "name": "Comfort+", "id": 3, "type": 8, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "comfort" }, { "room_id": "2042969726", "therm_setpoint_fp": "comfort" }, { "room_id": "3497055021", "therm_setpoint_fp": "comfort" }, { "room_id": "3435163850", "therm_setpoint_fp": "comfort" }, { "room_id": "873035982", "therm_setpoint_fp": "comfort" }, { "room_id": "1662974901", "therm_setpoint_fp": "comfort" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "comfort" }, { "room_id": "3795659199", "therm_setpoint_fp": "comfort" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "comfort" } ], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "comfort" }, { "id": "2042969726", "therm_setpoint_fp": "comfort" }, { "id": "3497055021", "therm_setpoint_fp": "comfort" }, { "id": "3435163850", "therm_setpoint_fp": "comfort" }, { "id": "873035982", "therm_setpoint_fp": "comfort" }, { "id": "1662974901", "therm_setpoint_fp": "comfort" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "comfort" }, { "id": "3795659199", "therm_setpoint_fp": "comfort" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "comfort" } ] }, { "name": "Nuit", "id": 1, "type": 1, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "room_id": "2042969726", "therm_setpoint_fp": "away" }, { "room_id": "3497055021", "therm_setpoint_fp": "away" }, { "room_id": "3435163850", "therm_setpoint_fp": "away" }, { "room_id": "873035982", "therm_setpoint_fp": "away" }, { "room_id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "room_id": "93888250", "therm_setpoint_fp": "frost_guard" }, { "room_id": "596817675", "therm_setpoint_fp": "frost_guard" }, { "room_id": "3795659199", "therm_setpoint_fp": "away" }, { "room_id": "927970817", "therm_setpoint_fp": "frost_guard" }, { "room_id": "1641945290", "therm_setpoint_fp": "frost_guard" }, { "room_id": "2102454491", "therm_setpoint_fp": "frost_guard" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "id": "2042969726", "therm_setpoint_fp": "away" }, { "id": "3497055021", "therm_setpoint_fp": "away" }, { "id": "3435163850", "therm_setpoint_fp": "away" }, { "id": "873035982", "therm_setpoint_fp": "away" }, { "id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "id": "93888250", "therm_setpoint_fp": "frost_guard" }, { "id": "596817675", "therm_setpoint_fp": "frost_guard" }, { "id": "3795659199", "therm_setpoint_fp": "away" }, { "id": "927970817", "therm_setpoint_fp": "frost_guard" }, { "id": "1641945290", "therm_setpoint_fp": "frost_guard" }, { "id": "2102454491", "therm_setpoint_fp": "frost_guard" } ] }, { "name": "Confort", "id": 0, "type": 0, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "room_id": "2042969726", "therm_setpoint_fp": "comfort" }, { "room_id": "3497055021", "therm_setpoint_fp": "comfort" }, { "room_id": "3435163850", "therm_setpoint_fp": "comfort" }, { "room_id": "873035982", "therm_setpoint_fp": "comfort" }, { "room_id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "frost_guard" }, { "room_id": "3795659199", "therm_setpoint_fp": "comfort" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "frost_guard" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "id": "2042969726", "therm_setpoint_fp": "comfort" }, { "id": "3497055021", "therm_setpoint_fp": "comfort" }, { "id": "3435163850", "therm_setpoint_fp": "comfort" }, { "id": "873035982", "therm_setpoint_fp": "comfort" }, { "id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "frost_guard" }, { "id": "3795659199", "therm_setpoint_fp": "comfort" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "frost_guard" } ] }, { "name": "Éco", "id": 4, "type": 5, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "room_id": "2042969726", "therm_setpoint_fp": "away" }, { "room_id": "3497055021", "therm_setpoint_fp": "away" }, { "room_id": "3435163850", "therm_setpoint_fp": "away" }, { "room_id": "873035982", "therm_setpoint_fp": "away" }, { "room_id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "room_id": "93888250", "therm_setpoint_fp": "frost_guard" }, { "room_id": "596817675", "therm_setpoint_fp": "frost_guard" }, { "room_id": "3795659199", "therm_setpoint_fp": "away" }, { "room_id": "927970817", "therm_setpoint_fp": "frost_guard" }, { "room_id": "1641945290", "therm_setpoint_fp": "frost_guard" }, { "room_id": "2102454491", "therm_setpoint_fp": "frost_guard" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "id": "2042969726", "therm_setpoint_fp": "away" }, { "id": "3497055021", "therm_setpoint_fp": "away" }, { "id": "3435163850", "therm_setpoint_fp": "away" }, { "id": "873035982", "therm_setpoint_fp": "away" }, { "id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "id": "93888250", "therm_setpoint_fp": "frost_guard" }, { "id": "596817675", "therm_setpoint_fp": "frost_guard" }, { "id": "3795659199", "therm_setpoint_fp": "away" }, { "id": "927970817", "therm_setpoint_fp": "frost_guard" }, { "id": "1641945290", "therm_setpoint_fp": "frost_guard" }, { "id": "2102454491", "therm_setpoint_fp": "frost_guard" } ] } ], "name": "Chambres et SDB", "default": false, "away_temp": 12, "hg_temp": 7, "id": "6413ac548decf9f28b0efc4e", "type": "therm" }, { "timetable": [ { "zone_id": 5, "m_offset": 0 }, { "zone_id": 2, "m_offset": 360 }, { "zone_id": 5, "m_offset": 450 }, { "zone_id": 2, "m_offset": 1020 }, { "zone_id": 5, "m_offset": 1080 }, { "zone_id": 2, "m_offset": 1800 }, { "zone_id": 5, "m_offset": 1890 }, { "zone_id": 2, "m_offset": 2460 }, { "zone_id": 5, "m_offset": 2520 }, { "zone_id": 2, "m_offset": 3240 }, { "zone_id": 5, "m_offset": 3330 }, { "zone_id": 2, "m_offset": 3900 }, { "zone_id": 5, "m_offset": 3960 }, { "zone_id": 2, "m_offset": 4680 }, { "zone_id": 5, "m_offset": 4770 }, { "zone_id": 2, "m_offset": 5340 }, { "zone_id": 5, "m_offset": 5400 }, { "zone_id": 2, "m_offset": 6120 }, { "zone_id": 5, "m_offset": 6210 }, { "zone_id": 2, "m_offset": 6780 }, { "zone_id": 5, "m_offset": 6840 }, { "zone_id": 2, "m_offset": 7680 }, { "zone_id": 5, "m_offset": 7740 }, { "zone_id": 2, "m_offset": 8220 }, { "zone_id": 5, "m_offset": 8280 }, { "zone_id": 2, "m_offset": 9120 }, { "zone_id": 5, "m_offset": 9180 }, { "zone_id": 2, "m_offset": 9660 }, { "zone_id": 5, "m_offset": 9720 } ], "zones": [ { "name": "Comfort", "id": 0, "type": 0, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "comfort" }, { "room_id": "2042969726", "therm_setpoint_fp": "comfort" }, { "room_id": "3497055021", "therm_setpoint_fp": "comfort" }, { "room_id": "3435163850", "therm_setpoint_fp": "comfort" }, { "room_id": "873035982", "therm_setpoint_fp": "comfort" }, { "room_id": "1662974901", "therm_setpoint_fp": "comfort" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "comfort" }, { "room_id": "3795659199", "therm_setpoint_fp": "comfort" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "comfort" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "comfort" }, { "id": "2042969726", "therm_setpoint_fp": "comfort" }, { "id": "3497055021", "therm_setpoint_fp": "comfort" }, { "id": "3435163850", "therm_setpoint_fp": "comfort" }, { "id": "873035982", "therm_setpoint_fp": "comfort" }, { "id": "1662974901", "therm_setpoint_fp": "comfort" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "comfort" }, { "id": "3795659199", "therm_setpoint_fp": "comfort" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "comfort" } ] }, { "name": "Night", "id": 1, "type": 1, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "away" }, { "room_id": "2042969726", "therm_setpoint_fp": "away" }, { "room_id": "3497055021", "therm_setpoint_fp": "away" }, { "room_id": "3435163850", "therm_setpoint_fp": "away" }, { "room_id": "873035982", "therm_setpoint_fp": "away" }, { "room_id": "1662974901", "therm_setpoint_fp": "away" }, { "room_id": "93888250", "therm_setpoint_fp": "away" }, { "room_id": "596817675", "therm_setpoint_fp": "away" }, { "room_id": "3795659199", "therm_setpoint_fp": "away" }, { "room_id": "927970817", "therm_setpoint_fp": "away" }, { "room_id": "1641945290", "therm_setpoint_fp": "away" }, { "room_id": "2102454491", "therm_setpoint_fp": "away" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "away" }, { "id": "2042969726", "therm_setpoint_fp": "away" }, { "id": "3497055021", "therm_setpoint_fp": "away" }, { "id": "3435163850", "therm_setpoint_fp": "away" }, { "id": "873035982", "therm_setpoint_fp": "away" }, { "id": "1662974901", "therm_setpoint_fp": "away" }, { "id": "93888250", "therm_setpoint_fp": "away" }, { "id": "596817675", "therm_setpoint_fp": "away" }, { "id": "3795659199", "therm_setpoint_fp": "away" }, { "id": "927970817", "therm_setpoint_fp": "away" }, { "id": "1641945290", "therm_setpoint_fp": "away" }, { "id": "2102454491", "therm_setpoint_fp": "away" } ] }, { "name": "Comfort+", "id": 3, "type": 8, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "comfort" }, { "room_id": "2042969726", "therm_setpoint_fp": "comfort" }, { "room_id": "3497055021", "therm_setpoint_fp": "comfort" }, { "room_id": "3435163850", "therm_setpoint_fp": "comfort" }, { "room_id": "873035982", "therm_setpoint_fp": "comfort" }, { "room_id": "1662974901", "therm_setpoint_fp": "comfort" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "comfort" }, { "room_id": "3795659199", "therm_setpoint_fp": "comfort" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "comfort" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "comfort" }, { "id": "2042969726", "therm_setpoint_fp": "comfort" }, { "id": "3497055021", "therm_setpoint_fp": "comfort" }, { "id": "3435163850", "therm_setpoint_fp": "comfort" }, { "id": "873035982", "therm_setpoint_fp": "comfort" }, { "id": "1662974901", "therm_setpoint_fp": "comfort" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "comfort" }, { "id": "3795659199", "therm_setpoint_fp": "comfort" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "comfort" } ] }, { "name": "Eco", "id": 4, "type": 5, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "away" }, { "room_id": "2042969726", "therm_setpoint_fp": "away" }, { "room_id": "3497055021", "therm_setpoint_fp": "away" }, { "room_id": "3435163850", "therm_setpoint_fp": "away" }, { "room_id": "873035982", "therm_setpoint_fp": "away" }, { "room_id": "1662974901", "therm_setpoint_fp": "away" }, { "room_id": "93888250", "therm_setpoint_fp": "away" }, { "room_id": "596817675", "therm_setpoint_fp": "away" }, { "room_id": "3795659199", "therm_setpoint_fp": "away" }, { "room_id": "927970817", "therm_setpoint_fp": "away" }, { "room_id": "1641945290", "therm_setpoint_fp": "away" }, { "room_id": "2102454491", "therm_setpoint_fp": "away" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "away" }, { "id": "2042969726", "therm_setpoint_fp": "away" }, { "id": "3497055021", "therm_setpoint_fp": "away" }, { "id": "3435163850", "therm_setpoint_fp": "away" }, { "id": "873035982", "therm_setpoint_fp": "away" }, { "id": "1662974901", "therm_setpoint_fp": "away" }, { "id": "93888250", "therm_setpoint_fp": "away" }, { "id": "596817675", "therm_setpoint_fp": "away" }, { "id": "3795659199", "therm_setpoint_fp": "away" }, { "id": "927970817", "therm_setpoint_fp": "away" }, { "id": "1641945290", "therm_setpoint_fp": "away" }, { "id": "2102454491", "therm_setpoint_fp": "away" } ] }, { "name": "SDB seulement", "id": 2, "type": 4, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "room_id": "2042969726", "therm_setpoint_fp": "frost_guard" }, { "room_id": "3497055021", "therm_setpoint_fp": "frost_guard" }, { "room_id": "3435163850", "therm_setpoint_fp": "frost_guard" }, { "room_id": "873035982", "therm_setpoint_fp": "frost_guard" }, { "room_id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "comfort" }, { "room_id": "3795659199", "therm_setpoint_fp": "frost_guard" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "frost_guard" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "id": "2042969726", "therm_setpoint_fp": "frost_guard" }, { "id": "3497055021", "therm_setpoint_fp": "frost_guard" }, { "id": "3435163850", "therm_setpoint_fp": "frost_guard" }, { "id": "873035982", "therm_setpoint_fp": "frost_guard" }, { "id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "comfort" }, { "id": "3795659199", "therm_setpoint_fp": "frost_guard" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "frost_guard" } ] }, { "name": "Tout Off", "id": 5, "type": 4, "rooms_temp": [ { "room_id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "room_id": "2042969726", "therm_setpoint_fp": "frost_guard" }, { "room_id": "3497055021", "therm_setpoint_fp": "frost_guard" }, { "room_id": "3435163850", "therm_setpoint_fp": "frost_guard" }, { "room_id": "873035982", "therm_setpoint_fp": "frost_guard" }, { "room_id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "comfort" }, { "room_id": "3795659199", "therm_setpoint_fp": "frost_guard" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "frost_guard" } ], "modules": [], "rooms": [ { "id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "id": "2042969726", "therm_setpoint_fp": "frost_guard" }, { "id": "3497055021", "therm_setpoint_fp": "frost_guard" }, { "id": "3435163850", "therm_setpoint_fp": "frost_guard" }, { "id": "873035982", "therm_setpoint_fp": "frost_guard" }, { "id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "comfort" }, { "id": "3795659199", "therm_setpoint_fp": "frost_guard" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "frost_guard" } ] }, { "name": "Chambres Confort and All Off", "id": 6, "type": 4, "rooms_temp": [ { "room_id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "room_id": "2042969726", "therm_setpoint_fp": "comfort" }, { "room_id": "3435163850", "therm_setpoint_fp": "comfort" }, { "room_id": "3497055021", "therm_setpoint_fp": "comfort" }, { "room_id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "room_id": "3795659199", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "frost_guard" }, { "room_id": "873035982", "therm_setpoint_fp": "comfort" }, { "room_id": "93888250", "therm_setpoint_fp": "frost_guard" }, { "room_id": "927970817", "therm_setpoint_fp": "frost_guard" }, { "room_id": "1641945290", "therm_setpoint_fp": "frost_guard" }, { "room_id": "2102454491", "therm_setpoint_fp": "frost_guard" } ], "modules": [], "rooms": [ { "id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "id": "2042969726", "therm_setpoint_fp": "comfort" }, { "id": "3435163850", "therm_setpoint_fp": "comfort" }, { "id": "3497055021", "therm_setpoint_fp": "comfort" }, { "id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "id": "3795659199", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "frost_guard" }, { "id": "873035982", "therm_setpoint_fp": "comfort" }, { "id": "93888250", "therm_setpoint_fp": "frost_guard" }, { "id": "927970817", "therm_setpoint_fp": "frost_guard" }, { "id": "1641945290", "therm_setpoint_fp": "frost_guard" }, { "id": "2102454491", "therm_setpoint_fp": "frost_guard" } ] }, { "name": "Chambres Eco and all Off", "id": 7, "type": 4, "rooms_temp": [ { "room_id": "1662974901", "therm_setpoint_fp": "comfort" }, { "room_id": "2042969726", "therm_setpoint_fp": "away" }, { "room_id": "3435163850", "therm_setpoint_fp": "away" }, { "room_id": "3497055021", "therm_setpoint_fp": "away" }, { "room_id": "3707962039", "therm_setpoint_fp": "comfort" }, { "room_id": "3795659199", "therm_setpoint_fp": "away" }, { "room_id": "596817675", "therm_setpoint_fp": "comfort" }, { "room_id": "873035982", "therm_setpoint_fp": "away" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "comfort" } ], "modules": [], "rooms": [ { "id": "1662974901", "therm_setpoint_fp": "comfort" }, { "id": "2042969726", "therm_setpoint_fp": "away" }, { "id": "3435163850", "therm_setpoint_fp": "away" }, { "id": "3497055021", "therm_setpoint_fp": "away" }, { "id": "3707962039", "therm_setpoint_fp": "comfort" }, { "id": "3795659199", "therm_setpoint_fp": "away" }, { "id": "596817675", "therm_setpoint_fp": "comfort" }, { "id": "873035982", "therm_setpoint_fp": "away" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "comfort" } ] }, { "name": "Chambres Eco SDB Confort All OFF", "id": 8, "type": 4, "rooms_temp": [ { "room_id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "room_id": "2042969726", "therm_setpoint_fp": "away" }, { "room_id": "3435163850", "therm_setpoint_fp": "away" }, { "room_id": "3497055021", "therm_setpoint_fp": "away" }, { "room_id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "room_id": "3795659199", "therm_setpoint_fp": "away" }, { "room_id": "596817675", "therm_setpoint_fp": "frost_guard" }, { "room_id": "873035982", "therm_setpoint_fp": "away" }, { "room_id": "93888250", "therm_setpoint_fp": "frost_guard" }, { "room_id": "927970817", "therm_setpoint_fp": "frost_guard" }, { "room_id": "1641945290", "therm_setpoint_fp": "frost_guard" }, { "room_id": "2102454491", "therm_setpoint_fp": "frost_guard" } ], "modules": [], "rooms": [ { "id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "id": "2042969726", "therm_setpoint_fp": "away" }, { "id": "3435163850", "therm_setpoint_fp": "away" }, { "id": "3497055021", "therm_setpoint_fp": "away" }, { "id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "id": "3795659199", "therm_setpoint_fp": "away" }, { "id": "596817675", "therm_setpoint_fp": "frost_guard" }, { "id": "873035982", "therm_setpoint_fp": "away" }, { "id": "93888250", "therm_setpoint_fp": "frost_guard" }, { "id": "927970817", "therm_setpoint_fp": "frost_guard" }, { "id": "1641945290", "therm_setpoint_fp": "frost_guard" }, { "id": "2102454491", "therm_setpoint_fp": "frost_guard" } ] }, { "name": "Chambres & SDB Confort All OFF", "id": 9, "type": 4, "rooms_temp": [ { "room_id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "room_id": "2042969726", "therm_setpoint_fp": "comfort" }, { "room_id": "3435163850", "therm_setpoint_fp": "comfort" }, { "room_id": "3497055021", "therm_setpoint_fp": "comfort" }, { "room_id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "room_id": "3795659199", "therm_setpoint_fp": "comfort" }, { "room_id": "596817675", "therm_setpoint_fp": "frost_guard" }, { "room_id": "873035982", "therm_setpoint_fp": "comfort" }, { "room_id": "93888250", "therm_setpoint_fp": "comfort" }, { "room_id": "927970817", "therm_setpoint_fp": "comfort" }, { "room_id": "1641945290", "therm_setpoint_fp": "comfort" }, { "room_id": "2102454491", "therm_setpoint_fp": "frost_guard" } ], "modules": [], "rooms": [ { "id": "1662974901", "therm_setpoint_fp": "frost_guard" }, { "id": "2042969726", "therm_setpoint_fp": "comfort" }, { "id": "3435163850", "therm_setpoint_fp": "comfort" }, { "id": "3497055021", "therm_setpoint_fp": "comfort" }, { "id": "3707962039", "therm_setpoint_fp": "frost_guard" }, { "id": "3795659199", "therm_setpoint_fp": "comfort" }, { "id": "596817675", "therm_setpoint_fp": "frost_guard" }, { "id": "873035982", "therm_setpoint_fp": "comfort" }, { "id": "93888250", "therm_setpoint_fp": "comfort" }, { "id": "927970817", "therm_setpoint_fp": "comfort" }, { "id": "1641945290", "therm_setpoint_fp": "comfort" }, { "id": "2102454491", "therm_setpoint_fp": "frost_guard" } ] } ], "name": "SDM seulement", "default": false, "away_temp": 12, "hg_temp": 7, "id": "65428fdc7349fc4e49034381", "type": "therm" }, { "timetable": [ { "zone_id": 1, "m_offset": 300 }, { "zone_id": 3, "m_offset": 540 }, { "zone_id": 2, "m_offset": 960 }, { "zone_id": 0, "m_offset": 1020 }, { "zone_id": 1, "m_offset": 1740 }, { "zone_id": 3, "m_offset": 1980 }, { "zone_id": 2, "m_offset": 2400 }, { "zone_id": 0, "m_offset": 2460 }, { "zone_id": 1, "m_offset": 3180 }, { "zone_id": 3, "m_offset": 3420 }, { "zone_id": 2, "m_offset": 3840 }, { "zone_id": 0, "m_offset": 3900 }, { "zone_id": 1, "m_offset": 4620 }, { "zone_id": 3, "m_offset": 4860 }, { "zone_id": 2, "m_offset": 5280 }, { "zone_id": 0, "m_offset": 5340 }, { "zone_id": 1, "m_offset": 6060 }, { "zone_id": 3, "m_offset": 6300 }, { "zone_id": 2, "m_offset": 6720 }, { "zone_id": 0, "m_offset": 6780 }, { "zone_id": 1, "m_offset": 7500 }, { "zone_id": 3, "m_offset": 7740 }, { "zone_id": 2, "m_offset": 8160 }, { "zone_id": 0, "m_offset": 8220 }, { "zone_id": 1, "m_offset": 8940 }, { "zone_id": 3, "m_offset": 9180 }, { "zone_id": 2, "m_offset": 9600 }, { "zone_id": 0, "m_offset": 9660 } ], "zones": [ { "id": 0, "modules": [ { "id": "98:76:54:32:10:00:00:67", "bridge": "aa:aa:aa:aa:aa:aa", "on": false } ] }, { "id": 1, "modules": [ { "id": "98:76:54:32:10:00:00:67", "bridge": "aa:aa:aa:aa:aa:aa", "on": true } ] }, { "id": 2, "modules": [ { "id": "98:76:54:32:10:00:00:67", "bridge": "aa:aa:aa:aa:aa:aa", "on": true } ] }, { "id": 3, "modules": [ { "id": "98:76:54:32:10:00:00:67", "bridge": "aa:aa:aa:aa:aa:aa", "on": false } ] } ], "name": "Planning d'actions", "default": false, "timetable_sunrise": [], "timetable_sunset": [], "id": "64fa4a1266404bbb130f4b71", "type": "event", "selected": true }, { "timetable": [], "zones": [], "name": "Hiver", "default": false, "timetable_sunrise": [], "timetable_sunset": [], "id": "65c3f82f61e0a3ec5401640f", "type": "event" }, { "timetable": [ { "zone_id": 0, "m_offset": 0 }, { "zone_id": 1, "m_offset": 130 }, { "zone_id": 0, "m_offset": 430 }, { "zone_id": 1, "m_offset": 850 }, { "zone_id": 0, "m_offset": 1030 }, { "zone_id": 1, "m_offset": 1570 }, { "zone_id": 0, "m_offset": 1870 }, { "zone_id": 1, "m_offset": 2290 }, { "zone_id": 0, "m_offset": 2470 }, { "zone_id": 1, "m_offset": 3010 }, { "zone_id": 0, "m_offset": 3310 }, { "zone_id": 1, "m_offset": 3730 }, { "zone_id": 0, "m_offset": 3910 }, { "zone_id": 1, "m_offset": 4450 }, { "zone_id": 0, "m_offset": 4750 }, { "zone_id": 1, "m_offset": 5170 }, { "zone_id": 0, "m_offset": 5350 }, { "zone_id": 1, "m_offset": 5890 }, { "zone_id": 0, "m_offset": 6190 }, { "zone_id": 1, "m_offset": 6610 }, { "zone_id": 0, "m_offset": 6790 }, { "zone_id": 1, "m_offset": 7330 }, { "zone_id": 0, "m_offset": 7630 }, { "zone_id": 1, "m_offset": 8050 }, { "zone_id": 0, "m_offset": 8230 }, { "zone_id": 1, "m_offset": 8770 }, { "zone_id": 0, "m_offset": 9070 }, { "zone_id": 1, "m_offset": 9490 }, { "zone_id": 0, "m_offset": 9670 } ], "zones": [ { "id": 0, "price": 0.27, "price_type": "peak" }, { "id": 1, "price": 0.2068, "price_type": "off_peak" } ], "name": "electricity", "default": false, "tariff": "edf_tarif_bleu", "tariff_option": "peak_and_off_peak", "power_threshold": 36, "contract_power_unit": "kW", "id": "60ce3d057a24d640444c4f1c", "type": "electricity", "selected": true } ] }, { "id": "eeeeeeeeeffffffffffaaaaa", "name": "A SECOND HOME", "altitude": 200, "coordinates": [ 34.345576, 89.667112 ], "country": "FR", "timezone": "Europe/Paris", "rooms": [ { "id": "1468717414", "name": "Cave", "type": "garage", "module_ids": [ "12:34:56:78:90:00:00:09", "12:34:56:78:90:00:00:20", "12:34:56:78:90:00:00:33" ] }, { "id": "738709350", "name": "Salon", "type": "livingroom", "module_ids": [ "bb:bb:bb:bb:bb:bb", "12:34:56:78:90:00:00:01", "12:34:56:78:90:00:00:02", "12:34:56:78:90:00:00:03", "12:34:56:78:90:00:00:04", "12:34:56:78:90:00:00:05", "12:34:56:78:90:00:00:06", "12:34:56:78:90:00:00:07", "12:34:56:78:90:00:00:08", "12:34:56:78:90:00:00:10", "12:34:56:78:90:00:00:23", "12:34:56:78:90:00:00:24", "12:34:56:78:90:00:00:29", "12:34:56:78:90:00:00:30" ] }, { "id": "3098890768", "name": "Entrée", "type": "lobby", "module_ids": [ "12:34:56:78:90:00:00:11" ] }, { "id": "70754041", "name": "Salle de bains", "type": "bathroom", "module_ids": [ "12:34:56:78:90:00:00:12", "12:34:56:78:90:00:00:26" ] }, { "id": "1761556353", "name": "Nouveaux toilettes", "type": "toilets", "module_ids": [ "12:34:56:78:90:00:00:13" ] }, { "id": "968846272", "name": "Anciens Toilettes", "type": "toilets", "module_ids": [ "12:34:56:78:90:00:00:14" ] }, { "id": "4008422910", "name": "Palier", "type": "corridor", "module_ids": [ "12:34:56:78:90:00:00:15", "12:34:56:78:90:00:00:18", "12:34:56:78:90:00:00:31" ] }, { "id": "2640531479", "name": "Chambre parents", "type": "bedroom", "module_ids": [ "12:34:56:78:90:00:00:16", "12:34:56:78:90:00:00:27" ] }, { "id": "2667868658", "name": "Chambre Older", "type": "bedroom", "module_ids": [ "12:34:56:78:90:00:00:17", "12:34:56:78:90:00:00:22" ] }, { "id": "3783425301", "name": "Chambre Enfants", "type": "bedroom", "module_ids": [ "12:34:56:78:90:00:00:19", "12:34:56:78:90:00:00:28" ] }, { "id": "68319658", "name": "Chambre Old", "type": "bedroom", "module_ids": [ "12:34:56:78:90:00:00:25" ] }, { "id": "1156588698", "name": "Jardin", "type": "outdoor", "module_ids": [ "12:34:56:78:90:00:00:21" ] }, { "id": "1229033409", "name": "Grenier", "type": "custom", "module_ids": [ "12:34:56:78:90:00:00:32", "12:34:56:78:90:00:00:34" ] } ], "modules": [ { "id": "bb:bb:bb:bb:bb:bb", "type": "NLG", "name": "Legrand Gateway", "setup_date": 1692558574, "room_id": "738709350", "modules_bridged": [ "12:34:56:78:90:00:00:01", "12:34:56:78:90:00:00:02", "12:34:56:78:90:00:00:03", "12:34:56:78:90:00:00:04", "12:34:56:78:90:00:00:05", "12:34:56:78:90:00:00:06", "12:34:56:78:90:00:00:07", "12:34:56:78:90:00:00:08", "12:34:56:78:90:00:00:09", "12:34:56:78:90:00:00:10", "12:34:56:78:90:00:00:11", "12:34:56:78:90:00:00:12", "12:34:56:78:90:00:00:13", "12:34:56:78:90:00:00:14", "12:34:56:78:90:00:00:15", "12:34:56:78:90:00:00:16", "12:34:56:78:90:00:00:17", "12:34:56:78:90:00:00:18", "12:34:56:78:90:00:00:19", "12:34:56:78:90:00:00:20", "12:34:56:78:90:00:00:21", "12:34:56:78:90:00:00:22", "12:34:56:78:90:00:00:23", "12:34:56:78:90:00:00:24", "12:34:56:78:90:00:00:25", "12:34:56:78:90:00:00:26", "12:34:56:78:90:00:00:27", "12:34:56:78:90:00:00:28", "12:34:56:78:90:00:00:29", "12:34:56:78:90:00:00:30", "12:34:56:78:90:00:00:31", "12:34:56:78:90:00:00:32", "12:34:56:78:90:00:00:33", "12:34:56:78:90:00:00:34" ] }, { "id": "12:34:56:78:90:00:00:01", "type": "NLAO", "name": "Commande On/Off (Sans-Fil, Sans Pile) 1", "setup_date": 1692558628, "room_id": "738709350", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:02", "type": "NLAO", "name": "Commande On/Off (Sans-Fil, Sans Pile) 2", "setup_date": 1692558628, "room_id": "738709350", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:03", "type": "NLAO", "name": "Commande On/Off (Sans-Fil, Sans Pile) 3", "setup_date": 1692558628, "room_id": "738709350", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:04", "type": "NLAO", "name": "Commande On/Off (Sans-Fil, Sans Pile) 4", "setup_date": 1692558628, "room_id": "738709350", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:05", "type": "NLAO", "name": "Commande On/Off (Sans-Fil, Sans Pile) 5", "setup_date": 1692558628, "room_id": "738709350", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:06", "type": "NLAO", "name": "Commande On/Off (Sans-Fil, Sans Pile) 6", "setup_date": 1692558628, "room_id": "738709350", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:07", "type": "NLAO", "name": "Commande On/Off (Sans-Fil, Sans Pile) 7", "setup_date": 1692558628, "room_id": "738709350", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:08", "type": "NLAO", "name": "Commande On/Off (Sans-Fil, Sans Pile) 8", "setup_date": 1692558628, "room_id": "738709350", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:09", "type": "NLPO", "name": "OL Cumulus", "setup_date": 1692558628, "room_id": "1468717414", "bridge": "bb:bb:bb:bb:bb:bb", "appliance_type": "water_heater" }, { "id": "12:34:56:78:90:00:00:10", "type": "NLPT", "name": "OL Lumière Cuisine", "setup_date": 1692558628, "room_id": "738709350", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:11", "type": "NLPT", "name": "OL Escalier", "setup_date": 1692558628, "room_id": "3098890768", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:12", "type": "NLPT", "name": "OL Éclairage Salle de bain", "setup_date": 1692558628, "room_id": "70754041", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:13", "type": "NLPT", "name": "OL Lumière nouveaux toilettes", "setup_date": 1692558628, "room_id": "1761556353", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:14", "type": "NLPT", "name": "OL Lumière anciens toilettes", "setup_date": 1692558628, "room_id": "968846272", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:15", "type": "NLPT", "name": "OL Lumière palier salle de bain", "setup_date": 1692558628, "room_id": "4008422910", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:16", "type": "NLPT", "name": "OL Lumière chambre A", "setup_date": 1692558628, "room_id": "2640531479", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:17", "type": "NLPT", "name": "OL Lumière Chambre Older", "setup_date": 1692558628, "room_id": "2667868658", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:18", "type": "NLPT", "name": "OL Lumière Palier", "setup_date": 1692558628, "room_id": "4008422910", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:19", "type": "NLPT", "name": "OL Lumière enfants", "setup_date": 1692558628, "room_id": "3783425301", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:20", "type": "NLM", "name": "OL Lumière Cave", "setup_date": 1692643741, "room_id": "1468717414", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:21", "type": "NLM", "name": "OL Lumière Jardin", "setup_date": 1692643763, "room_id": "1156588698", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:22", "type": "NLC", "name": "OL Radiateur Chambre Older", "setup_date": 1692644489, "room_id": "2667868658", "bridge": "bb:bb:bb:bb:bb:bb", "appliance_type": "radiator" }, { "id": "12:34:56:78:90:00:00:23", "type": "NLC", "name": "OL Radiateur Salon Fenêtre", "setup_date": 1692644493, "room_id": "738709350", "bridge": "bb:bb:bb:bb:bb:bb", "appliance_type": "radiator" }, { "id": "12:34:56:78:90:00:00:24", "type": "NLC", "name": "OL Radiateur Salon Porte", "setup_date": 1692644497, "room_id": "738709350", "bridge": "bb:bb:bb:bb:bb:bb", "appliance_type": "radiator" }, { "id": "12:34:56:78:90:00:00:25", "type": "NLC", "name": "OL Radiateur Chambre Old", "setup_date": 1692644501, "room_id": "68319658", "bridge": "bb:bb:bb:bb:bb:bb", "appliance_type": "radiator" }, { "id": "12:34:56:78:90:00:00:26", "type": "NLC", "name": "OL Radiateur Serviette", "setup_date": 1692644506, "room_id": "70754041", "bridge": "bb:bb:bb:bb:bb:bb", "appliance_type": "radiator" }, { "id": "12:34:56:78:90:00:00:27", "type": "NLC", "name": "OL Radiateur Chambre A", "setup_date": 1692644509, "room_id": "2640531479", "bridge": "bb:bb:bb:bb:bb:bb", "appliance_type": "radiator" }, { "id": "12:34:56:78:90:00:00:28", "type": "NLC", "name": "OL Radiateur Chambre E", "setup_date": 1693159267, "room_id": "3783425301", "bridge": "bb:bb:bb:bb:bb:bb", "appliance_type": "radiator" }, { "id": "12:34:56:78:90:00:00:29", "type": "NLPT", "name": "OL Salle à manger", "setup_date": 1696921179, "room_id": "738709350", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:30", "type": "NLPT", "name": "OL Plan de travail", "setup_date": 1696921199, "room_id": "738709350", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:31", "type": "NLAO", "name": "Commande On/Off (Sans-Fil, Sans Pile) 9", "setup_date": 1696922170, "room_id": "4008422910", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:32", "type": "NLPT", "name": "OL Lumière Grenier", "setup_date": 1696949709, "room_id": "1229033409", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:33", "type": "NLAO", "name": "Commande Cave", "setup_date": 1696949890, "room_id": "1468717414", "bridge": "bb:bb:bb:bb:bb:bb" }, { "id": "12:34:56:78:90:00:00:34", "type": "NLAO", "name": "Commande Grenier", "setup_date": 1696951661, "room_id": "1229033409", "bridge": "bb:bb:bb:bb:bb:bb" } ], "temperature_control_mode": "heating", "therm_mode": "hg", "therm_setpoint_default_duration": 180, "schedules": [ { "timetable": [ { "zone_id": 1, "m_offset": 0 }, { "zone_id": 0, "m_offset": 420 }, { "zone_id": 4, "m_offset": 480 }, { "zone_id": 0, "m_offset": 1140 }, { "zone_id": 1, "m_offset": 1320 }, { "zone_id": 0, "m_offset": 1860 }, { "zone_id": 4, "m_offset": 1920 }, { "zone_id": 0, "m_offset": 2580 }, { "zone_id": 1, "m_offset": 2760 }, { "zone_id": 0, "m_offset": 3300 }, { "zone_id": 4, "m_offset": 3360 }, { "zone_id": 0, "m_offset": 4020 }, { "zone_id": 1, "m_offset": 4200 }, { "zone_id": 0, "m_offset": 4740 }, { "zone_id": 4, "m_offset": 4800 }, { "zone_id": 0, "m_offset": 5460 }, { "zone_id": 1, "m_offset": 5640 }, { "zone_id": 0, "m_offset": 6180 }, { "zone_id": 4, "m_offset": 6240 }, { "zone_id": 0, "m_offset": 6900 }, { "zone_id": 1, "m_offset": 7080 }, { "zone_id": 0, "m_offset": 7620 }, { "zone_id": 4, "m_offset": 7800 }, { "zone_id": 0, "m_offset": 8220 }, { "zone_id": 1, "m_offset": 8520 }, { "zone_id": 0, "m_offset": 9060 }, { "zone_id": 4, "m_offset": 9240 }, { "zone_id": 0, "m_offset": 9660 }, { "zone_id": 1, "m_offset": 9960 } ], "zones": [ { "name": "Comfort", "id": 0, "type": 0, "rooms_temp": [ { "room_id": "738709350", "therm_setpoint_fp": "comfort" }, { "room_id": "70754041", "therm_setpoint_fp": "comfort" }, { "room_id": "2640531479", "therm_setpoint_fp": "comfort" }, { "room_id": "2667868658", "therm_setpoint_fp": "comfort" }, { "room_id": "3783425301", "therm_setpoint_fp": "comfort" }, { "room_id": "68319658", "therm_setpoint_fp": "comfort" } ], "modules": [], "rooms": [ { "id": "738709350", "therm_setpoint_fp": "comfort" }, { "id": "70754041", "therm_setpoint_fp": "comfort" }, { "id": "2640531479", "therm_setpoint_fp": "comfort" }, { "id": "2667868658", "therm_setpoint_fp": "comfort" }, { "id": "3783425301", "therm_setpoint_fp": "comfort" }, { "id": "68319658", "therm_setpoint_fp": "comfort" } ] }, { "name": "Night", "id": 1, "type": 1, "rooms_temp": [ { "room_id": "738709350", "therm_setpoint_fp": "away" }, { "room_id": "70754041", "therm_setpoint_fp": "away" }, { "room_id": "2640531479", "therm_setpoint_fp": "away" }, { "room_id": "2667868658", "therm_setpoint_fp": "away" }, { "room_id": "3783425301", "therm_setpoint_fp": "away" }, { "room_id": "68319658", "therm_setpoint_fp": "away" } ], "modules": [], "rooms": [ { "id": "738709350", "therm_setpoint_fp": "away" }, { "id": "70754041", "therm_setpoint_fp": "away" }, { "id": "2640531479", "therm_setpoint_fp": "away" }, { "id": "2667868658", "therm_setpoint_fp": "away" }, { "id": "3783425301", "therm_setpoint_fp": "away" }, { "id": "68319658", "therm_setpoint_fp": "away" } ] }, { "name": "Comfort+", "id": 3, "type": 8, "rooms_temp": [ { "room_id": "738709350", "therm_setpoint_fp": "comfort" }, { "room_id": "70754041", "therm_setpoint_fp": "comfort" }, { "room_id": "2640531479", "therm_setpoint_fp": "comfort" }, { "room_id": "2667868658", "therm_setpoint_fp": "comfort" }, { "room_id": "3783425301", "therm_setpoint_fp": "comfort" }, { "room_id": "68319658", "therm_setpoint_fp": "comfort" } ], "modules": [], "rooms": [ { "id": "738709350", "therm_setpoint_fp": "comfort" }, { "id": "70754041", "therm_setpoint_fp": "comfort" }, { "id": "2640531479", "therm_setpoint_fp": "comfort" }, { "id": "2667868658", "therm_setpoint_fp": "comfort" }, { "id": "3783425301", "therm_setpoint_fp": "comfort" }, { "id": "68319658", "therm_setpoint_fp": "comfort" } ] }, { "name": "Eco", "id": 4, "type": 5, "rooms_temp": [ { "room_id": "738709350", "therm_setpoint_fp": "away" }, { "room_id": "70754041", "therm_setpoint_fp": "away" }, { "room_id": "2640531479", "therm_setpoint_fp": "away" }, { "room_id": "2667868658", "therm_setpoint_fp": "away" }, { "room_id": "3783425301", "therm_setpoint_fp": "away" }, { "room_id": "68319658", "therm_setpoint_fp": "away" } ], "modules": [], "rooms": [ { "id": "738709350", "therm_setpoint_fp": "away" }, { "id": "70754041", "therm_setpoint_fp": "away" }, { "id": "2640531479", "therm_setpoint_fp": "away" }, { "id": "2667868658", "therm_setpoint_fp": "away" }, { "id": "3783425301", "therm_setpoint_fp": "away" }, { "id": "68319658", "therm_setpoint_fp": "away" } ] } ], "name": "Mon planning de chauffe", "default": false, "away_temp": 12, "hg_temp": 7, "id": "64e3b6102853d9405304b27a", "type": "therm", "selected": true }, { "timetable": [], "zones": [], "name": "Planning d'actions", "default": false, "timetable_sunrise": [], "timetable_sunset": [], "id": "64ee68e2c8419b37790c5050", "type": "event", "selected": true }, { "timetable": [ { "zone_id": 0, "m_offset": 0 } ], "zones": [ { "id": 0, "price": 0.2516, "price_type": "basic" } ], "name": "electricity", "default": false, "tariff": "edf_tarif_bleu", "tariff_option": "basic", "power_threshold": 9, "contract_power_unit": "kVA", "id": "64e28390bc6d555f2d05c684", "type": "electricity", "selected": true } ] } ], "user": { "email": "john.doe@doe.com", "language": "fr-FR", "locale": "fr-FR", "feel_like_algorithm": 0, "unit_pressure": 0, "unit_system": 0, "unit_wind": 0, "id": "111111111112222222333333" } }, "status": "ok", "time_exec": 0.07427000999450684, "time_server": 1709762264 }pyatmo-9.2.1/fixtures/homestatus_91763b24c43d3e344f424e8b.json000066400000000000000000000356151501740523400232300ustar00rootroot00000000000000{ "status": "ok", "time_server": 1559292039, "body": { "home": { "modules": [ { "id": "12:34:56:80:bb:26", "type": "NAMain", "firmware_revision": 202, "wifi_state": "full", "wifi_strength": 45, "ts": 1702884705, "temperature": 18.9, "co2": 498, "humidity": 33, "noise": 47, "pressure": 1034.8, "absolute_pressure": 956.1 }, { "id": "12:34:56:80:1c:42", "type": "NAModule1", "battery_state": "full", "battery_level": 6690, "firmware_revision": 53, "rf_state": "full", "rf_strength": 42, "last_seen": 1702884800, "reachable": true, "bridge": "70:ee:50:37:11:ca", "ts": 1702884697, "temperature": 5.8, "humidity": 65 }, { "id": "12:34:56:00:f1:62", "type": "NACamera", "monitoring": "on", "sd_status": 4, "alim_status": 2, "locked": false, "vpn_url": "https://prodvpn-eu-2.netatmo.net/restricted/10.255.123.45/609e27de5699fb18147ab47d06846631/MTRPn_BeWCav5RBq4U1OMDruTW4dkQ0NuMwNDAw11g,,", "is_local": true }, { "id": "12:34:56:00:f1:63", "type": "NPC", "monitoring": "on", "sd_status": 4, "alim_status": 2, "locked": false, "vpn_url": "https://prodvpn-eu-2.netatmo.net/restricted/10.255.123.45/9fb1814609e27de5697ab47d06846631/MTRPn_BeWCav5RBq4U1OMDruTW4dkQ0NuMwNDAw11g,,", "is_local": true }, { "id": "12:34:56:00:fa:d0", "type": "NAPlug", "firmware_revision": 174, "rf_strength": 107, "wifi_strength": 42 }, { "id": "12:34:56:00:01:ae", "reachable": true, "type": "NATherm1", "firmware_revision": 65, "rf_strength": 58, "battery_level": 3793, "boiler_valve_comfort_boost": false, "boiler_status": false, "anticipating": false, "bridge": "12:34:56:00:fa:d0", "battery_state": "high" }, { "id": "12:34:56:03:a5:54", "reachable": true, "type": "NRV", "firmware_revision": 79, "rf_strength": 51, "battery_level": 3025, "bridge": "12:34:56:00:fa:d0", "battery_state": "full" }, { "id": "12:34:56:03:a0:ac", "reachable": true, "type": "NRV", "firmware_revision": 79, "rf_strength": 59, "battery_level": 3029, "bridge": "12:34:56:00:fa:d0", "battery_state": "full" }, { "type": "NDB", "last_ftp_event": { "type": 3, "time": 1631444443, "id": 3 }, "id": "12:34:56:10:f1:66", "websocket_connected": true, "vpn_url": "https://prodvpn-eu-6.netatmo.net/10.20.30.40/1111111111111/2222222222222,,", "is_local": false, "alim_status": 2, "connection": "wifi", "firmware_name": "2.18.0", "firmware_revision": 2018000, "homekit_status": "configured", "max_peers_reached": false, "sd_status": 4, "wifi_strength": 66, "wifi_state": "medium" }, { "type": "NOC", "firmware_revision": 3002000, "monitoring": "on", "sd_status": 4, "connection": "wifi", "homekit_status": "upgradable", "floodlight": "auto", "timelapse_available": true, "id": "12:34:56:10:b9:0e", "vpn_url": "https://prodvpn-eu-6.netatmo.net/10.20.30.41/333333333333/444444444444,,", "is_local": false, "network_lock": false, "firmware_name": "3.2.0", "wifi_strength": 62, "alim_status": 2, "locked": false, "wifi_state": "high" }, { "boiler_control": "onoff", "dhw_control": "none", "firmware_revision": 22, "hardware_version": 222, "id": "12:34:56:20:f5:44", "outdoor_temperature": 8.2, "sequence_id": 19764, "type": "OTH", "wifi_strength": 57 }, { "battery_level": 4176, "boiler_status": false, "boiler_valve_comfort_boost": false, "firmware_revision": 6, "id": "12:34:56:20:f5:8c", "last_message": 1637684297, "last_seen": 1637684297, "radio_id": 2, "reachable": true, "rf_strength": 64, "type": "OTM", "bridge": "12:34:56:20:f5:44", "battery_state": "full" }, { "id": "12:34:56:30:d5:d4", "type": "NBG", "firmware_revision": 39, "wifi_strength": 65, "reachable": true }, { "id": "0009999992", "type": "NBR", "current_position": 0, "target_position": 0, "target_position_step": 100, "firmware_revision": 16, "rf_strength": 0, "last_seen": 1638353156, "reachable": true, "bridge": "12:34:56:30:d5:d4" }, { "id": "0009999993", "type": "NBO", "current_position": 0, "target_position": 0, "target_position:step": 100, "firmware_revision": 22, "rf_strength": 0, "last_seen": 1671395511, "reachable": true, "bridge": "12:34:56:30:d5:d4" }, { "id": "12:34:56:00:86:99", "type": "NACamDoorTag", "battery_state": "high", "battery_level": 5240, "firmware_revision": 58, "rf_state": "full", "rf_strength": 58, "last_seen": 1642698124, "last_activity": 1627757310, "reachable": false, "bridge": "12:34:56:00:f1:62", "status": "no_news" }, { "id": "12:34:56:00:e3:9b", "type": "NIS", "battery_state": "low", "battery_level": 5438, "firmware_revision": 209, "rf_state": "medium", "rf_strength": 62, "last_seen": 1644569790, "reachable": true, "bridge": "12:34:56:00:f1:62", "status": "no_sound", "monitoring": "off" }, { "id": "12:34:56:80:60:40", "type": "NLG", "offload": false, "firmware_revision": 211, "last_seen": 1644567372, "wifi_strength": 51, "reachable": true }, { "id": "12:34:56:80:00:12:ac:f2", "type": "NLP", "on": true, "offload": false, "firmware_revision": 62, "last_seen": 1644569425, "power": 0, "reachable": true, "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:80:00:c3:69:3c", "type": "NLT", "battery_state": "full", "battery_level": 3300, "firmware_revision": 42, "last_seen": 0, "reachable": false, "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:80:00:c3:69:3e", "type": "NLD", "battery_state": "medium", "battery_level": 2500, "firmware_revision": 56, "last_seen": 0, "reachable": true, "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:80:00:c3:69:3d", "type": "Z3V", "current_position": 0, "target_position": 0, "target_position_step": 100, "firmware_revision": 16, "last_seen": 1638353156, "reachable": true, "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:16:0e", "type": "NLE", "firmware_revision": 14, "wifi_strength": 38 }, { "id": "12:34:56:00:16:0e#0", "type": "NLE", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:16:0e#1", "type": "NLE", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:16:0e#2", "type": "NLE", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:16:0e#3", "type": "NLE", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:16:0e#4", "type": "NLE", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:16:0e#5", "type": "NLE", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:16:0e#6", "type": "NLE", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:16:0e#7", "type": "NLE", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:16:0e#8", "type": "NLE", "bridge": "12:34:56:00:16:0e" }, { "id": "12:34:56:00:00:a1:4c:da", "type": "NLPC", "firmware_revision": 62, "last_seen": 1646511241, "power": 476, "reachable": true, "bridge": "12:34:56:80:60:40" }, { "id": "10:20:30:bd:b8:1e", "type": "BNS", "firmware_revision": 32, "wifi_strength": 49, "boiler_valve_comfort_boost": false, "boiler_status": true, "cooler_status": false }, { "id": "00:11:22:33:00:11:45:fe", "type": "NLF", "on": false, "brightness": 63, "firmware_revision": 57, "last_seen": 1657086939, "power": 0, "reachable": true, "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:01:01:01:b1", "type": "NLLF", "firmware_revision": 60, "last_seen": 1657086949, "power": 11, "reachable": true, "bridge": "12:34:56:80:60:40", "fan_speed": 1 }, { "firmware_revision": 53, "id": "12:34:56:00:01:01:01:b2", "last_seen": 1657086949, "on": false, "power": 0, "reachable": true, "type": "NLL", "bridge": "12:34:56:80:60:40" }, { "current_position": 0, "firmware_revision": 47, "id": "12:34:56:00:01:01:01:b3", "last_seen": 1746730909, "reachable": true, "target_position": 0, "target_position:step": 100, "type": "NLV", "bridge": "12:34:56:80:60:40" }, { "current_position": 0, "firmware_revision": 53, "id": "12:34:56:00:01:01:01:b4", "last_seen": 1746730664, "reachable": true, "target_position": 10, "target_position:step": 1, "type": "NLLV", "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:01:01:01:b5", "type": "NLJ", "target_position": 100, "target_position:step": 1, "firmware_revision": 7, "last_seen": 1746736151, "reachable": true, "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:01:01:01:b6", "type": "NLIS", "firmware_revision": 20, "last_seen": 1746731520, "reachable": true, "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:01:01:01:b6#2", "type": "NLIS", "on": false, "power": 0, "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:01:01:01:b6#1", "type": "NLIS", "on": false, "power": 0, "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:01:01:01:b7", "type": "NLPT", "on": true, "firmware_revision": 77, "last_seen": 1746731885, "power": 0, "reachable": true, "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:01:01:01:b8", "type": "NLPD", "on": true, "offload": false, "firmware_revision": 66, "last_seen": 1746731949, "power": 0, "reachable": true, "bridge": "12:34:56:80:60:40" }, { "id": "12:34:56:00:01:01:01:b9", "type": "NLPO", "on": false, "contactor_mode": "off", "offload": false, "firmware_revision": 74, "last_seen": 1746731968, "power": 0, "reachable": true, "bridge": "12:34:56:80:60:40" } ], "rooms": [ { "id": "2746182631", "reachable": true, "therm_measured_temperature": 19.8, "therm_setpoint_temperature": 12, "therm_setpoint_mode": "away", "therm_setpoint_start_time": 1559229567, "therm_setpoint_end_time": 0 }, { "id": "2940411577", "reachable": true, "therm_measured_temperature": 27, "heating_power_request": 0, "therm_setpoint_temperature": 7, "therm_setpoint_mode": "hg", "therm_setpoint_start_time": 0, "therm_setpoint_end_time": 0, "anticipating": false, "open_window": false }, { "id": "2833524037", "reachable": true, "therm_measured_temperature": 24.5, "heating_power_request": 0, "therm_setpoint_temperature": 7, "therm_setpoint_mode": "hg", "therm_setpoint_start_time": 0, "therm_setpoint_end_time": 0, "anticipating": false, "open_window": false }, { "id": "1002003001", "reachable": true, "anticipating": false, "heating_power_request": 0, "open_window": false, "humidity": 67, "therm_measured_temperature": 22, "therm_setpoint_temperature": 22, "therm_setpoint_start_time": 1647462737, "therm_setpoint_end_time": null, "therm_setpoint_mode": "home" } ], "id": "91763b24c43d3e344f424e8b", "persons": [ { "id": "91827374-7e04-5298-83ad-a0cb8372dff1", "last_seen": 1557071156, "out_of_sight": true }, { "id": "91827375-7e04-5298-83ae-a0cb8372dff2", "last_seen": 1559282761, "out_of_sight": false }, { "id": "91827376-7e04-5298-83af-a0cb8372dff3", "last_seen": 1559224132, "out_of_sight": true } ] } } }pyatmo-9.2.1/fixtures/homestatus_91763b24c43d3e344f424e8c.json000066400000000000000000000010061501740523400232140ustar00rootroot00000000000000{ "status": "ok", "time_server": 1642952130, "body": { "home": { "persons": [ { "id": "abcdef12-1111-0000-0000-000111222333", "last_seen": 1489050910, "out_of_sight": true }, { "id": "abcdef12-2222-0000-0000-000111222333", "last_seen": 1489078776, "out_of_sight": true } ] } } }pyatmo-9.2.1/fixtures/ping.json000066400000000000000000000001631501740523400165360ustar00rootroot00000000000000{ "local_url": "http://192.168.0.123/678460a0d47e5618699fb31169e2b47d", "product_name": "Welcome Netatmo" }pyatmo-9.2.1/fixtures/status_ok.json000066400000000000000000000001311501740523400176100ustar00rootroot00000000000000{ "status": "ok", "time_exec": 0.020781993865967, "time_server": 1559162635 }pyatmo-9.2.1/fixtures/sync_schedule_591b54a2764ff4d50d8b5795.json000066400000000000000000000061331501740523400236720ustar00rootroot00000000000000{ "away_temp": 14, "hg_temp": 7, "timetable": [ { "m_offset": 0, "zone_id": 1 }, { "m_offset": 360, "zone_id": 0 }, { "m_offset": 420, "zone_id": 4 }, { "m_offset": 960, "zone_id": 0 }, { "m_offset": 1410, "zone_id": 1 }, { "m_offset": 1800, "zone_id": 0 }, { "m_offset": 1860, "zone_id": 4 }, { "m_offset": 2400, "zone_id": 0 }, { "m_offset": 2850, "zone_id": 1 }, { "m_offset": 3240, "zone_id": 0 }, { "m_offset": 3300, "zone_id": 4 }, { "m_offset": 3840, "zone_id": 0 }, { "m_offset": 4290, "zone_id": 1 }, { "m_offset": 4680, "zone_id": 0 }, { "m_offset": 4740, "zone_id": 4 }, { "m_offset": 5280, "zone_id": 0 }, { "m_offset": 5730, "zone_id": 1 }, { "m_offset": 6120, "zone_id": 0 }, { "m_offset": 6180, "zone_id": 4 }, { "m_offset": 6720, "zone_id": 0 }, { "m_offset": 7170, "zone_id": 1 }, { "m_offset": 7620, "zone_id": 0 }, { "m_offset": 8610, "zone_id": 1 }, { "m_offset": 9060, "zone_id": 0 }, { "m_offset": 10050, "zone_id": 1 } ], "zones": [ { "id": 0, "name": "Comfort", "type": 0, "rooms": [ { "id": "2746182631", "therm_setpoint_temperature": 21 }, { "id": "2746182632", "therm_setpoint_temperature": 22 } ] }, { "id": 1, "name": "Night", "type": 1, "rooms": [ { "id": "2746182631", "therm_setpoint_temperature": 15 }, { "id": "2746182632", "therm_setpoint_temperature": 18 } ] }, { "id": 4, "name": "Eco", "type": 5, "rooms": [ { "id": "2746182631", "therm_setpoint_temperature": 18 }, { "id": "2746182632", "therm_setpoint_temperature": 19 } ] } ] }pyatmo-9.2.1/fixtures/sync_schedule_b1b54a2f45795764f59d50d8.json000066400000000000000000000061331501740523400236720ustar00rootroot00000000000000{ "away_temp": 14, "hg_temp": 7, "timetable": [ { "m_offset": 0, "zone_id": 1 }, { "m_offset": 360, "zone_id": 0 }, { "m_offset": 420, "zone_id": 4 }, { "m_offset": 960, "zone_id": 0 }, { "m_offset": 1410, "zone_id": 1 }, { "m_offset": 1800, "zone_id": 0 }, { "m_offset": 1860, "zone_id": 4 }, { "m_offset": 2400, "zone_id": 0 }, { "m_offset": 2850, "zone_id": 1 }, { "m_offset": 3240, "zone_id": 0 }, { "m_offset": 3300, "zone_id": 4 }, { "m_offset": 3840, "zone_id": 0 }, { "m_offset": 4290, "zone_id": 1 }, { "m_offset": 4680, "zone_id": 0 }, { "m_offset": 4740, "zone_id": 4 }, { "m_offset": 5280, "zone_id": 0 }, { "m_offset": 5730, "zone_id": 1 }, { "m_offset": 6120, "zone_id": 0 }, { "m_offset": 6180, "zone_id": 4 }, { "m_offset": 6720, "zone_id": 0 }, { "m_offset": 7170, "zone_id": 1 }, { "m_offset": 7620, "zone_id": 0 }, { "m_offset": 8610, "zone_id": 1 }, { "m_offset": 9060, "zone_id": 0 }, { "m_offset": 10050, "zone_id": 1 } ], "zones": [ { "id": 0, "name": "Comfort", "type": 0, "rooms": [ { "id": "2746182631", "therm_setpoint_temperature": 21 }, { "id": "2746182632", "therm_setpoint_temperature": 22 } ] }, { "id": 1, "name": "Night", "type": 1, "rooms": [ { "id": "2746182631", "therm_setpoint_temperature": 14 }, { "id": "2746182632", "therm_setpoint_temperature": 18 } ] }, { "id": 4, "name": "Eco", "type": 5, "rooms": [ { "id": "2746182631", "therm_setpoint_temperature": 18 }, { "id": "2746182632", "therm_setpoint_temperature": 19 } ] } ] }pyatmo-9.2.1/pyproject.toml000066400000000000000000000070461501740523400157600ustar00rootroot00000000000000[build-system] build-backend = "setuptools.build_meta" requires = [ "setuptools>=77", "setuptools_scm>=8", ] [project] name = "pyatmo" description = "Simple API to access Netatmo weather station data from any Python 3 script. Designed for Home Assistant (but not only)" readme = "README.md" authors = [ { email = "jabesq@gmail.com", name = "Hugo Dupras" }, ] maintainers = [ { email = "cgtobi@gmail.com", name = "Tobias Sauerwein" }, { email = "jabesq@gmail.com", name = "Hugo Dupras" }, ] license = "MIT" license-files = ["LICENSE.txt"] requires-python = ">=3.11" dependencies = [ "aiohttp>=3.7.4,<4.0.0", "oauthlib~=3.1", "requests-oauthlib>=1.3,<3.0", "requests~=2.24", ] classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy", "Topic :: Home Automation", ] dynamic = ["version"] [project.urls] Changelog = "https://github.com/jabesq-org/pyatmo/blob/development/CHANGELOG.md" Homepage = "https://github.com/jabesq-org/pyatmo" Issues = "https://github.com/jabesq-org/pyatmo/issues" Repository = "https://github.com/jabesq-org/pyatmo.git" [tool.mypy] explicit_package_bases = true namespace_packages = true show_error_context = true show_error_codes = true pretty = true check_untyped_defs = true strict_equality = true implicit_optional=true warn_redundant_casts = true warn_unused_ignores = true warn_unreachable = true warn_no_return = true disallow_incomplete_defs = true [tool.pytest.ini_options] asyncio_default_fixture_loop_scope = "function" asyncio_mode = "auto" minversion = "8.0" [tool.ruff] fix = true line-length = 88 [tool.ruff.lint] select = [ "ALL" ] ignore = [ "D202", # blank-line-after-function (D202) "D203", # incorrect-blank-line-before-class (D203) "D213", # multi-line-summary-second-line (D213) "DTZ005", # call-datetime-now-without-tzinfo (DTZ005) "DTZ006", # call-datetime-fromtimestamp (DTZ006) "E501", # line-too-long (E501) "FBT001", # Boolean-typed positional argument in function definition (FBT001) "FBT002", # Boolean default positional argument in function definition (FBT002) "FBT003", # Boolean positional value in function call (FBT003) "PLR0913", # Too many arguments in function definition (PLR0913) "PLW2901", # redefined-loop-name (PLW2901) ] [tool.ruff.lint.flake8-pytest-style] fixture-parentheses = false [tool.ruff.lint.flake8-tidy-imports.banned-api.pytz] msg = "use zoneinfo instead" [tool.ruff.lint.isort] combine-as-imports = true force-sort-within-sections = true split-on-trailing-comma = false [tool.ruff.lint.mccabe] max-complexity = 12 [tool.ruff.lint.per-file-ignores] "tests/*" = [ "ANN001", "ANN002", "ANN003", "ANN201", "ANN202", "ANN204", "D10", "DTZ001", "N802", "PLR2004", "S101", "S105", ] [tool.setuptools_scm] local_scheme = "no-local-version" [tool.uv] dev-dependencies = [ "anyio>=4.3.0", "black>=24.8.0", "codespell>=2.3.0", "docutils>=0.21.2", "mypy>=1.11.2", "pre-commit>=3.8.0", "pytest-asyncio>=0.24.0", "pytest-cov>=5.0.0", "pytest-mock>=3.14.0", "pytest>=8.3.3", "requests-mock>=1.12.1", "ruff>=0.6.4", "time-machine>=2.15.0", "tox-uv>=1.25.0", "twine>=6.1.0", ] pyatmo-9.2.1/src/000077500000000000000000000000001501740523400136245ustar00rootroot00000000000000pyatmo-9.2.1/src/pyatmo/000077500000000000000000000000001501740523400151355ustar00rootroot00000000000000pyatmo-9.2.1/src/pyatmo/__init__.py000066400000000000000000000015031501740523400172450ustar00rootroot00000000000000"""Expose submodules.""" from pyatmo import const, modules from pyatmo.account import AsyncAccount from pyatmo.auth import AbstractAsyncAuth from pyatmo.exceptions import ( ApiError, ApiHomeReachabilityError, ApiThrottlingError, InvalidHomeError, InvalidRoomError, InvalidScheduleError, NoDeviceError, NoScheduleError, ) from pyatmo.home import Home from pyatmo.modules import Module from pyatmo.modules.device_types import DeviceType from pyatmo.room import Room __all__ = [ "AbstractAsyncAuth", "ApiError", "ApiHomeReachabilityError", "ApiThrottlingError", "AsyncAccount", "DeviceType", "Home", "InvalidHomeError", "InvalidRoomError", "InvalidScheduleError", "Module", "NoDeviceError", "NoScheduleError", "Room", "const", "modules", ] pyatmo-9.2.1/src/pyatmo/account.py000066400000000000000000000253051501740523400171500ustar00rootroot00000000000000"""Support for a Netatmo account.""" from __future__ import annotations import logging from typing import TYPE_CHECKING, Any, cast from uuid import uuid4 from pyatmo import modules from pyatmo.const import ( GETEVENTS_ENDPOINT, GETHOMECOACHDATA_ENDPOINT, GETHOMESDATA_ENDPOINT, GETHOMESTATUS_ENDPOINT, GETPUBLIC_DATA_ENDPOINT, GETSTATIONDATA_ENDPOINT, HOME, SETSTATE_ENDPOINT, RawData, ) from pyatmo.helpers import extract_raw_data from pyatmo.home import Home from pyatmo.modules.module import Energy, MeasureInterval, Module if TYPE_CHECKING: from pyatmo.auth import AbstractAsyncAuth LOG = logging.getLogger(__name__) class AsyncAccount: """Async class of a Netatmo account.""" def __init__( self, auth: AbstractAsyncAuth, favorite_stations: bool = True, ) -> None: """Initialize the Netatmo account.""" self.auth: AbstractAsyncAuth = auth self.user: str | None = None self.all_homes_id: dict[str, str] = {} self.homes: dict[str, Home] = {} self.raw_data: RawData = {} self.favorite_stations: bool = favorite_stations self.public_weather_areas: dict[str, modules.PublicWeatherArea] = {} self.modules: dict[str, Module] = {} def __repr__(self) -> str: """Return the representation.""" return ( f"{self.__class__.__name__}(user={self.user}, home_ids={self.homes.keys()}" ) def process_topology(self, disabled_homes_ids: list[str] | None = None) -> None: """Process topology information from /homesdata.""" if disabled_homes_ids is None: disabled_homes_ids = [] for home in self.raw_data["homes"]: home_id = home.get("id", "Unknown") home_name = home.get("name", "Unknown") self.all_homes_id[home_id] = home_name if home_id in disabled_homes_ids: if home_id in self.homes: del self.homes[home_id] continue if home_id in self.homes: self.homes[home_id].update_topology(home) else: self.homes[home_id] = Home(self.auth, raw_data=home) async def async_update_topology( self, disabled_homes_ids: list[str] | None = None, ) -> None: """Retrieve topology data from /homesdata.""" resp = await self.auth.async_post_api_request( endpoint=GETHOMESDATA_ENDPOINT, ) self.raw_data = extract_raw_data(await resp.json(), "homes") self.user = self.raw_data.get("user", {}).get("email") self.process_topology(disabled_homes_ids=disabled_homes_ids) async def async_update_status(self, home_id: str) -> None: """Retrieve status data from /homestatus.""" resp = await self.auth.async_post_api_request( endpoint=GETHOMESTATUS_ENDPOINT, params={"home_id": home_id}, ) raw_data = extract_raw_data(await resp.json(), HOME) await self.homes[home_id].update(raw_data, do_raise_for_reachability_error=True) async def async_update_events(self, home_id: str) -> None: """Retrieve events from /getevents.""" resp = await self.auth.async_post_api_request( endpoint=GETEVENTS_ENDPOINT, params={"home_id": home_id}, ) raw_data = extract_raw_data(await resp.json(), HOME) await self.homes[home_id].update(raw_data) async def async_update_weather_stations(self) -> None: """Retrieve status data from /getstationsdata.""" params = {"get_favorites": ("true" if self.favorite_stations else "false")} await self._async_update_data( GETSTATIONDATA_ENDPOINT, params=params, ) async def async_update_air_care(self) -> None: """Retrieve status data from /gethomecoachsdata.""" await self._async_update_data(GETHOMECOACHDATA_ENDPOINT) async def async_update_measures( self, home_id: str, module_id: str, start_time: int | None = None, end_time: int | None = None, interval: MeasureInterval = MeasureInterval.HOUR, days: int = 7, ) -> None: """Retrieve measures data from /getmeasure.""" module = self.homes[home_id].modules[module_id] if module.has_feature("historical_data"): module = cast("Energy", module) await module.async_update_measures( start_time=start_time, end_time=end_time, interval=interval, days=days, ) def register_public_weather_area( self, lat_ne: str, lon_ne: str, lat_sw: str, lon_sw: str, required_data_type: str | None = None, filtering: bool = False, *, area_id: str = str(uuid4()), ) -> str: """Register public weather area to monitor.""" self.public_weather_areas[area_id] = modules.PublicWeatherArea( lat_ne, lon_ne, lat_sw, lon_sw, required_data_type, filtering, ) return area_id async def async_update_public_weather(self, area_id: str) -> None: """Retrieve status data from /getpublicdata.""" params = { "lat_ne": self.public_weather_areas[area_id].location.lat_ne, "lon_ne": self.public_weather_areas[area_id].location.lon_ne, "lat_sw": self.public_weather_areas[area_id].location.lat_sw, "lon_sw": self.public_weather_areas[area_id].location.lon_sw, "filtering": ( "true" if self.public_weather_areas[area_id].filtering else "false" ), } await self._async_update_data( GETPUBLIC_DATA_ENDPOINT, tag="body", params=params, area_id=area_id, ) async def _async_update_data( self, endpoint: str, params: dict[str, Any] | None = None, tag: str = "devices", area_id: str | None = None, ) -> None: """Retrieve status data from .""" resp = await self.auth.async_post_api_request(endpoint=endpoint, params=params) raw_data = extract_raw_data(await resp.json(), tag) await self.update_devices(raw_data, area_id) async def async_set_state(self, home_id: str, data: dict[str, Any]) -> None: """Modify device state by passing JSON specific to the device.""" LOG.debug("Setting state: %s", data) post_params = { "json": { HOME: { "id": home_id, **data, }, }, } resp = await self.auth.async_post_api_request( endpoint=SETSTATE_ENDPOINT, params=post_params, ) LOG.debug("Response: %s", resp) async def update_devices( self, raw_data: RawData, area_id: str | None = None, ) -> None: """Update device states.""" for device_data in raw_data.get("devices", {}): if home_id := device_data.get( "home_id", self.find_home_of_device(device_data), ): if home_id not in self.homes: modules_data = [] for module_data in device_data.get("modules", []): module_data["home_id"] = home_id module_data["id"] = module_data["_id"] module_data["name"] = module_data.get("module_name") modules_data.append(normalize_weather_attributes(module_data)) modules_data.append(normalize_weather_attributes(device_data)) self.homes[home_id] = Home( self.auth, raw_data={ "id": home_id, "name": device_data.get("home_name", "Unknown"), "modules": modules_data, }, ) await self.homes[home_id].update( {HOME: {"modules": [normalize_weather_attributes(device_data)]}}, ) else: LOG.debug("No home %s (%s) found.", home_id, home_id) for module_data in device_data.get("modules", []): module_data["home_id"] = home_id await self.update_devices({"devices": [module_data]}) if ( device_data["type"] == "NHC" or self.find_home_of_device(device_data) is None ): device_data["name"] = device_data.get( "station_name", device_data.get("module_name", "Unknown"), ) device_data = normalize_weather_attributes(device_data) if device_data["id"] not in self.modules: self.modules[device_data["id"]] = getattr( modules, device_data["type"], )( home=self, module=device_data, ) await self.modules[device_data["id"]].update(device_data) if device_data.get("modules", []): self.modules[device_data["id"]].modules = [ module["_id"] for module in device_data["modules"] ] if area_id is not None: self.public_weather_areas[area_id].update(raw_data) def find_home_of_device(self, device_data: dict[str, Any]) -> str | None: """Find home_id of device.""" return next( ( home_id for home_id, home in self.homes.items() if device_data["_id"] in home.modules ), None, ) ATTRIBUTES_TO_FIX = { "_id": "id", "firmware": "firmware_revision", "wifi_status": "wifi_strength", "rf_status": "rf_strength", "Temperature": "temperature", "Humidity": "humidity", "Pressure": "pressure", "CO2": "co2", "AbsolutePressure": "absolute_pressure", "Noise": "noise", "Rain": "rain", "WindStrength": "wind_strength", "WindAngle": "wind_angle", "GustStrength": "gust_strength", "GustAngle": "gust_angle", } def normalize_weather_attributes(raw_data: RawData) -> dict[str, Any]: """Normalize weather attributes.""" result: dict[str, Any] = {} for attribute, value in raw_data.items(): if attribute == "dashboard_data": result.update(**normalize_weather_attributes(value)) else: result[ATTRIBUTES_TO_FIX.get(attribute, attribute)] = value return result pyatmo-9.2.1/src/pyatmo/auth.py000066400000000000000000000150531501740523400164540ustar00rootroot00000000000000"""Support for Netatmo authentication.""" from __future__ import annotations from abc import ABC, abstractmethod from json import JSONDecodeError import logging from typing import Any from aiohttp import ( ClientError, ClientResponse, ClientSession, ClientTimeout, ContentTypeError, ) from pyatmo.const import ( AUTHORIZATION_HEADER, DEFAULT_BASE_URL, ERRORS, FORBIDDEN_ERROR_CODE, THROTTLING_ERROR_CODE, WEBHOOK_URL_ADD_ENDPOINT, WEBHOOK_URL_DROP_ENDPOINT, ) from pyatmo.exceptions import ApiError, ApiThrottlingError LOG = logging.getLogger(__name__) class AbstractAsyncAuth(ABC): """Abstract class to make authenticated requests.""" def __init__( self, websession: ClientSession, base_url: str = DEFAULT_BASE_URL, ) -> None: """Initialize the auth.""" self.websession = websession self.base_url = base_url @abstractmethod async def async_get_access_token(self) -> str: """Return a valid access token.""" async def async_get_image( self, endpoint: str, base_url: str | None = None, params: dict[str, Any] | None = None, ) -> bytes: """Wrap async get requests.""" try: access_token = await self.async_get_access_token() except ClientError as err: error_type = type(err).__name__ msg = f"Access token failure: {error_type} - {err}" raise ApiError(msg) from err headers = {AUTHORIZATION_HEADER: f"Bearer {access_token}"} url = (base_url or self.base_url) + endpoint async with self.websession.get( url, params=params, headers=headers, timeout=ClientTimeout(total=5), ) as resp: resp_content = await resp.read() if resp.headers.get("content-type") == "image/jpeg": return resp_content msg = f"{resp.status} - invalid content-type in response when accessing '{url}'" raise ApiError( msg, ) async def async_post_api_request( self, endpoint: str, base_url: str | None = None, params: dict[str, Any] | None = None, ) -> ClientResponse: """Wrap async post requests.""" return await self.async_post_request( url=(base_url or self.base_url) + endpoint, params=params, ) async def async_post_request( self, url: str, params: dict[str, Any] | None = None, ) -> ClientResponse: """Wrap async post requests.""" access_token = await self.get_access_token() headers = {AUTHORIZATION_HEADER: f"Bearer {access_token}"} req_args = self.prepare_request_arguments(params) async with self.websession.post( url, **req_args, headers=headers, timeout=ClientTimeout(total=5), ) as resp: return await self.process_response(resp, url) async def get_access_token(self) -> str: """Get access token.""" try: return await self.async_get_access_token() except ClientError as err: msg = f"Access token failure: {err}" raise ApiError(msg) from err def prepare_request_arguments(self, params: dict | None) -> dict: """Prepare request arguments.""" req_args = {"data": params if params is not None else {}} if "params" in req_args["data"]: req_args["params"] = req_args["data"]["params"] req_args["data"].pop("params") if "json" in req_args["data"]: req_args["json"] = req_args["data"]["json"] req_args.pop("data") return req_args async def process_response(self, resp: ClientResponse, url: str) -> ClientResponse: """Process response.""" resp_status = resp.status resp_content = await resp.read() if not resp.ok: LOG.debug("The Netatmo API returned %s (%s)", resp_content, resp_status) await self.handle_error_response(resp, resp_status, url) return await self.handle_success_response(resp, resp_content) async def handle_error_response( self, resp: ClientResponse, resp_status: int, url: str, ) -> None: """Handle error response.""" try: resp_json = await resp.json() message = ( f"{resp_status} - " f"{ERRORS.get(resp_status, '')} - " f"{resp_json['error']['message']} " f"({resp_json['error']['code']}) " f"when accessing '{url}'", ) if ( resp_status == FORBIDDEN_ERROR_CODE and resp_json["error"]["code"] == THROTTLING_ERROR_CODE ): raise ApiThrottlingError(message) raise ApiError(message) except (JSONDecodeError, ContentTypeError) as exc: msg = ( f"{resp_status} - " f"{ERRORS.get(resp_status, '')} - " f"when accessing '{url}'" ) raise ApiError( msg, ) from exc async def handle_success_response( self, resp: ClientResponse, resp_content: bytes, ) -> ClientResponse: """Handle success response.""" try: if "application/json" in resp.headers.get("content-type", []): return resp if resp_content not in [b"", b"None"]: return resp except (TypeError, AttributeError): LOG.debug("Invalid response %s", resp) return resp async def async_addwebhook(self, webhook_url: str) -> None: """Register webhook.""" try: resp = await self.async_post_api_request( endpoint=WEBHOOK_URL_ADD_ENDPOINT, params={"url": webhook_url}, ) except TimeoutError as exc: msg = "Webhook registration timed out" raise ApiError(msg) from exc else: LOG.debug("addwebhook: %s", resp) async def async_dropwebhook(self) -> None: """Unregister webhook.""" try: resp = await self.async_post_api_request( endpoint=WEBHOOK_URL_DROP_ENDPOINT, params={"app_types": "app_security"}, ) except TimeoutError as exc: msg = "Webhook registration timed out" raise ApiError(msg) from exc else: LOG.debug("dropwebhook: %s", resp) pyatmo-9.2.1/src/pyatmo/const.py000066400000000000000000000077411501740523400166460ustar00rootroot00000000000000"""Common constants.""" from __future__ import annotations from typing import Any ERRORS: dict[int, str] = { 400: "Bad request", 401: "Unauthorized", 403: "Forbidden", 404: "Not found", 406: "Not Acceptable", 500: "Internal Server Error", 502: "Bad Gateway", 503: "Service Unavailable", } # Special types RawData = dict[str, Any] DEFAULT_BASE_URL: str = "https://api.netatmo.com/" # Endpoints AUTH_REQ_ENDPOINT = "oauth2/token" AUTH_URL_ENDPOINT = "oauth2/authorize" WEBHOOK_URL_ADD_ENDPOINT = "api/addwebhook" WEBHOOK_URL_DROP_ENDPOINT = "api/dropwebhook" GETHOMESDATA_ENDPOINT = "api/homesdata" GETHOMESTATUS_ENDPOINT = "api/homestatus" GETEVENTS_ENDPOINT = "api/getevents" SETTHERMMODE_ENDPOINT = "api/setthermmode" SETROOMTHERMPOINT_ENDPOINT = "api/setroomthermpoint" GETROOMMEASURE_ENDPOINT = "api/getroommeasure" SWITCHHOMESCHEDULE_ENDPOINT = "api/switchhomeschedule" SYNCHOMESCHEDULE_ENDPOINT = "api/synchomeschedule" GETHOMEDATA_ENDPOINT = "api/gethomedata" GETCAMERAPICTURE_ENDPOINT = "api/getcamerapicture" GETEVENTSUNTIL_ENDPOINT = "api/geteventsuntil" SETPERSONSAWAY_ENDPOINT = "api/setpersonsaway" SETPERSONSHOME_ENDPOINT = "api/setpersonshome" SETSTATE_ENDPOINT = "api/setstate" GETHOMECOACHDATA_ENDPOINT = "api/gethomecoachsdata" GETMEASURE_ENDPOINT = "api/getmeasure" GETSTATIONDATA_ENDPOINT = "api/getstationsdata" GETPUBLIC_DATA_ENDPOINT = "api/getpublicdata" AUTHORIZATION_HEADER = "Authorization" # Possible scops ALL_SCOPES: list[str] = [ "access_camera", # Netatmo camera products "access_doorbell", # Netatmo Smart Video Doorbell "access_presence", # Netatmo Smart Outdoor Camera "read_bubendorff", # Bubbendorf shutters "read_bfi", # BTicino IP "read_camera", # Netatmo camera products "read_carbonmonoxidedetector", # Netatmo CO sensor "read_doorbell", # Netatmo Smart Video Doorbell "read_homecoach", # Netatmo Smart Indoor Air Quality Monitor "read_magellan", # Legrand Wiring device or Electrical panel products "read_mhs1", # Bticino MyHome Server 1 modules "read_mx", # BTicino Classe 300 EOS "read_presence", # Netatmo Smart Outdoor Camera "read_smarther", # Smarther with Netatmo thermostat "read_smokedetector", # Smart Smoke Alarm information and events "read_station", # Netatmo weather station "read_thermostat", # Netatmo climate products "write_bubendorff", # Bubbendorf shutters "write_bfi", # BTicino IP "write_camera", # Netatmo camera products "write_magellan", # Legrand Wiring device or Electrical panel products "write_mhs1", # Bticino MyHome Server 1 modules "write_mx", # BTicino Classe 300 EOS "write_presence", # Netatmo Smart Outdoor Camera "write_smarther", # Smarther products "write_thermostat", # Netatmo climate products ] EVENTS = "events" SCHEDULES = "schedules" MANUAL = "manual" MAX = "max" HOME = "home" FROSTGUARD = "hg" SCHEDULE = "schedule" OFF = "off" AWAY = "away" HEATING = "heating" COOLING = "cooling" IDLE = "idle" PILOT_WIRE_COMFORT = "comfort" PILOT_WIRE_AWAY = "away" PILOT_WIRE_FROST_GUARD = "frost_guard" PILOT_WIRE_STAND_BY = "stand_by" PILOT_WIRE_COMFORT_1 = "comfort_1" # => doc unclear and contradictory: it is in the json schema but no in the doc PILOT_WIRE_COMFORT_2 = "comfort_2" # => same STATION_TEMPERATURE_TYPE = "temperature" STATION_PRESSURE_TYPE = "pressure" STATION_HUMIDITY_TYPE = "humidity" ACCESSORY_RAIN_LIVE_TYPE = "rain_live" ACCESSORY_RAIN_60MIN_TYPE = "rain_60min" ACCESSORY_RAIN_24H_TYPE = "rain_24h" ACCESSORY_RAIN_TIME_TYPE = "rain_timeutc" ACCESSORY_WIND_STRENGTH_TYPE = "wind_strength" ACCESSORY_WIND_ANGLE_TYPE = "wind_angle" ACCESSORY_WIND_TIME_TYPE = "wind_timeutc" ACCESSORY_GUST_STRENGTH_TYPE = "gust_strength" ACCESSORY_GUST_ANGLE_TYPE = "gust_angle" # 2 days of dynamic historical data stored MAX_HISTORY_TIME_FRAME = 24 * 2 * 3600 UNKNOWN = "unknown" # Error codes THROTTLING_ERROR_CODE = 26 FORBIDDEN_ERROR_CODE = 403 # Location constants GPS_COORDINATES_COUNT = 2 pyatmo-9.2.1/src/pyatmo/enums.py000066400000000000000000000010221501740523400166310ustar00rootroot00000000000000"""Enums for the pyatmo package.""" from enum import StrEnum class ScheduleType(StrEnum): """Enum representing the type of a schedule.""" THERM = "therm" COOLING = "cooling" ELECTRICITY = "electricity" EVENT = "event" AUTO = "auto" class TemperatureControlMode(StrEnum): """Temperature control mode.""" HEATING = "heating" COOLING = "cooling" SCHEDULE_TYPE_MAPPING = { TemperatureControlMode.HEATING: ScheduleType.THERM, TemperatureControlMode.COOLING: ScheduleType.COOLING, } pyatmo-9.2.1/src/pyatmo/event.py000066400000000000000000000053241501740523400166340ustar00rootroot00000000000000"""Module to represent a Netatmo event.""" from __future__ import annotations from dataclasses import dataclass from enum import Enum from typing import TYPE_CHECKING if TYPE_CHECKING: from pyatmo.const import RawData EVENT_ATTRIBUTES_MAP = {"id": "entity_id", "type": "event_type", "time": "event_time"} class EventTypes(Enum): """Event types.""" movement = "movement" person = "person" person_away = "person_away" connection = "connection" disconnection = "disconnection" new_module = "new_module" module_connect = "module_connect" module_disconnect = "module_disconnect" module_low_battery = "module_low_battery" module_end_update = "module_end_update" on = "on" off = "off" sd = "sd" alim = "alim" boot = "boot" outdoor = "outdoor" daily_summary = "daily_summary" tag_big_move = "tag_big_move" tag_small_move = "tag_small_move" tag_uninstalled = "tag_uninstalled" tag_open = "tag_open" hush = "hush" smoke = "smoke" tampered = "tampered" wifi_status = "wifi_status" battery_status = "battery_status" detection_chamber_status = "detection_chamber_status" sound_test = "sound_test" siren_sounding = "siren_sounding" siren_tampered = "siren_tampered" incoming_call = "incoming_call" accepted_call = "accepted_call" missed_call = "missed_call" co_detected = "co_detected" class VideoStatus(Enum): """Video states.""" available = "available" deleted = "deleted" @dataclass class Snapshot: """Class to represent a Netatmo event snapshot.""" snapshot_id: str version: int key: str url: str @dataclass class Event: """Class to represent a Netatmo events.""" entity_id: str event_type: EventTypes event_time: int message: str | None = None camera_id: str | None = None device_id: str | None = None module_id: str | None = None person_id: str | None = None video_id: str | None = None sub_type: int | None = None snapshot: Snapshot | None = None vignette: Snapshot | None = None video_status: VideoStatus | None = None is_arrival: bool | None = None subevents: list[Event] | None = None def __init__(self, home_id: str, raw_data: RawData) -> None: """Initialize a Netatmo event instance.""" self.home_id = home_id self._init_attributes(raw_data) def _init_attributes(self, raw_data: RawData) -> None: """Initialize attributes of the instance.""" for attrib, value in raw_data.items(): if attrib == "subevents": value = [Event(self.home_id, event) for event in value] setattr(self, EVENT_ATTRIBUTES_MAP.get(attrib, attrib), value) pyatmo-9.2.1/src/pyatmo/exceptions.py000066400000000000000000000014671501740523400177000ustar00rootroot00000000000000"""Exceptions for pyatmo.""" class NoScheduleError(Exception): """Raised when no schedule is found.""" class InvalidScheduleError(Exception): """Raised when an invalid schedule is encountered.""" class InvalidHomeError(Exception): """Raised when an invalid home is encountered.""" class InvalidRoomError(Exception): """Raised when an invalid room is encountered.""" class NoDeviceError(Exception): """Raised when no device is found.""" class ApiError(Exception): """Raised when an API error is encountered.""" class ApiThrottlingError(ApiError): """Raised when an API error is encountered.""" class ApiHomeReachabilityError(ApiError): """Raised when an API error is encountered.""" class InvalidStateError(Exception): """Raised when an invalid state is encountered.""" pyatmo-9.2.1/src/pyatmo/helpers.py000066400000000000000000000034331501740523400171540ustar00rootroot00000000000000"""Collection of helper functions.""" from __future__ import annotations import logging from typing import TYPE_CHECKING, cast from pyatmo.exceptions import NoDeviceError if TYPE_CHECKING: from pyatmo.const import RawData LOG: logging.Logger = logging.getLogger(__name__) def fix_id(raw_data: list[RawData | str]) -> list[RawData | str]: """Fix known errors in station ids like superfluous spaces.""" if not raw_data: return raw_data for station in raw_data: if not isinstance(station, dict): continue if station.get("_id") is None: continue station["_id"] = cast("dict", station)["_id"].replace(" ", "") for module in station.get("modules", {}): module["_id"] = module["_id"].replace(" ", "") return raw_data def extract_raw_data(resp: RawData, tag: str) -> RawData: """Extract raw data from server response.""" if tag == "body": return {"public": resp["body"], "errors": []} if resp is None or "body" not in resp or tag not in resp["body"]: LOG.debug("Server response (tag: %s): %s", tag, resp) msg = "No device found, errors in response" raise NoDeviceError(msg) if tag == "homes": homes = fix_id(resp["body"].get(tag)) if not homes: LOG.debug("Server response (tag: %s): %s", tag, resp) msg = "No homes found" raise NoDeviceError(msg) return { tag: homes, "errors": resp["body"].get("errors", []), } if not (raw_data := fix_id(resp["body"].get(tag))): LOG.debug("Server response (tag: %s): %s", tag, resp) msg = "No device data available" raise NoDeviceError(msg) return {tag: raw_data, "errors": resp["body"].get("errors", [])} pyatmo-9.2.1/src/pyatmo/home.py000066400000000000000000000356211501740523400164460ustar00rootroot00000000000000"""Module to represent a Netatmo home.""" from __future__ import annotations import logging from typing import TYPE_CHECKING, Any, cast from pyatmo import modules from pyatmo.const import ( EVENTS, SCHEDULES, SETPERSONSAWAY_ENDPOINT, SETPERSONSHOME_ENDPOINT, SETSTATE_ENDPOINT, SETTHERMMODE_ENDPOINT, SWITCHHOMESCHEDULE_ENDPOINT, SYNCHOMESCHEDULE_ENDPOINT, RawData, ) from pyatmo.enums import SCHEDULE_TYPE_MAPPING, TemperatureControlMode from pyatmo.event import Event from pyatmo.exceptions import ( ApiHomeReachabilityError, InvalidScheduleError, InvalidStateError, NoScheduleError, ) from pyatmo.person import Person from pyatmo.room import Room from pyatmo.schedule import Schedule if TYPE_CHECKING: from aiohttp import ClientResponse from pyatmo.auth import AbstractAsyncAuth from pyatmo.modules import Module from pyatmo.modules.netatmo import NACamera LOG = logging.getLogger(__name__) class Home: """Class to represent a Netatmo home.""" auth: AbstractAsyncAuth entity_id: str name: str rooms: dict[str, Room] modules: dict[str, Module] schedules: dict[str, Schedule] persons: dict[str, Person] events: dict[str, Event] temperature_control_mode: TemperatureControlMode | None = None therm_mode: str | None = None therm_setpoint_default_duration: int | None = None cooling_mode: str | None = None def __init__(self, auth: AbstractAsyncAuth, raw_data: RawData) -> None: """Initialize a Netatmo home instance.""" self.auth = auth self.entity_id = raw_data["id"] self.name = raw_data.get("name", "Unknown") self.modules = { module["id"]: self.get_module(module) for module in raw_data.get("modules", []) } self.rooms = { room["id"]: Room( home=self, room=room, all_modules=self.modules, ) for room in raw_data.get("rooms", []) } self.schedules = { s["id"]: Schedule(home=self, raw_data=s) for s in raw_data.get(SCHEDULES, []) } self.persons = { s["id"]: Person(home=self, raw_data=s) for s in raw_data.get("persons", []) } self.events = {} self.temperature_control_mode = get_temperature_control_mode( raw_data.get("temperature_control_mode"), ) self.therm_mode = raw_data.get("therm_mode") self.therm_setpoint_default_duration = raw_data.get( "therm_setpoint_default_duration", ) self.cooling_mode = raw_data.get("cooling_mode") def get_module(self, module: dict) -> Module: """Return module.""" try: return getattr(modules, module["type"])( home=self, module=module, ) except AttributeError: LOG.info("Unknown device type %s", module["type"]) return modules.NLunknown( home=self, module=module, ) def update_topology(self, raw_data: RawData) -> None: """Update topology.""" self.name = raw_data.get("name", "Unknown") raw_modules = raw_data.get("modules", []) self.temperature_control_mode = get_temperature_control_mode( raw_data.get("temperature_control_mode"), ) self.therm_mode = raw_data.get("therm_mode") self.therm_setpoint_default_duration = raw_data.get( "therm_setpoint_default_duration", ) self.cooling_mode = raw_data.get("cooling_mode") for module in raw_modules: if (module_id := module["id"]) not in self.modules: self.modules[module_id] = self.get_module(module) else: self.modules[module_id].update_topology(module) # Drop module if has been removed for module in self.modules.keys() - {m["id"] for m in raw_modules}: self.modules.pop(module) raw_rooms = raw_data.get("rooms", []) for room in raw_rooms: if (room_id := room["id"]) not in self.rooms: self.rooms[room_id] = Room( home=self, room=room, all_modules=self.modules, ) else: self.rooms[room_id].update_topology(room) # Drop room if has been removed for room in self.rooms.keys() - {m["id"] for m in raw_rooms}: self.rooms.pop(room) raw_schedules = raw_data.get("schedules", []) for schedule in raw_schedules: if (schedule_id := schedule["id"]) not in self.schedules: self.schedules[schedule_id] = Schedule(home=self, raw_data=schedule) else: self.schedules[schedule_id].update_topology(schedule) # Drop schedule if has been removed for schedule in self.schedules.keys() - {s["id"] for s in raw_schedules}: self.schedules.pop(schedule) async def update( self, raw_data: RawData, do_raise_for_reachability_error: bool = False, ) -> None: """Update home with the latest data.""" has_error = False for module in raw_data.get("errors", []): has_error = True await self.modules[module["id"]].update({}) data = raw_data["home"] has_an_update = False for module in data.get("modules", []): has_an_update = True if module["id"] not in self.modules: self.update_topology({"modules": [module]}) await self.modules[module["id"]].update(module) for room in data.get("rooms", []): has_an_update = True self.rooms[room["id"]].update(room) for person_status in data.get("persons", []): # if there is a person update, it means the house has been updated has_an_update = True if person := self.persons.get(person_status["id"]): person.update(person_status) self.events = { s["id"]: Event(home_id=self.entity_id, raw_data=s) for s in data.get(EVENTS, []) } if len(self.events) > 0: has_an_update = True has_one_module_reachable = False for module in self.modules.values(): if module.reachable: has_one_module_reachable = True if hasattr(module, "events"): module = cast("NACamera", module) module.events = [ event for event in self.events.values() if event.module_id == module.entity_id ] if ( do_raise_for_reachability_error and has_error and has_one_module_reachable is False and has_an_update is False ): msg = "No Home update could be performed, all modules unreachable and not updated" raise ApiHomeReachabilityError( msg, ) def get_selected_schedule(self) -> Schedule | None: """Return selected schedule for given home.""" return next( ( schedule for schedule in self.schedules.values() if schedule.selected and self.temperature_control_mode and schedule.type == SCHEDULE_TYPE_MAPPING[self.temperature_control_mode] ), None, ) def get_available_schedules(self) -> list[Schedule]: """Return available schedules for given home.""" return [ schedule for schedule in self.schedules.values() if self.temperature_control_mode and schedule.type == SCHEDULE_TYPE_MAPPING[self.temperature_control_mode] ] def is_valid_schedule(self, schedule_id: str) -> bool: """Check if valid schedule.""" return schedule_id in self.schedules def has_otm(self) -> bool: """Check if any room has an OTM device.""" return any("OTM" in room.device_types for room in self.rooms.values()) def has_bns(self) -> bool: """Check if any room has a BNS device.""" return any("BNS" in room.device_types for room in self.rooms.values()) def get_hg_temp(self) -> float | None: """Return frost guard temperature value for given home.""" if (schedule := self.get_selected_schedule()) is None: return None return schedule.hg_temp def get_away_temp(self) -> float | None: """Return configured away temperature value for given home.""" if (schedule := self.get_selected_schedule()) is None: return None return schedule.away_temp async def async_set_thermmode( self, mode: str | None, end_time: int | None = None, schedule_id: str | None = None, ) -> bool: """Set thermotat mode.""" if schedule_id is not None and not self.is_valid_schedule(schedule_id): msg = f"{schedule_id} is not a valid schedule id." raise NoScheduleError(msg) if mode is None: msg = f"{mode} is not a valid mode." raise NoScheduleError(msg) post_params = {"home_id": self.entity_id, "mode": mode} if end_time is not None and mode in {"hg", "away"}: post_params["endtime"] = str(end_time) if schedule_id is not None and mode == "schedule": post_params["schedule_id"] = schedule_id LOG.debug( "Setting home (%s) mode to %s (%s)", self.entity_id, mode, schedule_id, ) resp = await self.auth.async_post_api_request( endpoint=SETTHERMMODE_ENDPOINT, params=post_params, ) return (await resp.json()).get("status") == "ok" async def async_switch_schedule(self, schedule_id: str) -> bool: """Switch the schedule.""" if not self.is_valid_schedule(schedule_id): msg = f"{schedule_id} is not a valid schedule id" raise NoScheduleError(msg) LOG.debug("Setting home (%s) schedule to %s", self.entity_id, schedule_id) resp = await self.auth.async_post_api_request( endpoint=SWITCHHOMESCHEDULE_ENDPOINT, params={"home_id": self.entity_id, "schedule_id": schedule_id}, ) return (await resp.json()).get("status") == "ok" async def async_set_state(self, data: dict[str, Any]) -> bool: """Set state using given data.""" if not is_valid_state(data): msg = "Data for '/set_state' contains errors." raise InvalidStateError(msg) LOG.debug("Setting state for home (%s) according to %s", self.entity_id, data) resp = await self.auth.async_post_api_request( endpoint=SETSTATE_ENDPOINT, params={"json": {"home": {"id": self.entity_id, **data}}}, ) return (await resp.json()).get("status") == "ok" async def async_set_persons_home( self, person_ids: list[str] | None = None, ) -> ClientResponse: """Mark persons as home.""" post_params: dict[str, Any] = {"home_id": self.entity_id} if person_ids: post_params["person_ids[]"] = person_ids return await self.auth.async_post_api_request( endpoint=SETPERSONSHOME_ENDPOINT, params=post_params, ) async def async_set_persons_away( self, person_id: str | None = None, ) -> ClientResponse: """Mark a person as away or set the whole home to being empty.""" post_params = {"home_id": self.entity_id} if person_id: post_params["person_id"] = person_id return await self.auth.async_post_api_request( endpoint=SETPERSONSAWAY_ENDPOINT, params=post_params, ) async def async_set_schedule_temperatures( self, zone_id: str, temps: dict[str, float], ) -> None: """Set the scheduled room temperature for the given schedule ID.""" selected_schedule = self.get_selected_schedule() if selected_schedule is None: msg = "Could not determine selected schedule." raise NoScheduleError(msg) for zone in (z for z in selected_schedule.zones if z.entity_id == zone_id): for room in (r for r in zone.rooms if r.entity_id in temps): room.therm_setpoint_temperature = temps[room.entity_id] await self.async_sync_schedule(selected_schedule) async def async_sync_schedule( self, schedule: Schedule, ) -> None: """Modify an existing schedule.""" if not is_valid_schedule(schedule): msg = "Data for '/synchomeschedule' contains errors." raise InvalidScheduleError(msg) LOG.debug( "Setting schedule (%s) for home (%s) to %s", schedule.entity_id, self.entity_id, schedule, ) timetable_entries = [ { "m_offset": timetable_entry.m_offset, "zone_id": timetable_entry.zone_id, } for timetable_entry in schedule.timetable ] zones = [] for zone in schedule.zones: new_zone = { "id": zone.entity_id, "name": zone.name, "type": zone.type, "rooms": [ { "id": room.entity_id, "therm_setpoint_temperature": room.therm_setpoint_temperature, } for room in zone.rooms ], } zones.append(new_zone) request_json = { "away_temp": schedule.away_temp, "hg_temp": schedule.hg_temp, "timetable": timetable_entries, "zones": zones, } resp = await self.auth.async_post_api_request( endpoint=SYNCHOMESCHEDULE_ENDPOINT, params={ "params": { "home_id": self.entity_id, "schedule_id": schedule.entity_id, "name": "Default", }, "json": request_json, }, ) return (await resp.json()).get("status") == "ok" def is_valid_state(data: dict[str, Any]) -> bool: """Check set state data.""" return data is not None def is_valid_schedule(schedule: Schedule) -> bool: """Check schedule.""" return ( isinstance(schedule, Schedule) and hasattr(schedule, "entity_id") and schedule.entity_id != "" ) def get_temperature_control_mode( temperature_control_mode: str | None, ) -> TemperatureControlMode | None: """Return temperature control mode.""" return ( TemperatureControlMode(temperature_control_mode) if temperature_control_mode else None ) pyatmo-9.2.1/src/pyatmo/modules/000077500000000000000000000000001501740523400166055ustar00rootroot00000000000000pyatmo-9.2.1/src/pyatmo/modules/__init__.py000066400000000000000000000041441501740523400207210ustar00rootroot00000000000000"""Expose submodules.""" from .base_class import Place from .bticino import ( BNAB, BNAS, BNCS, BNCX, BNDL, BNEU, BNFC, BNIL, BNLD, BNMH, BNMS, BNSL, BNTH, BNTR, BNXM, ) from .idiamant import NBG, NBO, NBR, NBS from .legrand import ( EBU, NLAO, NLAS, NLC, NLD, NLDD, NLE, NLF, NLFE, NLFN, NLG, NLIS, NLJ, NLL, NLLF, NLLM, NLLV, NLM, NLP, NLPBS, NLPC, NLPD, NLPM, NLPO, NLPS, NLPT, NLT, NLTS, NLUF, NLUI, NLUO, NLUP, NLV, Z3L, Z3V, NLunknown, ) from .module import Camera, Dimmer, Fan, Module, Shutter, Switch from .netatmo import ( NAC, NCO, NDB, NHC, NIS, NOC, NPC, NRV, NSD, OTH, OTM, Location, NACamDoorTag, NACamera, NAMain, NAModule1, NAModule2, NAModule3, NAModule4, NAPlug, NATherm1, PublicWeatherArea, ) from .smarther import BNS from .somfy import TPSRS __all__ = [ "BNAB", "BNAS", "BNCS", "BNCX", "BNDL", "BNEU", "BNFC", "BNIL", "BNLD", "BNMH", "BNMS", "BNS", "BNSL", "BNTH", "BNTR", "BNXM", "EBU", "NAC", "NBG", "NBO", "NBR", "NBS", "NCO", "NDB", "NHC", "NIS", "NLAO", "NLAS", "NLC", "NLD", "NLDD", "NLE", "NLF", "NLFE", "NLFN", "NLG", "NLIS", "NLJ", "NLL", "NLLF", "NLLM", "NLLV", "NLM", "NLP", "NLPBS", "NLPC", "NLPD", "NLPM", "NLPO", "NLPS", "NLPT", "NLT", "NLTS", "NLUF", "NLUI", "NLUO", "NLUP", "NLV", "NOC", "NPC", "NRV", "NSD", "OTH", "OTM", "TPSRS", "Z3L", "Z3V", "Camera", "Dimmer", "Fan", "Location", "Module", "NACamDoorTag", "NACamera", "NAMain", "NAModule1", "NAModule2", "NAModule3", "NAModule4", "NAPlug", "NATherm1", "NLunknown", "Place", "PublicWeatherArea", "Shutter", "Switch", ] pyatmo-9.2.1/src/pyatmo/modules/base_class.py000066400000000000000000000140211501740523400212540ustar00rootroot00000000000000"""Base class for Netatmo entities.""" from __future__ import annotations from abc import ABC import bisect from dataclasses import dataclass import logging from operator import itemgetter from time import time from typing import TYPE_CHECKING, Any from pyatmo.const import GPS_COORDINATES_COUNT, MAX_HISTORY_TIME_FRAME, RawData from pyatmo.event import EventTypes from pyatmo.modules.device_types import ApplianceType, DeviceType if TYPE_CHECKING: from collections.abc import Callable, Iterator from pyatmo.home import Home from pyatmo.modules.module import ModuleT LOG = logging.getLogger(__name__) NETATMO_ATTRIBUTES_MAP = { "entity_id": lambda x, y: x.get("id", y), "modules": lambda x, y: x.get("modules_bridged", y), "device_type": lambda x, y: DeviceType(x.get("type", y)), "event_type": lambda x, y: EventTypes(x.get("type", y)), "reachable": lambda x, _: x.get("reachable", False), "monitoring": lambda x, _: x.get("monitoring", False) == "on", "battery_level": lambda x, _: x.get("battery_vp", x.get("battery_level")), "place": lambda x, _: Place(x.get("place")), "target_position__step": lambda x, _: x.get("target_position:step"), "appliance_type": lambda x, y: ApplianceType(x.get("appliance_type", y)), } def default(key: str, val: Any) -> Callable[[dict[str, Any], Any], Any]: # noqa: ANN401 """Return default value.""" return lambda x, _: x.get(key, val) def update_name(name: str, pre_fix: str) -> str: """Remove duplicates from string.""" if name.startswith(pre_fix): return name return f"{pre_fix} {name}" class EntityBase: """Base class for Netatmo entities.""" entity_id: str home: Home bridge: str | None history_features: set[str] history_features_values: dict name: str def __init__(self, home: Home, module: ModuleT) -> None: """Initialize the entity.""" self.home = home self.entity_id = module.get("id", "") self.name = module.get("name", f"Unknown {self.entity_id}") self.bridge = None self.history_features = set() self.history_features_values = {} def has_feature(self, feature: str) -> bool: """Check if the entity has the given feature.""" return hasattr(self, feature) or feature in self.history_features class NetatmoBase(EntityBase, ABC): """Base class for Netatmo entities.""" def __init__(self, raw_data: RawData) -> None: """Initialize a Netatmo entity.""" self.entity_id = raw_data["id"] self.name = raw_data.get("name", f"Unknown {self.entity_id}") self.history_features_values = {} self.history_features = set() def update_topology(self, raw_data: RawData) -> None: """Update topology.""" self._update_attributes(raw_data) def _update_attributes(self, raw_data: RawData) -> None: """Update attributes.""" self.__dict__ = { key: NETATMO_ATTRIBUTES_MAP.get(key, default(key, val))(raw_data, val) for key, val in self.__dict__.items() } now = int(time()) for hist_feature in self.history_features: if hist_feature in self.__dict__: val = getattr(self, hist_feature) if val is None: continue self.add_history_data(hist_feature, val, now) def add_history_data( self, feature: str, value: Any, # noqa: ANN401 time: int, ) -> None: """Add historical data at the given time.""" # get the feature values rolling buffer hist_f = self.history_features_values.setdefault(feature, []) if not hist_f or hist_f[-1][0] <= time: hist_f.append((time, value, self.entity_id)) else: i = bisect.bisect_left(hist_f, time, key=itemgetter(0)) if i < len(hist_f) and hist_f[i][0] == time: hist_f[i] = (time, value, self.entity_id) else: hist_f.insert(i, (time, value, self.entity_id)) # keep timing history to a maximum representative time while len(hist_f) > 0 and hist_f[-1][0] - hist_f[0][0] > MAX_HISTORY_TIME_FRAME: hist_f.pop(0) def get_history_data( self, feature: str, from_ts: float, to_ts: float | None = None, ) -> list[Any]: """Retrieve historical data.""" hist_f = self.history_features_values.get(feature, []) if not hist_f: return [] in_s = bisect.bisect_left(hist_f, from_ts, key=itemgetter(0)) if to_ts is None: out_s = len(hist_f) else: out_s = bisect.bisect_right(hist_f, to_ts, key=itemgetter(0)) return hist_f[in_s:out_s] @dataclass class Location: """Class of Netatmo public weather location.""" latitude: float longitude: float def __init__(self, longitude: float, latitude: float) -> None: """Initialize self.""" self.latitude = latitude self.longitude = longitude def __iter__(self) -> Iterator[float]: """Iterate over latitude and longitude.""" yield self.longitude yield self.latitude @dataclass class Place: """Class of Netatmo public weather place.""" altitude: int | None city: str | None country: str | None timezone: str | None location: Location | None def __init__( self, data: dict[str, Any] | None, ) -> None: """Initialize self.""" if data is None: LOG.debug("Place data is unknown") return if (location := data.get("location")) is None or len( list(location), ) != GPS_COORDINATES_COUNT: LOG.debug("Invalid location data: %s", data) return self.altitude = data.get("altitude") self.city = data.get("city") self.country = data.get("country") self.timezone = data.get("timezone") location_data = list(location) self.location = Location(location_data[0], location_data[1]) pyatmo-9.2.1/src/pyatmo/modules/bticino.py000066400000000000000000000022151501740523400206060ustar00rootroot00000000000000"""Module to represent BTicino modules.""" from __future__ import annotations import logging from pyatmo.modules.module import ( DimmableMixin, Module, Shutter, ShutterMixin, Switch, SwitchMixin, ) LOG = logging.getLogger(__name__) class BNDL(Module): """BTicino door lock.""" class BNSL(Switch): """BTicino staircase light.""" class BNCX(Module): """BTicino internal panel = gateway.""" class BNEU(Module): """BTicino external unit.""" class BNCS(Switch): """Bticino module Controlled Socket.""" class BNXM(Module): """BTicino X meter.""" class BNMS(Shutter): """BTicino motorized shade.""" class BNAS(ShutterMixin, Module): """BTicino automatic shutter.""" class BNAB(Shutter): """BTicino automatic blind.""" class BNMH(Module): """BTicino MyHome server.""" class BNTH(Module): """BTicino thermostat.""" class BNFC(Module): """BTicino fan coil.""" class BNTR(Module): """BTicino radiator thermostat.""" class BNIL(SwitchMixin, Module): """BTicino intelligent light.""" class BNLD(DimmableMixin, SwitchMixin, Module): """BTicino dimmer light.""" pyatmo-9.2.1/src/pyatmo/modules/device_types.py000066400000000000000000000304631501740523400216500ustar00rootroot00000000000000"""Definitions of Netatmo devices types.""" from __future__ import annotations from enum import Enum import logging from typing import Literal LOG = logging.getLogger(__name__) class DeviceType(str, Enum): """Class to represent Netatmo device types.""" # Climate/Energy NAPlug = "NAPlug" # Smart thermostat gateway NATherm1 = "NATherm1" # Smart thermostat NRV = "NRV" # Smart valve NAC = "NAC" # Smart AC control OTH = "OTH" # OpenTherm gateway OTM = "OTM" # OpenTherm modulating thermostat # Cameras/Security NACamDoorTag = "NACamDoorTag" # Smart Door and Window Sensors NACamera = "NACamera" # Smart Indoor Camera NCO = "NCO" # Smart Carbon Monoxide Alarm NDB = "NDB" # Smart Video Doorbell NIS = "NIS" # Smart Indoor Siren NOC = "NOC" # Smart Outdoor Camera (with Siren) NPC = "NPC" # Indoor Camera Advance NSD = "NSD" # Smart Smoke Detector # Weather NAMain = "NAMain" # Smart Home Weather Station NAModule1 = "NAModule1" NAModule2 = "NAModule2" NAModule3 = "NAModule3" NAModule4 = "NAModule4" public = "public" # Home Coach NHC = "NHC" # Smart Indoor Air Quality Monitor # Legrand Wiring devices and electrical panel products NLC = "NLC" # Cable outlet NLD = "NLD" # Remote control double on off dimmer NLDD = "NLDD" # Dimmer NLE = "NLE" # Connected Ecometer NLF = "NLF" # Dimmer Light Switch NLFE = "NLFE" # Dimmer Light Switch Evolution NLFN = "NLFN" # light switch with neutral NLG = "NLG" # Gateway NLGS = "NLGS" # Gateway standalone NLIS = "NLIS" # Double light switch NLL = "NLL" # Italian light switch with neutral NLLM = "NLLM" # Legrand / BTicino shutters NLLV = "NLLV" # Legrand / BTicino shutters NLM = "NLM" # light micro module NLP = "NLP" # Plug NLPBS = "NLPBS" # British standard plugs NLPC = "NLPC" # Connected energy meter NLPD = "NLPD" # Dry contact NLPM = "NLPM" # mobile plug NLPO = "NLPO" # Connected contactor NLPS = "NLPS" # Smart Load Shedder NLPT = "NLPT" # Connected latching relay / Telerupt NLT = "NLT" # Remote control NLV = "NLV" # Legrand / BTicino shutters NLAO = "NLAO" # Legrand wireless batteryless light switch NLUO = "NLUO" # Legrand Plug-In dimmer switch NLUI = "NLUI" # Legrand In-Wall ON/OFF switch NLunknown = "NLunknown" # Legrand device stub NLUF = "NLUF" # Legrand device stub NLAS = "NLAS" # Legrand wireless batteryless scene switch NLUP = "NLUP" # Legrand device stub NLLF = "NLLF" # Legrand Centralized Ventilation Control NLTS = "NLTS" # Legrand motion sensor stub NLJ = "NLJ" # Legrand garage door opener # BTicino Classe 300 EOS BNCX = "BNCX" # internal panel = gateway BNDL = "BNDL" # door lock BNEU = "BNEU" # external unit BNSL = "BNSL" # staircase light BNCS = "BNCS" # Controlled Socket BNXM = "BNXM" # X meter BNMS = "BNMS" # motorized shade BNAS = "BNAS" # automatic shutter BNAB = "BNAB" # automatic blind BNMH = "BNMH" # MyHome server BNTH = "BNTH" # thermostat BNFC = "BNFC" # fan coil BNTR = "BNTR" # radiator BNIL = "BNIL" # intelligent light BNLD = "BNLD" # dimmer light # Bubbendorf shutters NBG = "NBG" # gateway NBO = "NBO" # orientable shutter NBR = "NBR" # roller shutter NBS = "NBS" # swing shutter # Somfy TPSRS = "TPSRS" # Somfy io shutter # 3rd Party BNS = "BNS" # Smarther with Netatmo EBU = "EBU" # EBU gas meter Z3L = "Z3L" # Zigbee 3 Light Z3V = "Z3V" # Zigbee 3 roller shutter # Magellan NLDP = "NLDP" # Pocket Remote @classmethod def _missing_(cls, key: object) -> Literal[DeviceType.NLunknown]: """Handle unknown device types.""" msg = f"{key} device is unknown" LOG.warning(msg) return DeviceType.NLunknown class DeviceCategory(str, Enum): """Class to represent Netatmo device types.""" # temporarily disable locally-disabled and locally-enabled climate = "climate" camera = "camera" siren = "siren" shutter = "shutter" lock = "lock" switch = "switch" sensor = "sensor" weather = "weather" air_care = "air_care" meter = "meter" dimmer = "dimmer" opening = "opening" fan = "fan" DEVICE_CATEGORY_MAP: dict[DeviceType, DeviceCategory] = { DeviceType.NRV: DeviceCategory.climate, DeviceType.NAC: DeviceCategory.climate, DeviceType.NATherm1: DeviceCategory.climate, DeviceType.OTM: DeviceCategory.climate, DeviceType.NOC: DeviceCategory.camera, DeviceType.NPC: DeviceCategory.camera, DeviceType.NACamDoorTag: DeviceCategory.opening, DeviceType.NACamera: DeviceCategory.camera, DeviceType.NDB: DeviceCategory.camera, DeviceType.NAMain: DeviceCategory.weather, DeviceType.NAModule1: DeviceCategory.weather, DeviceType.NAModule2: DeviceCategory.weather, DeviceType.NAModule3: DeviceCategory.weather, DeviceType.NAModule4: DeviceCategory.weather, DeviceType.NHC: DeviceCategory.air_care, DeviceType.NLV: DeviceCategory.shutter, DeviceType.NLLV: DeviceCategory.shutter, DeviceType.NLLM: DeviceCategory.shutter, DeviceType.NBR: DeviceCategory.shutter, DeviceType.NBO: DeviceCategory.shutter, DeviceType.NLP: DeviceCategory.switch, DeviceType.NLPM: DeviceCategory.switch, DeviceType.NLPBS: DeviceCategory.switch, DeviceType.NLIS: DeviceCategory.switch, DeviceType.NLL: DeviceCategory.switch, DeviceType.NLM: DeviceCategory.switch, DeviceType.NLC: DeviceCategory.switch, DeviceType.NLFN: DeviceCategory.dimmer, DeviceType.NLF: DeviceCategory.dimmer, DeviceType.NLFE: DeviceCategory.dimmer, DeviceType.BNS: DeviceCategory.climate, DeviceType.NLPC: DeviceCategory.meter, DeviceType.NLE: DeviceCategory.meter, DeviceType.Z3L: DeviceCategory.dimmer, DeviceType.Z3V: DeviceCategory.shutter, DeviceType.NLUP: DeviceCategory.switch, DeviceType.NLPO: DeviceCategory.switch, DeviceType.TPSRS: DeviceCategory.shutter, DeviceType.NLUO: DeviceCategory.dimmer, DeviceType.NLUI: DeviceCategory.switch, DeviceType.NLUF: DeviceCategory.dimmer, DeviceType.NLPS: DeviceCategory.meter, DeviceType.NLDD: DeviceCategory.switch, DeviceType.NLPT: DeviceCategory.switch, DeviceType.BNMS: DeviceCategory.shutter, DeviceType.BNAS: DeviceCategory.shutter, DeviceType.BNAB: DeviceCategory.shutter, DeviceType.BNTH: DeviceCategory.climate, DeviceType.BNFC: DeviceCategory.climate, DeviceType.BNTR: DeviceCategory.climate, DeviceType.NLPD: DeviceCategory.switch, DeviceType.NLJ: DeviceCategory.shutter, DeviceType.BNIL: DeviceCategory.switch, DeviceType.BNLD: DeviceCategory.dimmer, DeviceType.NIS: DeviceCategory.siren, DeviceType.BNCS: DeviceCategory.switch, DeviceType.NLLF: DeviceCategory.fan, } DEVICE_DESCRIPTION_MAP: dict[DeviceType, tuple[str, str]] = { # Netatmo Climate/Energy DeviceType.NAPlug: ("Netatmo", "Smart Thermostat Gateway"), DeviceType.NATherm1: ("Netatmo", "Smart Thermostat"), DeviceType.NRV: ("Netatmo", "Smart Valve"), DeviceType.NAC: ("Netatmo", "Smart AC Control"), DeviceType.OTH: ("Netatmo", "OpenTherm Gateway"), DeviceType.OTM: ("Netatmo", "OpenTherm Modulating Thermostat"), # Netatmo Cameras/Security DeviceType.NOC: ("Netatmo", "Smart Outdoor Camera"), DeviceType.NPC: ("Netatmo", "Indoor Camera Advance"), DeviceType.NACamera: ("Netatmo", "Smart Indoor Camera"), DeviceType.NSD: ("Netatmo", "Smart Smoke Detector"), DeviceType.NIS: ("Netatmo", "Smart Indoor Siren"), DeviceType.NACamDoorTag: ("Netatmo", "Smart Door/Window Sensors"), DeviceType.NDB: ("Netatmo", "Smart Video Doorbell"), DeviceType.NCO: ("Netatmo", "Smart Carbon Monoxide Alarm"), # Netatmo Weather DeviceType.NAMain: ("Netatmo", "Smart Home Weather station"), DeviceType.NAModule1: ("Netatmo", "Smart Outdoor Module"), DeviceType.NAModule2: ("Netatmo", "Smart Anemometer"), DeviceType.NAModule3: ("Netatmo", "Smart Rain Gauge"), DeviceType.NAModule4: ("Netatmo", "Smart Indoor Module"), DeviceType.public: ("Netatmo", "Public Weather station"), # Netatmo Home Coach DeviceType.NHC: ("Netatmo", "Smart Indoor Air Quality Monitor"), # Legrand Wiring devices and electrical panel products DeviceType.NLG: ("Legrand", "Gateway"), DeviceType.NLGS: ("Legrand", "Gateway standalone"), DeviceType.NLP: ("Legrand", "Plug"), DeviceType.NLPM: ("Legrand", "Mobile plug"), DeviceType.NLPBS: ("Legrand", "British standard plugs"), DeviceType.NLF: ("Legrand", "2 wire light switch/dimmer"), DeviceType.NLFE: ("Legrand", "2 wire light switch/dimmer evolution"), DeviceType.NLIS: ("Legrand", "Double switch"), DeviceType.NLFN: ("Legrand", "Light switch/dimmer with neutral"), DeviceType.NLM: ("Legrand", "Light micro module"), DeviceType.NLL: ("Legrand", "Italian light switch with neutral"), DeviceType.NLLF: ("Legrand", "Centralized ventilation device"), DeviceType.NLV: ("Legrand/BTicino", "Shutters"), DeviceType.NLLV: ("Legrand/BTicino", "Shutters"), DeviceType.NLLM: ("Legrand/BTicino", "Shutters"), DeviceType.NLPO: ("Legrand", "Connected Contactor"), DeviceType.NLPT: ("Legrand", "Connected Latching Relay"), DeviceType.NLPC: ("Legrand", "Connected Energy Meter"), DeviceType.NLE: ("Legrand", "Connected Ecometer"), DeviceType.NLPS: ("Legrand", "Smart Load Shedder"), DeviceType.NLC: ("Legrand", "Cable Outlet"), DeviceType.NLT: ("Legrand", "Global Remote Control"), DeviceType.NLAS: ("Legrand", "Wireless batteryless scene switch"), DeviceType.NLD: ("Legrand", "Remote Control"), DeviceType.NLDD: ("Legrand", "Dimmer"), DeviceType.NLUP: ("Legrand", "Power outlet"), DeviceType.NLUO: ("Legrand", "Plug-In dimmer switch"), DeviceType.NLUI: ("Legrand", "In-wall switch"), DeviceType.NLTS: ("Legrand", "Motion sensor"), DeviceType.NLUF: ("Legrand", "In-Wall dimmer"), DeviceType.NLJ: ("Legrand", "Garage door opener"), # BTicino Classe 300 EOS DeviceType.BNCX: ("BTicino", "Internal Panel"), DeviceType.BNEU: ("BTicino", "External Unit"), DeviceType.BNDL: ("BTicino", "Door Lock"), DeviceType.BNSL: ("BTicino", "Staircase Light"), DeviceType.BNMS: ("BTicino", "Motorized Shade"), DeviceType.BNAS: ("BTicino", "Automatic Shutter"), DeviceType.BNAB: ("BTicino", "Automatic Blind"), DeviceType.BNMH: ("BTicino", "MyHome server 1"), DeviceType.BNTH: ("BTicino", "Thermostat"), DeviceType.BNFC: ("BTicino", "Fan coil"), DeviceType.BNTR: ("BTicino", "Module towel rail"), DeviceType.BNIL: ("BTicino", "Intelligent light"), DeviceType.BNLD: ("BTicino", "Dimmer"), DeviceType.BNCS: ("BTicino", "Controlled socket"), # Bubbendorf shutters DeviceType.NBG: ("Bubbendorf", "Gateway"), DeviceType.NBR: ("Bubbendorf", "Roller Shutter"), DeviceType.NBO: ("Bubbendorf", "Orientable Shutter"), DeviceType.NBS: ("Bubbendorf", "Swing Shutter"), # Somfy DeviceType.TPSRS: ("Somfy", "io Shutter"), # 3rd Party DeviceType.BNS: ("Smarther", "Smarther with Netatmo"), DeviceType.Z3L: ("3rd Party", "Zigbee 3 Light"), DeviceType.Z3V: ("3rd Party", "Zigbee 3 roller shutter"), DeviceType.EBU: ("3rd Party", "EBU gas meter"), DeviceType.NLPD: ("Drivia", "Dry contact"), } class ApplianceType(str, Enum): """Class to represent appliance type of a module. This is only for Home + Control.""" # temporarily disable locally-disabled and locally-enabled light = "light" fridge_freezer = "fridge_freezer" oven = "oven" washing_machine = "washing_machine" tumble_dryer = "tumble_dryer" dishwasher = "dishwasher" multimedia = "multimedia" router = "router" other = "other" ooking = "cooking" radiator = "radiator" radiator_without_pilot_wire = "radiator_without_pilot_wire" water_heater = "water_heater" extractor_hood = "extractor_hood" contactor = "contactor" dryer = "dryer" electric_charger = "electric_charger" unknown = "unknown" @classmethod def _missing_(cls, key: object) -> Literal[ApplianceType.unknown]: """Handle unknown device types.""" msg = f"{key} appliance type is unknown" LOG.warning(msg) return ApplianceType.unknown pyatmo-9.2.1/src/pyatmo/modules/idiamant.py000066400000000000000000000012131501740523400207420ustar00rootroot00000000000000"""Module to represent iDiamant modules.""" from __future__ import annotations import logging from pyatmo.modules.module import ( FirmwareMixin, Module, RfMixin, ShutterMixin, WifiMixin, ) LOG = logging.getLogger(__name__) class NBG(FirmwareMixin, WifiMixin, Module): """Class to represent a iDiamant NBG.""" class NBR(FirmwareMixin, RfMixin, ShutterMixin, Module): """Class to represent a iDiamant NBR.""" class NBO(FirmwareMixin, RfMixin, ShutterMixin, Module): """Class to represent a iDiamant NBO.""" class NBS(FirmwareMixin, RfMixin, ShutterMixin, Module): """Class to represent a iDiamant NBS.""" pyatmo-9.2.1/src/pyatmo/modules/legrand.py000066400000000000000000000073161501740523400206020ustar00rootroot00000000000000"""Module to represent Legrand modules.""" from __future__ import annotations import logging from typing import TYPE_CHECKING from pyatmo.modules.module import ( BatteryMixin, ContactorMixin, Dimmer, EnergyHistoryLegacyMixin, EnergyHistoryMixin, Fan, FirmwareMixin, Module, ModuleT, OffloadMixin, PowerMixin, RemoteControlMixin, ShutterMixin, Switch, SwitchMixin, WifiMixin, ) if TYPE_CHECKING: from pyatmo.home import Home LOG = logging.getLogger(__name__) class NLG(FirmwareMixin, OffloadMixin, WifiMixin, Module): """Legrand gateway.""" class NLT(RemoteControlMixin, BatteryMixin): """Legrand global remote control...but also wireless switch, like NLD.""" class NLP(OffloadMixin, Switch): """Legrand plug.""" class NLPM(OffloadMixin, Switch): """Legrand mobile plug.""" class NLPO(ContactorMixin, OffloadMixin, Switch): """Legrand contactor.""" class NLPT(OffloadMixin, Switch): """Legrand latching relay/teleruptor.""" class NLPBS(Switch): """Legrand british standard plug.""" class NLF(Dimmer): """Legrand 2 wire light switch.""" class NLFN(Dimmer): """Legrand light switch with neutral.""" class NLFE(Dimmer): """Legrand On-Off dimmer switch evolution.""" class NLM(Switch): """Legrand light micro module.""" class NLIS(Switch): """Legrand double switch.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize NLIS module.""" super().__init__(home, module) if "#" not in self.entity_id: # This is a workaround for the fact the this module type has three entries in the API # but one of them is not a light switch self.device_category = None class NLD(RemoteControlMixin, BatteryMixin): """Legrand Double On/Off dimmer remote. Wireless 2 button switch light.""" class NLL(Switch): """Legrand / BTicino italian light switch with neutral.""" class NLV(FirmwareMixin, ShutterMixin, Module): """Legrand / BTicino shutters.""" class NLLV(FirmwareMixin, ShutterMixin, Module): """Legrand / BTicino shutters.""" class NLLM(FirmwareMixin, ShutterMixin, Module): """Legrand / BTicino shutters.""" class NLPC(FirmwareMixin, EnergyHistoryMixin, PowerMixin, Module): """Legrand / BTicino connected energy meter.""" class NLE(FirmwareMixin, EnergyHistoryLegacyMixin, Module): """Legrand / BTicino connected ecometer. no power supported for the NLE (in the home status API).""" class NLPS(FirmwareMixin, EnergyHistoryMixin, PowerMixin, Module): """Legrand / BTicino smart load shedder.""" class NLC(OffloadMixin, Switch): """Legrand / BTicino cable outlet.""" class NLDD(RemoteControlMixin): """Legrand NLDD dimmer remote control.""" class NLUP(Switch): """Legrand NLUP Power outlet.""" class NLAO(RemoteControlMixin): """Legrand wireless batteryless light switch.""" class NLUI(FirmwareMixin, SwitchMixin, Module): """Legrand NLUI in-wall switch.""" class NLUF(Dimmer): """Legrand NLUF device stub.""" class NLUO(Dimmer): """Legrand NLUO device stub.""" class NLLF(Fan, PowerMixin, EnergyHistoryMixin): """Legrand NLLF fan/ventilation device.""" class NLunknown(Module): """NLunknown device stub.""" class NLAS(RemoteControlMixin): """NLAS wireless batteryless scene switch.""" class Z3L(Dimmer): """Zigbee 3 Light.""" class Z3V(FirmwareMixin, ShutterMixin, Module): """Zigbee 3 roller shutter.""" class EBU(Module): """EBU gas meter.""" class NLTS(Module): """NLTS motion sensor.""" class NLPD(OffloadMixin, Switch): """NLPD dry contact.""" class NLJ(FirmwareMixin, ShutterMixin, Module): """Legrand garage door opener.""" pyatmo-9.2.1/src/pyatmo/modules/module.py000066400000000000000000001064131501740523400204510ustar00rootroot00000000000000"""Module to represent a Netatmo module.""" from __future__ import annotations from datetime import UTC, datetime, timedelta from enum import Enum import logging from operator import itemgetter from time import time from typing import TYPE_CHECKING, Any, LiteralString from aiohttp import ClientConnectorError from pyatmo.const import GETMEASURE_ENDPOINT, RawData from pyatmo.exceptions import ApiError from pyatmo.modules.base_class import EntityBase, NetatmoBase, Place, update_name from pyatmo.modules.device_types import ( DEVICE_CATEGORY_MAP, ApplianceType, DeviceCategory, DeviceType, ) if TYPE_CHECKING: from pyatmo.event import Event from pyatmo.home import Home LOG = logging.getLogger(__name__) ModuleT = dict[str, Any] # Hide from features list ATTRIBUTE_FILTER = { "battery_state", "battery_level", "battery_percent", "date_min_temp", "date_max_temp", "name", "entity_id", "device_id", "modules", "firmware_revision", "firmware_name", "home", "bridge", "room_id", "device_category", "device_type", "features", "history_features", "history_features_values", "appliance_type", } def process_battery_state(data: str) -> int: """Process battery data and return percent (int) for display.""" mapping = { "max": 100, "full": 90, "high": 75, "medium": 50, "low": 25, "very_low": 10, } return mapping[data] class FirmwareMixin(EntityBase): """Mixin for firmware data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize firmware mixin.""" super().__init__(home, module) self.firmware_revision: int | None = None self.firmware_name: str | None = None class WifiMixin(EntityBase): """Mixin for wifi data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize wifi mixin.""" super().__init__(home, module) self.wifi_strength: int | None = None class RfMixin(EntityBase): """Mixin for rf data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize rf mixin.""" super().__init__(home, module) self.rf_strength: int | None = None class RainMixin(EntityBase): """Mixin for rain data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize rain mixin.""" super().__init__(home, module) self.rain: float | None = None self.sum_rain_1: float | None = None self.sum_rain_24: float | None = None class WindMixin(EntityBase): """Mixin for wind data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize wind mixin.""" super().__init__(home, module) self.wind_strength: int | None = None self.wind_angle: int | None = None self.gust_strength: int | None = None self.gust_angle: int | None = None @property def wind_direction(self) -> str | None: """Return wind direction.""" return None if self.wind_angle is None else process_angle(self.wind_angle) @property def gust_direction(self) -> str | None: """Return gust direction.""" return None if self.gust_angle is None else process_angle(self.gust_angle) def process_angle(angle: int) -> str: """Process angle and return string for display.""" angle_mapping = { (0, 30): "N", (30, 60): "NE", (60, 120): "E", (120, 150): "SE", (150, 210): "S", (210, 240): "SW", (240, 300): "W", (300, 330): "NW", (330, 360): "N", } for (lower, upper), direction in angle_mapping.items(): if lower <= angle < upper: return direction return "N" # Default case class TemperatureMixin(EntityBase): """Mixin for temperature data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize temperature mixin.""" super().__init__(home, module) self.temperature: float | None = None self.temp_min: float | None = None self.temp_max: float | None = None self.temp_trend: str | None = None self.min_temp: float | None = None self.max_temp: float | None = None self.date_min_temp: int | None = None self.date_max_temp: int | None = None class HumidityMixin(EntityBase): """Mixin for humidity data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize humidity mixin.""" super().__init__(home, module) self.humidity: int | None = None class CO2Mixin(EntityBase): """Mixin for CO2 data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize CO2 mixin.""" super().__init__(home, module) self.co2: int | None = None class HealthIndexMixin(EntityBase): """Mixin for health index data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize health index mixin.""" super().__init__(home, module) self.health_idx: int | None = None class NoiseMixin(EntityBase): """Mixin for noise data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize noise mixin.""" super().__init__(home, module) self.noise: int | None = None class PressureMixin(EntityBase): """Mixin for pressure data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize pressure mixin.""" super().__init__(home, module) self.pressure: float | None = None self.absolute_pressure: float | None = None self.pressure_trend: str | None = None class BoilerMixin(EntityBase): """Mixin for boiler data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize boiler mixin.""" super().__init__(home, module) self.boiler_status: bool | None = None self.boiler_valve_comfort_boost: bool | None = None class CoolerMixin(EntityBase): """Mixin for cooler data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize cooler mixin.""" super().__init__(home, module) self.cooler_status: bool | None = None class BatteryMixin(EntityBase): """Mixin for battery data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize battery mixin.""" super().__init__(home, module) self.battery_state: str | None = None self.battery_level: int | None = None self.battery_percent: int | None = None @property def battery(self) -> int: """Return battery percent.""" if self.battery_percent is not None: return self.battery_percent if self.battery_state is None: return 0 return process_battery_state(self.battery_state) class PlaceMixin(EntityBase): """Mixin for place data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize place mixin.""" super().__init__(home, module) self.place: Place | None = None class DimmableMixin(EntityBase): """Mixin for dimmable data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize dimmable mixin.""" super().__init__(home, module) self.brightness: int | None = None async def async_set_brightness(self, brightness: int) -> bool: """Set brightness.""" json_brightness = { "modules": [ { "id": self.entity_id, "brightness": max(min(100, brightness), -1), "bridge": self.bridge, }, ], } return await self.home.async_set_state(json_brightness) class ApplianceTypeMixin(EntityBase): """Mixin for appliance type data.""" device_category: DeviceCategory | None appliance_type: ApplianceType | None def __init__(self, home: Home, module: ModuleT) -> None: """Initialize appliance type mixin.""" super().__init__(home, module) self.appliance_type: ApplianceType | None = module.get( "appliance_type", ApplianceType.unknown, ) class PowerMixin(EntityBase): """Mixin for power data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize power mixin.""" super().__init__(home, module) self.power: int | None = None self.history_features.add("power") class EventMixin(EntityBase): """Mixin for event data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize event mixin.""" super().__init__(home, module) self.events: list[Event] = [] class ContactorMixin(EntityBase): """Mixin for contactor data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize contactor mixin.""" super().__init__(home, module) self.contactor_mode: str | None = None class OffloadMixin(EntityBase): """Mixin for offload data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize offload mixin.""" super().__init__(home, module) self.offload: bool | None = None class SwitchMixin(EntityBase): """Mixin for switch data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize switch mixin.""" super().__init__(home, module) self.on: bool | None = None async def async_set_switch(self, target_position: bool) -> bool: """Set switch to target position.""" json_switch = { "modules": [ { "id": self.entity_id, "on": target_position, "bridge": self.bridge, }, ], } return await self.home.async_set_state(json_switch) async def async_on(self) -> bool: """Switch on.""" return await self.async_set_switch(True) async def async_off(self) -> bool: """Switch off.""" return await self.async_set_switch(False) class FanSpeedMixin(EntityBase): """Mixin for fan speed data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize fan speed mixin.""" super().__init__(home, module) self.fan_speed: int | None = None async def async_set_fan_speed(self, speed: int) -> bool: """Set fan speed.""" json_fan_speed = { "modules": [ { "id": self.entity_id, # fan speed is clamped between 1 and 2 # since only NLLF is such a device # and it can only supports fan_speed 1 or 2 "fan_speed": max(min(2, speed), 1), "bridge": self.bridge, }, ], } return await self.home.async_set_state(json_fan_speed) class ShutterMixin(EntityBase): """Mixin for shutter data.""" __open_position = 100 __close_position = 0 __stop_position = -1 __preferred_position = -2 def __init__(self, home: Home, module: ModuleT) -> None: """Initialize shutter mixin.""" super().__init__(home, module) self.current_position: int | None = None self.target_position: int | None = None self.target_position__step: int | None = None async def async_set_target_position(self, target_position: int) -> bool: """Set shutter to target position.""" # in case of a too low value, we default to stop and not the preferred position # We check against __preferred_position that is the lower known value if target_position < self.__preferred_position: target_position = self.__stop_position json_roller_shutter = { "modules": [ { "id": self.entity_id, "target_position": min(self.__open_position, target_position), "bridge": self.bridge, }, ], } return await self.home.async_set_state(json_roller_shutter) async def async_open(self) -> bool: """Open shutter.""" return await self.async_set_target_position(self.__open_position) async def async_close(self) -> bool: """Close shutter.""" return await self.async_set_target_position(self.__close_position) async def async_stop(self) -> bool: """Stop shutter.""" return await self.async_set_target_position(self.__stop_position) async def async_move_to_preferred_position(self) -> bool: """Move shutter to preferred position.""" return await self.async_set_target_position(self.__preferred_position) class CameraMixin(EntityBase): """Mixin for camera data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize camera mixin.""" super().__init__(home, module) self.sd_status: int | None = None self.vpn_url: str | None = None self.local_url: str | None = None self.is_local: bool | None = None self.alim_status: int | None = None self.device_type: DeviceType async def async_get_live_snapshot(self) -> bytes | None: """Fetch live camera image.""" if not self.local_url and not self.vpn_url: return None resp = await self.home.auth.async_get_image( base_url=f"{self.local_url or self.vpn_url}", endpoint="/live/snapshot_720.jpg", ) return resp if isinstance(resp, bytes) else None async def async_update_camera_urls(self) -> None: """Update and validate the camera urls.""" if self.device_type == "NDB": self.is_local = None if self.vpn_url and self.is_local: temp_local_url = await self._async_check_url(self.vpn_url) if temp_local_url: try: self.local_url = await self._async_check_url( temp_local_url, ) except (TimeoutError, ClientConnectorError) as exc: LOG.debug("Cannot connect to %s - reason: %s", temp_local_url, exc) self.is_local = False self.local_url = None async def _async_check_url(self, url: str) -> str | None: """Validate camera url.""" try: resp = await self.home.auth.async_post_api_request( base_url=f"{url}", endpoint="/command/ping", ) except ApiError: LOG.debug("Api error for camera url %s", url) return None if isinstance(resp, bytes): msg = "Invalid response from camera url" raise ApiError(msg) resp_data = await resp.json() return resp_data.get("local_url") if resp_data else None class FloodlightMixin(EntityBase): """Mixin for floodlight data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize floodlight mixin.""" super().__init__(home, module) self.floodlight: str | None = None async def async_set_floodlight_state(self, state: str) -> bool: """Set floodlight state.""" json_floodlight_state = { "modules": [ { "id": self.entity_id, "floodlight": state, }, ], } return await self.home.async_set_state(json_floodlight_state) async def async_floodlight_on(self) -> bool: """Turn on floodlight.""" return await self.async_set_floodlight_state("on") async def async_floodlight_off(self) -> bool: """Turn off floodlight.""" return await self.async_set_floodlight_state("off") async def async_floodlight_auto(self) -> bool: """Set floodlight to auto mode.""" return await self.async_set_floodlight_state("auto") class StatusMixin(EntityBase): """Mixin for status data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize status mixin.""" super().__init__(home, module) self.status: str | None = None class MonitoringMixin(EntityBase): """Mixin for monitoring data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize monitoring mixin.""" super().__init__(home, module) self.monitoring: bool | None = None async def async_set_monitoring_state(self, state: str) -> bool: """Set monitoring state.""" json_monitoring_state = { "modules": [ { "id": self.entity_id, "monitoring": state, }, ], } return await self.home.async_set_state(json_monitoring_state) async def async_monitoring_on(self) -> bool: """Turn on monitoring.""" return await self.async_set_monitoring_state("on") async def async_monitoring_off(self) -> bool: """Turn off monitoring.""" return await self.async_set_monitoring_state("off") class MeasureInterval(Enum): """Measure interval.""" HALF_HOUR = "30min" HOUR = "1hour" THREE_HOURS = "3hours" DAY = "1day" WEEK = "1week" MONTH = "1month" class MeasureType(Enum): """Measure type.""" BOILERON = "boileron" BOILEROFF = "boileroff" SUM_BOILER_ON = "sum_boiler_on" SUM_BOILER_OFF = "sum_boiler_off" SUM_ENERGY_ELEC = "sum_energy_buy_from_grid" SUM_ENERGY_ELEC_BASIC = "sum_energy_buy_from_grid$0" SUM_ENERGY_ELEC_PEAK = "sum_energy_buy_from_grid$1" SUM_ENERGY_ELEC_OFF_PEAK = "sum_energy_buy_from_grid$2" SUM_ENERGY_PRICE = "sum_energy_buy_from_grid_price" SUM_ENERGY_PRICE_BASIC = "sum_energy_buy_from_grid_price$0" SUM_ENERGY_PRICE_PEAK = "sum_energy_buy_from_grid_price$1" SUM_ENERGY_PRICE_OFF_PEAK = "sum_energy_buy_from_grid_price$2" SUM_ENERGY_ELEC_LEGACY = "sum_energy_elec" SUM_ENERGY_ELEC_BASIC_LEGACY = "sum_energy_elec$0" SUM_ENERGY_ELEC_PEAK_LEGACY = "sum_energy_elec$1" SUM_ENERGY_ELEC_OFF_PEAK_LEGACY = "sum_energy_elec$2" MEASURE_INTERVAL_TO_SECONDS = { MeasureInterval.HALF_HOUR: 1800, MeasureInterval.HOUR: 3600, MeasureInterval.THREE_HOURS: 10800, MeasureInterval.DAY: 86400, MeasureInterval.WEEK: 604800, MeasureInterval.MONTH: 2592000, } ENERGY_FILTERS = f"{MeasureType.SUM_ENERGY_ELEC.value},{MeasureType.SUM_ENERGY_ELEC_BASIC.value},{MeasureType.SUM_ENERGY_ELEC_PEAK.value},{MeasureType.SUM_ENERGY_ELEC_OFF_PEAK.value}" ENERGY_FILTERS_LEGACY = f"{MeasureType.SUM_ENERGY_ELEC_LEGACY.value},{MeasureType.SUM_ENERGY_ELEC_BASIC_LEGACY.value},{MeasureType.SUM_ENERGY_ELEC_PEAK_LEGACY.value},{MeasureType.SUM_ENERGY_ELEC_OFF_PEAK_LEGACY.value}" ENERGY_FILTERS_MODES = ["generic", "basic", "peak", "off_peak"] def compute_riemann_sum( power_data: list[tuple[int, float]], conservative: bool = False, ) -> float: """Compute energy from power with a rieman sum.""" delta_energy = 0.0 if power_data and len(power_data) > 1: # compute a rieman sum, as best as possible , trapezoidal, taking pessimistic asumption # as we don't want to artifically go up the previous one # (except in rare exceptions like reset, 0 , etc) for i in range(len(power_data) - 1): dt_h = float(power_data[i + 1][0] - power_data[i][0]) / 3600.0 if conservative: d_p_w = 0.0 else: d_p_w = abs(float(power_data[i + 1][1] - power_data[i][1])) d_nrj_wh = dt_h * ( min(power_data[i + 1][1], power_data[i][1]) + 0.5 * d_p_w ) delta_energy += d_nrj_wh return delta_energy class EnergyHistoryMixin(EntityBase): """Mixin for Energy history data.""" def __init__(self, home: Home, module: ModuleT) -> None: """Initialize history mixin.""" super().__init__(home, module) self.historical_data: list[dict[str, Any]] | None = None self.start_time: float | None = None self.end_time: float | None = None self.interval: MeasureInterval | None = None self.sum_energy_elec: float = 0.0 self.sum_energy_elec_peak: float = 0.0 self.sum_energy_elec_off_peak: float = 0.0 self._anchor_for_power_adjustment: float | None = None self.in_reset: bool = False def reset_measures( self, start_power_time: datetime | None, in_reset: bool = True, ) -> None: """Reset energy measures.""" self.in_reset = in_reset self.historical_data = [] self.sum_energy_elec = 0.0 self.sum_energy_elec_peak = 0.0 self.sum_energy_elec_off_peak = 0.0 if start_power_time is None: self._anchor_for_power_adjustment = start_power_time else: self._anchor_for_power_adjustment = int(start_power_time.timestamp()) def get_sum_energy_elec_power_adapted( self, to_ts: float | None = None, conservative: bool = False, ) -> tuple[float, float]: """Compute proper energy value with adaptation from power.""" v = self.sum_energy_elec delta_energy = 0.0 if not self.in_reset: if to_ts is None: to_ts = int(time()) from_ts = self._anchor_for_power_adjustment if ( from_ts is not None and from_ts < to_ts and isinstance(self, PowerMixin) and isinstance(self, NetatmoBase) ): power_data = self.get_history_data( "power", from_ts=from_ts, to_ts=to_ts, ) if isinstance( self, EnergyHistoryMixin, ): # well to please the linter.... delta_energy = compute_riemann_sum(power_data, conservative) return v, delta_energy def _log_energy_error( self, start_time: float, end_time: float, msg: str | None = None, body: dict | None = None, ) -> None: LOG.debug( "ENERGY collection error %s %s %s %s %s %s %s", msg, self.name, datetime.fromtimestamp(start_time), datetime.fromtimestamp(end_time), start_time, end_time, body or "NO BODY", ) async def async_update_measures( self, start_time: int | None = None, end_time: int | None = None, interval: MeasureInterval = MeasureInterval.HOUR, days: int = 7, ) -> None: """Update historical data.""" if end_time is None: end_time = int(datetime.now().timestamp()) if start_time is None: end = datetime.fromtimestamp(end_time) start_time = int((end - timedelta(days=days)).timestamp()) prev_start_time = self.start_time prev_end_time = self.end_time self.start_time = start_time self.end_time = end_time # the legrand/netatmo handling of start and endtime is very peculiar # for 30mn/1h/3h intervals : in fact the starts is asked_start + intervals/2 ! # => so shift of 15mn, 30mn and 1h30 # for 1day : start is ALWAYS 12am (half day) of the first day of the range # for 1week : it will be half week ALWAYS, ie on a thursday at 12am (half day) # in fact in the case for all intervals the reported dates are "the middle" of the ranges delta_range = MEASURE_INTERVAL_TO_SECONDS.get(interval, 0) // 2 filters, raw_data = await self._energy_api_calls(start_time, end_time, interval) hist_good_vals = await self._get_aligned_energy_values_and_mode( start_time, end_time, delta_range, raw_data, ) prev_sum_energy_elec = self.sum_energy_elec self.sum_energy_elec = 0.0 self.sum_energy_elec_peak = 0.0 self.sum_energy_elec_off_peak = 0.0 # no data at all: we know nothing for the end: best guess, it is the start self._anchor_for_power_adjustment = start_time self.in_reset = False if len(hist_good_vals) == 0: # nothing has been updated or changed it can nearly be seen as an error, but the api is answering correctly # so we probably have to reset to 0 anyway as it means there were no exisitng # historical data for this time range LOG.debug( "NO VALUES energy update %s from: %s to %s, prev_sum=%s", self.name, datetime.fromtimestamp(start_time), datetime.fromtimestamp(end_time), prev_sum_energy_elec if prev_sum_energy_elec is not None else "NOTHING", ) else: await self._prepare_exported_historical_data( start_time, end_time, delta_range, hist_good_vals, prev_end_time or 0.0, prev_start_time or 0.0, prev_sum_energy_elec or 0.0, ) async def _prepare_exported_historical_data( self, start_time: float, end_time: float, delta_range: float, hist_good_vals: list[tuple[int, float, list[float]]], prev_end_time: float, prev_start_time: float, prev_sum_energy_elec: float | None, ) -> None: self.historical_data = [] computed_start = 0.0 computed_end = 0.0 computed_end_for_calculus = 0.0 for cur_start_time, val, vals in hist_good_vals: self.sum_energy_elec += val modes = [] val_modes = [] for i, v in enumerate(vals): if v is not None: modes.append(ENERGY_FILTERS_MODES[i]) val_modes.append(v) if ENERGY_FILTERS_MODES[i] == "off_peak": self.sum_energy_elec_off_peak += v elif ENERGY_FILTERS_MODES[i] == "peak": self.sum_energy_elec_peak += v c_start = cur_start_time c_end = cur_start_time + 2 * delta_range if computed_start == 0: computed_start = c_start computed_end = c_end computed_end_for_calculus = c_end start_time_string = f"{datetime.fromtimestamp(c_start + 1, tz=UTC).isoformat().split('+')[0]}Z" end_time_string = ( f"{datetime.fromtimestamp(c_end, tz=UTC).isoformat().split('+')[0]}Z" ) self.historical_data.append( { "duration": (2 * delta_range) // 60, "startTime": start_time_string, "endTime": end_time_string, "Wh": val, "energyMode": modes, "WhPerModes": val_modes, "startTimeUnix": c_start, "endTimeUnix": c_end, }, ) if ( prev_sum_energy_elec is not None and prev_sum_energy_elec > self.sum_energy_elec ): msg = ( "ENERGY GOING DOWN %s from: %s to %s " "computed_start: %s, computed_end: %s, " "sum=%f prev_sum=%f prev_start: %s, prev_end %s" ) LOG.debug( msg, self.name, datetime.fromtimestamp(start_time), datetime.fromtimestamp(end_time), datetime.fromtimestamp(computed_start), datetime.fromtimestamp(computed_end), self.sum_energy_elec, prev_sum_energy_elec, datetime.fromtimestamp(prev_start_time), datetime.fromtimestamp(prev_end_time), ) else: msg = ( "Success in energy update %s from: %s to %s " "computed_start: %s, computed_end: %s , sum=%s prev_sum=%s" ) LOG.debug( msg, self.name, datetime.fromtimestamp(start_time), datetime.fromtimestamp(end_time), datetime.fromtimestamp(computed_start), datetime.fromtimestamp(computed_end), self.sum_energy_elec, prev_sum_energy_elec if prev_sum_energy_elec is not None else "NOTHING", ) self._anchor_for_power_adjustment = computed_end_for_calculus async def _get_aligned_energy_values_and_mode( self, start_time: float, end_time: float, delta_range: float, raw_data: dict, ) -> list[Any]: hist_good_vals = [] values_lots = raw_data for values_lot in values_lots: try: start_lot_time = int(values_lot["beg_time"]) except KeyError: self._log_energy_error( start_time, end_time, msg="beg_time missing", body=values_lots, ) msg = ( f"Energy badly formed resp beg_time missing: {values_lots} - " f"module: {self.name}" ) raise ApiError( msg, ) from None interval_sec = values_lot.get("step_time") if interval_sec is None: if len(values_lot.get("value", [])) > 1: self._log_energy_error( start_time, end_time, msg="step_time missing", body=values_lots, ) interval_sec = 2 * delta_range else: interval_sec = int(interval_sec) # align the start on the begining of the segment cur_start_time = start_lot_time - interval_sec // 2 for val_arr in values_lot.get("value", []): vals = [] val = 0 for v in val_arr: if v is not None: v = int(v) val += v vals.append(v) else: vals.append(None) hist_good_vals.append((cur_start_time, val, vals)) cur_start_time = cur_start_time + interval_sec return sorted(hist_good_vals, key=itemgetter(0)) def _get_energy_filers(self) -> str: return ENERGY_FILTERS async def _energy_api_calls( self, start_time: float, end_time: float, interval: MeasureInterval, ) -> tuple[LiteralString, Any]: filters = self._get_energy_filers() params = { "device_id": self.bridge, "module_id": self.entity_id, "scale": interval.value, "type": filters, "date_begin": start_time, "date_end": end_time, } resp = await self.home.auth.async_post_api_request( endpoint=GETMEASURE_ENDPOINT, params=params, ) rw_dt_f = await resp.json() rw_dt = rw_dt_f.get("body") if rw_dt is None: self._log_energy_error( start_time, end_time, msg=f"direct from {filters}", body=rw_dt_f, ) msg = ( f"Energy badly formed resp: {rw_dt_f} - " f"module: {self.name} - " f"when accessing '{filters}'" ) raise ApiError(msg) raw_data = rw_dt return filters, raw_data class EnergyHistoryLegacyMixin(EnergyHistoryMixin): """Mixin for Energy history data, Using legacy APis (used for NLE).""" def _get_energy_filers(self) -> str: return ENERGY_FILTERS_LEGACY class Module(NetatmoBase): """Class to represent a Netatmo module.""" device_type: DeviceType device_category: DeviceCategory | None room_id: str | None modules: list[str] | None reachable: bool | None features: set[str] def __init__(self, home: Home, module: ModuleT) -> None: """Initialize a Netatmo module instance.""" super().__init__(module) self.device_type = DeviceType(module["type"]) self.home = home self.room_id = module.get("room_id") self.reachable = module.get("reachable") self.bridge = module.get("bridge") self.modules = module.get("modules_bridged") self.device_category = DEVICE_CATEGORY_MAP.get(self.device_type) self.features = set() async def update(self, raw_data: RawData) -> None: """Update module with the latest data.""" self.update_topology(raw_data) if ( self.bridge and self.bridge in self.home.modules and hasattr(self, "device_category") and self.device_category == "weather" ): self.name = update_name(self.name, self.home.modules[self.bridge].name) self.update_features() # If we have an NLE as a bridge all its bridged modules will have to be reachable if self.device_type == DeviceType.NLE: # if there is a bridge it means it is a leaf if self.bridge: self.reachable = True elif self.modules: # this NLE is a bridge itself : make it not available self.reachable = False if not self.reachable and self.modules: # Update bridged modules and associated rooms for module_id in self.modules: module = self.home.modules[module_id] await module.update(raw_data) if module.room_id: self.home.rooms[module.room_id].update(raw_data) def update_features(self) -> None: """Update features.""" self.features.update({var for var in vars(self) if var not in ATTRIBUTE_FILTER}) if "battery_state" in vars(self) or "battery_percent" in vars(self): self.features.add("battery") if "wind_angle" in self.features: self.features.add("wind_direction") self.features.add("gust_direction") class Camera( FirmwareMixin, MonitoringMixin, EventMixin, CameraMixin, WifiMixin, Module, ): """Class to represent a Netatmo camera.""" async def update(self, raw_data: RawData) -> None: """Update camera with the latest data.""" await Module.update(self, raw_data) await self.async_update_camera_urls() class Switch( FirmwareMixin, EnergyHistoryMixin, PowerMixin, SwitchMixin, ApplianceTypeMixin, Module, ): """Class to represent a Netatmo switch.""" class Dimmer(DimmableMixin, Switch): """Class to represent a Netatmo dimmer.""" class Shutter(FirmwareMixin, ShutterMixin, Module): """Class to represent a Netatmo shutter.""" class Fan(FirmwareMixin, FanSpeedMixin, PowerMixin, Module): """Class to represent a Netatmo ventilation device.""" class RemoteControlMixin(FirmwareMixin, Module): """Class to represent a Netatmo remote control.""" class Energy(EnergyHistoryMixin, Module): """Class to represent a Netatmo energy module.""" class Boiler(BoilerMixin, Module): """Class to represent a Netatmo boiler.""" pyatmo-9.2.1/src/pyatmo/modules/netatmo.py000066400000000000000000000163661501740523400206420ustar00rootroot00000000000000"""Module to represent Netatmo modules.""" from __future__ import annotations from dataclasses import dataclass import logging from typing import Any from pyatmo.const import ( ACCESSORY_GUST_ANGLE_TYPE, ACCESSORY_GUST_STRENGTH_TYPE, ACCESSORY_RAIN_24H_TYPE, ACCESSORY_RAIN_60MIN_TYPE, ACCESSORY_RAIN_LIVE_TYPE, ACCESSORY_WIND_ANGLE_TYPE, ACCESSORY_WIND_STRENGTH_TYPE, STATION_HUMIDITY_TYPE, STATION_PRESSURE_TYPE, STATION_TEMPERATURE_TYPE, RawData, ) from pyatmo.modules.module import ( BatteryMixin, BoilerMixin, Camera, CO2Mixin, FirmwareMixin, FloodlightMixin, HealthIndexMixin, HumidityMixin, Module, MonitoringMixin, NoiseMixin, PlaceMixin, PressureMixin, RainMixin, RfMixin, StatusMixin, TemperatureMixin, WifiMixin, WindMixin, ) LOG = logging.getLogger(__name__) class NRV(FirmwareMixin, RfMixin, BatteryMixin, Module): """Class to represent a Netatmo NRV.""" class NAC(FirmwareMixin, RfMixin, BatteryMixin, Module): """Class to represent a Netatmo NAC.""" class NATherm1(FirmwareMixin, RfMixin, BatteryMixin, BoilerMixin, Module): """Class to represent a Netatmo NATherm1.""" class NAPlug(FirmwareMixin, RfMixin, WifiMixin, Module): """Class to represent a Netatmo NAPlug.""" class OTH(FirmwareMixin, WifiMixin, Module): """Class to represent a Netatmo OTH.""" class OTM(FirmwareMixin, RfMixin, BatteryMixin, BoilerMixin, Module): """Class to represent a Netatmo OTM.""" class NACamera(Camera): """Class to represent a Netatmo NACamera.""" class NPC(Camera): """Class to represent a Netatmo NPC.""" class NOC(FloodlightMixin, Camera): """Class to represent a Netatmo NOC.""" class NDB(Camera): """Class to represent a Netatmo NDB.""" class NAMain( TemperatureMixin, HumidityMixin, CO2Mixin, NoiseMixin, PressureMixin, WifiMixin, FirmwareMixin, PlaceMixin, Module, ): """Class to represent a Netatmo NAMain.""" class NAModule1( TemperatureMixin, HumidityMixin, RfMixin, FirmwareMixin, BatteryMixin, PlaceMixin, Module, ): """Class to represent a Netatmo NAModule1.""" class NAModule2(WindMixin, RfMixin, FirmwareMixin, BatteryMixin, PlaceMixin, Module): """Class to represent a Netatmo NAModule2.""" class NAModule3(RainMixin, RfMixin, FirmwareMixin, BatteryMixin, PlaceMixin, Module): """Class to represent a Netatmo NAModule3.""" class NAModule4( TemperatureMixin, CO2Mixin, HumidityMixin, RfMixin, FirmwareMixin, BatteryMixin, PlaceMixin, Module, ): """Class to represent a Netatmo NAModule4.""" class NHC( TemperatureMixin, HumidityMixin, CO2Mixin, PressureMixin, NoiseMixin, HealthIndexMixin, WifiMixin, FirmwareMixin, PlaceMixin, Module, ): """Class to represent a Netatmo NHC.""" class NACamDoorTag(StatusMixin, FirmwareMixin, BatteryMixin, RfMixin, Module): """Class to represent a Netatmo NACamDoorTag.""" class NIS( StatusMixin, MonitoringMixin, FirmwareMixin, BatteryMixin, RfMixin, Module, ): """Class to represent a Netatmo NIS.""" class NSD( FirmwareMixin, Module, ): """Class to represent a Netatmo NSD.""" class NCO( FirmwareMixin, Module, ): """Class to represent a Netatmo NCO.""" @dataclass class Location: """Class of Netatmo public weather location.""" lat_ne: str lon_ne: str lat_sw: str lon_sw: str class PublicWeatherArea: """Class of Netatmo public weather data.""" location: Location required_data_type: str | None filtering: bool modules: list[dict[str, Any]] def __init__( self, lat_ne: str, lon_ne: str, lat_sw: str, lon_sw: str, required_data_type: str | None = None, filtering: bool = False, ) -> None: """Initialize self.""" self.location = Location( lat_ne, lon_ne, lat_sw, lon_sw, ) self.modules = [] self.required_data_type = required_data_type self.filtering = filtering def update(self, raw_data: RawData) -> None: """Update public weather area with the latest data.""" self.modules = list(raw_data.get("public", [])) def stations_in_area(self) -> int: """Return available number of stations in area.""" return len(self.modules) def get_latest_rain(self) -> dict[str, Any]: """Return latest rain measures.""" return self.get_accessory_data(ACCESSORY_RAIN_LIVE_TYPE) def get_60_min_rain(self) -> dict[str, Any]: """Return 60 min rain measures.""" return self.get_accessory_data(ACCESSORY_RAIN_60MIN_TYPE) def get_24_h_rain(self) -> dict[str, Any]: """Return 24 h rain measures.""" return self.get_accessory_data(ACCESSORY_RAIN_24H_TYPE) def get_latest_pressures(self) -> dict[str, Any]: """Return latest pressure measures.""" return self.get_latest_station_measures(STATION_PRESSURE_TYPE) def get_latest_temperatures(self) -> dict[str, Any]: """Return latest temperature measures.""" return self.get_latest_station_measures(STATION_TEMPERATURE_TYPE) def get_latest_humidities(self) -> dict[str, Any]: """Return latest humidity measures.""" return self.get_latest_station_measures(STATION_HUMIDITY_TYPE) def get_latest_wind_strengths(self) -> dict[str, Any]: """Return latest wind strength measures.""" return self.get_accessory_data(ACCESSORY_WIND_STRENGTH_TYPE) def get_latest_wind_angles(self) -> dict[str, Any]: """Return latest wind angle measures.""" return self.get_accessory_data(ACCESSORY_WIND_ANGLE_TYPE) def get_latest_gust_strengths(self) -> dict[str, Any]: """Return latest gust strength measures.""" return self.get_accessory_data(ACCESSORY_GUST_STRENGTH_TYPE) def get_latest_gust_angles(self) -> dict[str, Any]: """Return latest gust angle measures.""" return self.get_accessory_data(ACCESSORY_GUST_ANGLE_TYPE) def get_latest_station_measures(self, data_type: str) -> dict[str, Any]: """Return latest station measures of a given type.""" measures: dict[str, Any] = {} for station in self.modules: for module in station["measures"].values(): if ( "type" in module and data_type in module["type"] and "res" in module and module["res"] ): measure_index = module["type"].index(data_type) latest_timestamp = sorted(module["res"], reverse=True)[0] measures[station["_id"]] = module["res"][latest_timestamp][ measure_index ] return measures def get_accessory_data(self, data_type: str) -> dict[str, Any]: """Return accessory data of a given type.""" data: dict[str, Any] = {} for station in self.modules: for module in station["measures"].values(): if data_type in module: data[station["_id"]] = module[data_type] return data pyatmo-9.2.1/src/pyatmo/modules/smarther.py000066400000000000000000000005421501740523400210050ustar00rootroot00000000000000"""Module to represent Smarther modules.""" from __future__ import annotations import logging from pyatmo.modules.module import ( BoilerMixin, CoolerMixin, FirmwareMixin, Module, WifiMixin, ) LOG = logging.getLogger(__name__) class BNS(FirmwareMixin, BoilerMixin, CoolerMixin, WifiMixin, Module): """Smarther thermostat.""" pyatmo-9.2.1/src/pyatmo/modules/somfy.py000066400000000000000000000004011501740523400203070ustar00rootroot00000000000000"""Module to represent somfy modules.""" from __future__ import annotations import logging from pyatmo.modules.module import RfMixin, Shutter LOG = logging.getLogger(__name__) class TPSRS(RfMixin, Shutter): """Class to represent a somfy TPSRS.""" pyatmo-9.2.1/src/pyatmo/person.py000066400000000000000000000017331501740523400170210ustar00rootroot00000000000000"""Module to represent a Netatmo person.""" from __future__ import annotations from dataclasses import dataclass import logging from typing import TYPE_CHECKING from pyatmo.modules.base_class import NetatmoBase if TYPE_CHECKING: from pyatmo.const import RawData from .home import Home LOG = logging.getLogger(__name__) @dataclass class Person(NetatmoBase): """Class to represent a Netatmo person.""" pseudo: str | None url: str | None out_of_sight: bool | None = None last_seen: int | None = None def __init__(self, home: Home, raw_data: RawData) -> None: """Initialize a Netatmo person instance.""" super().__init__(raw_data) self.home = home self.pseudo = raw_data.get("pseudo") self.url = raw_data.get("url") def update(self, raw_data: RawData) -> None: """Update person data.""" self.out_of_sight = raw_data.get("out_of_sight") self.last_seen = raw_data.get("last_seen") pyatmo-9.2.1/src/pyatmo/py.typed000066400000000000000000000000001501740523400166220ustar00rootroot00000000000000pyatmo-9.2.1/src/pyatmo/room.py000066400000000000000000000332141501740523400164660ustar00rootroot00000000000000"""Module to represent a Netatmo room.""" from __future__ import annotations from dataclasses import dataclass import logging from typing import TYPE_CHECKING, Any, cast from pyatmo.const import ( AWAY, COOLING, FROSTGUARD, HEATING, HOME, IDLE, MANUAL, MAX, OFF, PILOT_WIRE_AWAY, PILOT_WIRE_COMFORT, PILOT_WIRE_COMFORT_1, PILOT_WIRE_COMFORT_2, PILOT_WIRE_FROST_GUARD, PILOT_WIRE_STAND_BY, SCHEDULE, SETROOMTHERMPOINT_ENDPOINT, UNKNOWN, RawData, ) from pyatmo.enums import TemperatureControlMode from pyatmo.modules.base_class import NetatmoBase from pyatmo.modules.device_types import ApplianceType, DeviceCategory, DeviceType from pyatmo.modules.module import ApplianceTypeMixin, Boiler, PowerMixin if TYPE_CHECKING: from pyatmo.home import Home from pyatmo.modules.module import Module LOG = logging.getLogger(__name__) MODE_MAP = {SCHEDULE: HOME} # as for now all the below is not exposed at all through the API, don't put it in the public API, so not in const.py NETAMO_CLIMATE_SETPOINT_MODE_TO_PILOT_WIRE = { MANUAL: PILOT_WIRE_COMFORT, MAX: PILOT_WIRE_COMFORT, OFF: PILOT_WIRE_FROST_GUARD, HOME: PILOT_WIRE_COMFORT, # HOME is equivalent to a schedule for Netatmo NLC based room FROSTGUARD: PILOT_WIRE_FROST_GUARD, SCHEDULE: PILOT_WIRE_COMFORT, AWAY: PILOT_WIRE_AWAY, } # invert of the map above: NETAMO_PILOT_WIRE_TO_CLIMATE_SETPOINT_MODE = { PILOT_WIRE_COMFORT: MANUAL, PILOT_WIRE_AWAY: MANUAL, # AWAY is like ECO for a pilot wire heater, so put manual to force it to happen PILOT_WIRE_FROST_GUARD: FROSTGUARD, PILOT_WIRE_STAND_BY: FROSTGUARD, PILOT_WIRE_COMFORT_1: HOME, PILOT_WIRE_COMFORT_2: HOME, } @dataclass class Room(NetatmoBase): """Class to represent a Netatmo room.""" modules: dict[str, Module] device_types: set[DeviceType] features: set[str] climate_type: DeviceType | None = None humidity: int | None = None therm_measured_temperature: float | None = None reachable: bool | None = None heating_power_request: int | None = None therm_setpoint_temperature: float | None = None therm_setpoint_mode: str | None = None # therm_setpoint_mode: per the documentation: "The thermostat mode in which the room is. # For a room controlled by a BNS, mode can be home, manual, max or hg/off (if heating/cooling). # For a room controlled by a NLC, mode can be off, manual or hg." # values can be # "manual" # "max" # "off" # "home" # "hg" # "schedule" # "away" # therm_setpoint_fp: used to set up pilot wire, ie "fil pilote" set point # netatmo documentation: # Usually used to control (Fil pilote (FP)) setpoint # values: # "comfort" # "away" # "frost_guard" # "stand_by" # "comfort_1" => documentation unclear and contradictory here, as it is in the json schema but no in the doc # "comfort_2" => same # but here: therm_setpoint_fp: str | None = None support_pilot_wire: bool = False therm_setpoint_start_time: int | None = None therm_setpoint_end_time: int | None = None anticipating: bool | None = None open_window: bool | None = None cooling_setpoint_temperature: float | None = None cooling_setpoint_start_time: int | None = None cooling_setpoint_end_time: int | None = None cooling_setpoint_mode: str | None = None radiators_power: int | None = None def __init__( self, home: Home, room: dict[str, Any], all_modules: dict[str, Module], ) -> None: """Initialize a Netatmo room instance.""" super().__init__(room) self.home = home self.support_pilot_wire = False self.modules = { m_id: m for m_id, m in all_modules.items() if m_id in room.get("module_ids", []) } self.device_types = set() self.features = set() self.evaluate_device_type() def update_topology(self, raw_data: RawData) -> None: """Update room topology.""" self.name = raw_data.get("name", UNKNOWN) self.modules = { m_id: m for m_id, m in self.home.modules.items() if m_id in raw_data.get("module_ids", []) } self.evaluate_device_type() def evaluate_device_type(self) -> None: """Evaluate the device type of the room.""" self.support_pilot_wire = False for module in self.modules.values(): self.device_types.add(module.device_type) if module.device_category is not None: self.features.add(module.device_category.name) if ( module.device_type == "NLC" and isinstance(module, ApplianceTypeMixin) and module.appliance_type == ApplianceType.radiator ): self.support_pilot_wire = True # Regarding to the room the cable outlet can be seen as climate control, add the climate feature self.features.add(DeviceCategory.climate.name) if "OTM" in self.device_types: self.climate_type = DeviceType.OTM elif "NATherm1" in self.device_types: self.climate_type = DeviceType.NATherm1 elif "BNS" in self.device_types: self.climate_type = DeviceType.BNS self.features.add("humidity") elif "NRV" in self.device_types: self.climate_type = DeviceType.NRV elif "NAC" in self.device_types: self.climate_type = DeviceType.NAC elif "BNTH" in self.device_types: self.climate_type = DeviceType.BNTH elif "NLC" in self.device_types and self.support_pilot_wire: self.climate_type = DeviceType.NLC def update(self, raw_data: RawData) -> None: """Update room data.""" self.humidity = raw_data.get("humidity") self.radiators_power = 0 if self.climate_type == DeviceType.BNTH: # BNTH is wired, so the room is always reachable self.reachable = True elif self.climate_type == DeviceType.NLC: self.reachable = raw_data.get("reachable", False) for module in self.modules.values(): if ( isinstance(module, ApplianceTypeMixin) and module.device_type == DeviceType.NLC and module.appliance_type == ApplianceType.radiator ): if isinstance(module, PowerMixin) and module.power is not None: self.radiators_power += module.power if hasattr(module, "reachable"): state = module.reachable if state is not None: if self.reachable is None: self.reachable = state else: self.reachable = ( self.reachable or state ) # as soon as we do have one else: self.reachable = raw_data.get("reachable") self.therm_measured_temperature = raw_data.get("therm_measured_temperature") self.heating_power_request = raw_data.get("heating_power_request") self.therm_setpoint_mode = raw_data.get("therm_setpoint_mode") self.therm_setpoint_fp = raw_data.get("therm_setpoint_fp") self.therm_setpoint_temperature = raw_data.get("therm_setpoint_temperature") self.therm_setpoint_start_time = raw_data.get("therm_setpoint_start_time") self.therm_setpoint_end_time = raw_data.get("therm_setpoint_end_time") self.anticipating = raw_data.get("anticipating") self.open_window = raw_data.get("open_window") self.cooling_setpoint_temperature = raw_data.get("cooling_setpoint_temperature") self.cooling_setpoint_start_time = raw_data.get("cooling_setpoint_start_time") self.cooling_setpoint_end_time = raw_data.get("cooling_setpoint_end_time") self.cooling_setpoint_mode = raw_data.get("cooling_setpoint_mode") async def async_therm_manual( self, temp: float | None = None, end_time: int | None = None, ) -> None: """Set room temperature set point to manual.""" await self.async_therm_set(MANUAL, temp, end_time) async def async_therm_home(self, end_time: int | None = None) -> None: """Set room temperature set point to home.""" await self.async_therm_set(HOME, end_time=end_time) async def async_therm_frostguard(self, end_time: int | None = None) -> None: """Set room temperature set point to frostguard.""" await self.async_therm_set(FROSTGUARD, end_time=end_time) async def async_therm_set( self, mode: str | None = None, temp: float | None = None, end_time: int | None = None, pilot_wire: str | None = None, ) -> None: """Set room temperature set point.""" if mode is None: mode = MANUAL mode = MODE_MAP.get(mode, mode) if "NATherm1" in self.device_types or ( "NRV" in self.device_types and not self.home.has_otm() and not self.home.has_bns() ): await self._async_set_thermpoint(mode, temp, end_time) else: await self._async_therm_set(mode, temp, end_time, pilot_wire) async def _async_therm_set( self, mode: str | None = None, temp: float | None = None, end_time: int | None = None, pilot_wire: str | None = None, ) -> bool: """Set room temperature set point (OTM).""" if pilot_wire is None: # in case both are None stop everything if mode is None: mode = FROSTGUARD pilot_wire = NETAMO_CLIMATE_SETPOINT_MODE_TO_PILOT_WIRE.get( mode, PILOT_WIRE_FROST_GUARD, ) # force back the proper preset mode in case of pilot wire # to comply with netatmo model if self.support_pilot_wire and self.climate_type == DeviceType.NLC: mode = NETAMO_PILOT_WIRE_TO_CLIMATE_SETPOINT_MODE.get( pilot_wire, FROSTGUARD, ) if pilot_wire is not None and mode is None: mode = MANUAL temp_mode_mapping = { None: "therm", TemperatureControlMode.HEATING: "therm", TemperatureControlMode.COOLING: "cooling", } setpoint_mode_prefix = temp_mode_mapping.get( self.home.temperature_control_mode, "therm", ) json_therm_set: dict[str, Any] = { "rooms": [ { "id": self.entity_id, f"{setpoint_mode_prefix}_setpoint_mode": mode, }, ], } if temp: json_therm_set["rooms"][0][ f"{setpoint_mode_prefix}_setpoint_temperature" ] = temp if end_time: json_therm_set["rooms"][0][ f"{setpoint_mode_prefix}_setpoint_end_time" ] = end_time if self.support_pilot_wire and pilot_wire: json_therm_set["rooms"][0]["therm_setpoint_fp"] = pilot_wire return await self.home.async_set_state(json_therm_set) async def _async_set_thermpoint( self, mode: str, temp: float | None = None, end_time: int | None = None, ) -> None: """Set room temperature set point (NRV, NATherm1).""" post_params = { "home_id": self.home.entity_id, "room_id": self.entity_id, "mode": mode, } # Temp and endtime should only be sent when mode=='manual', but netatmo api can # handle that even when mode == 'home' and these settings don't make sense if temp is not None: post_params["temp"] = str(temp) if end_time is not None: post_params["endtime"] = str(end_time) LOG.debug( "Setting room (%s) temperature set point to %s until %s", self.entity_id, temp, end_time, ) await self.home.auth.async_post_api_request( endpoint=SETROOMTHERMPOINT_ENDPOINT, params=post_params, ) @property def boiler_status(self) -> bool | None: """Return the boiler status.""" for module in self.modules.values(): if hasattr(module, "boiler_status"): module = cast("Boiler", module) if (boiler_status := module.boiler_status) is not None: return boiler_status return None @property def setpoint_mode(self) -> str: """Return the current setpoint mode.""" return self.therm_setpoint_mode or self.cooling_setpoint_mode or UNKNOWN @property def setpoint_temperature(self) -> float | None: """Return the current setpoint temperature.""" return ( self.therm_setpoint_temperature or self.cooling_setpoint_temperature or None ) @property def setpoint_fp(self) -> str | None: """Return the current setpoint 'Fil pilote (FP)'.""" return self.therm_setpoint_fp or None @property def hvac_action(self) -> str: """Return the current HVAC action.""" if self.setpoint_mode == OFF: return OFF if self.boiler_status is True: return HEATING if self.heating_power_request is not None and self.heating_power_request > 0: return HEATING if self.cooling_setpoint_temperature: return COOLING return IDLE pyatmo-9.2.1/src/pyatmo/schedule.py000066400000000000000000000061171501740523400173100ustar00rootroot00000000000000"""Module to represent a Netatmo schedule.""" from __future__ import annotations from dataclasses import dataclass import logging from typing import TYPE_CHECKING from pyatmo.enums import ScheduleType from pyatmo.modules.base_class import NetatmoBase from pyatmo.room import Room if TYPE_CHECKING: from pyatmo.const import RawData from .home import Home LOG = logging.getLogger(__name__) @dataclass class Schedule(NetatmoBase): """Class to represent a Netatmo schedule.""" type: ScheduleType away_temp: float | None hg_temp: float | None cooling_away_temp: float | None timetable: list[TimetableEntry] selected: bool default: bool def __init__(self, home: Home, raw_data: RawData) -> None: """Initialize a Netatmo schedule instance.""" super().__init__(raw_data) self.home = home self.type = ScheduleType(raw_data.get("type", ScheduleType.THERM)) self.default = raw_data.get("default", False) self.selected = raw_data.get("selected", False) self.hg_temp = raw_data.get("hg_temp") self.away_temp = raw_data.get("away_temp") self.cooling_away_temp = raw_data.get("cooling_away_temp") self.timetable = [ TimetableEntry(home, r) for r in raw_data.get("timetable", []) ] self.zones = [Zone(home, r) for r in raw_data.get("zones", [])] def update_topology(self, raw_data: RawData) -> None: """Update the schedule topology.""" super().update_topology(raw_data) self.selected = raw_data.get("selected", self.selected) self.default = raw_data.get("default", self.default) self.hg_temp = raw_data.get("hg_temp", self.hg_temp) self.away_temp = raw_data.get("away_temp", self.away_temp) self.cooling_away_temp = raw_data.get( "cooling_away_temp", self.cooling_away_temp, ) self.timetable = [ TimetableEntry(self.home, r) for r in raw_data.get("timetable", []) ] self.zones = [Zone(self.home, r) for r in raw_data.get("zones", [])] @dataclass class TimetableEntry: """Class to represent a Netatmo schedule's timetable entry.""" zone_id: int | None m_offset: int | None def __init__(self, home: Home, raw_data: RawData) -> None: """Initialize a Netatmo schedule's timetable entry instance.""" self.home = home self.zone_id = raw_data.get("zone_id", 0) self.m_offset = raw_data.get("m_offset", 0) @dataclass class Zone(NetatmoBase): """Class to represent a Netatmo schedule's zone.""" type: int rooms: list[Room] def __init__(self, home: Home, raw_data: RawData) -> None: """Initialize a Netatmo schedule's zone instance.""" super().__init__(raw_data) self.home = home self.type = raw_data.get("type", 0) def room_factory(home: Home, room_raw_data: RawData) -> Room: room = Room(home, room_raw_data, {}) room.update(room_raw_data) return room self.rooms = [room_factory(home, r) for r in raw_data.get("rooms", [])] pyatmo-9.2.1/tests/000077500000000000000000000000001501740523400141775ustar00rootroot00000000000000pyatmo-9.2.1/tests/__init__.py000066400000000000000000000000001501740523400162760ustar00rootroot00000000000000pyatmo-9.2.1/tests/common.py000066400000000000000000000041151501740523400160420ustar00rootroot00000000000000"""Define shared test helpers.""" from __future__ import annotations import json import pathlib def get_fixture_path(filename: str) -> pathlib.Path: """Get path of fixture.""" return pathlib.Path(__file__).parent.joinpath("../fixtures", filename) def load_fixture(filename): """Load a fixture.""" return get_fixture_path(filename).read_text(encoding="utf-8") class MockResponse: def __init__(self, text, status): self._text = text self.status = status async def json(self): return self._text async def read(self): return self._text async def __aexit__(self, exc_type, exc, traceback): pass async def __aenter__(self): return self async def fake_post_request(*_, **kwargs): """Return fake data.""" if "endpoint" not in kwargs: return "{}" endpoint = kwargs["endpoint"].split("/")[-1] if endpoint in "snapshot_720.jpg": return b"test stream image bytes" if endpoint in [ "setpersonsaway", "setpersonshome", "setstate", "setroomthermpoint", "setthermmode", "switchhomeschedule", ]: payload = f'{{"{endpoint}": true}}' elif endpoint == "homestatus": home_id = kwargs.get("params", {}).get("home_id") payload = json.loads(load_fixture(f"{endpoint}_{home_id}.json")) elif endpoint == "getmeasure": module_id = kwargs.get("params", {}).get("module_id", "") measure_type = kwargs.get("params", {}).get("type", "") payload = json.loads( load_fixture( f"{endpoint}_{measure_type}_{module_id.replace(':', '_')}.json", ), ) else: postfix = kwargs.get("POSTFIX") if postfix is not None: payload = json.loads(load_fixture(f"{endpoint}_{postfix}.json")) else: payload = json.loads(load_fixture(f"{endpoint}.json")) return MockResponse(payload, 200) async def fake_post_request_multi(*args, **kwargs): kwargs["POSTFIX"] = "multi" return await fake_post_request(*args, **kwargs) pyatmo-9.2.1/tests/conftest.py000066400000000000000000000035751501740523400164100ustar00rootroot00000000000000"""Define shared fixtures.""" from contextlib import contextmanager from unittest.mock import AsyncMock, patch import pytest import pyatmo from .common import fake_post_request, fake_post_request_multi @contextmanager def does_not_raise(): yield @pytest.fixture async def async_auth(): """AsyncAuth fixture.""" with patch("pyatmo.auth.AbstractAsyncAuth", AsyncMock()) as auth: yield auth @pytest.fixture async def async_account(async_auth): """AsyncAccount fixture.""" account = pyatmo.AsyncAccount(async_auth) with ( patch( "pyatmo.auth.AbstractAsyncAuth.async_post_api_request", fake_post_request, ), patch( "pyatmo.auth.AbstractAsyncAuth.async_post_request", fake_post_request, ), ): await account.async_update_topology() yield account @pytest.fixture async def async_home(async_account): """AsyncClimate fixture for home_id 91763b24c43d3e344f424e8b.""" home_id = "91763b24c43d3e344f424e8b" await async_account.async_update_status(home_id) return async_account.homes[home_id] @pytest.fixture async def async_account_multi(async_auth): """AsyncAccount fixture.""" account = pyatmo.AsyncAccount(async_auth) with ( patch( "pyatmo.auth.AbstractAsyncAuth.async_post_api_request", fake_post_request_multi, ), patch( "pyatmo.auth.AbstractAsyncAuth.async_post_request", fake_post_request_multi, ), ): await account.async_update_topology( disabled_homes_ids=["eeeeeeeeeffffffffffaaaaa"], ) yield account @pytest.fixture async def async_home_multi(async_account_multi): """AsyncClimate fixture for home_id 91763b24c43d3e344f424e8b.""" home_id = "aaaaaaaaaaabbbbbbbbbbccc" return async_account_multi.homes[home_id] pyatmo-9.2.1/tests/test_camera.py000066400000000000000000000111521501740523400170400ustar00rootroot00000000000000"""Define tests for camera module.""" import json from unittest.mock import AsyncMock, patch import anyio from pyatmo import DeviceType from tests.common import MockResponse async def test_async_camera_NACamera(async_home): """Test Netatmo indoor camera module.""" module_id = "12:34:56:00:f1:62" assert module_id in async_home.modules module = async_home.modules[module_id] await module.async_update_camera_urls() assert module.device_type == DeviceType.NACamera assert module.is_local assert module.local_url == "http://192.168.0.123/678460a0d47e5618699fb31169e2b47d" person_id = "91827374-7e04-5298-83ad-a0cb8372dff1" assert person_id in module.home.persons person = module.home.persons[person_id] assert person.pseudo == "John Doe" assert person.out_of_sight assert person.last_seen == 1557071156 async def test_async_camera_NPC(async_home): """Test Netatmo indoor camera advance module.""" module_id = "12:34:56:00:f1:63" assert module_id in async_home.modules module = async_home.modules[module_id] await module.async_update_camera_urls() assert module.device_type == DeviceType.NPC assert module.is_local assert module.local_url == "http://192.168.0.123/678460a0d47e5618699fb31169e2b47d" person_id = "91827374-7e04-5298-83ad-a0cb8372dff1" assert person_id in module.home.persons person = module.home.persons[person_id] assert person.pseudo == "John Doe" assert person.out_of_sight assert person.last_seen == 1557071156 async def test_async_NOC(async_home): """Test basic outdoor camera functionality.""" module_id = "12:34:56:10:b9:0e" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_type == DeviceType.NOC assert module.firmware_revision == 3002000 assert module.firmware_name == "3.2.0" assert module.monitoring is True assert module.alim_status == 2 assert module.is_local is False assert module.floodlight == "auto" async with await anyio.open_file( "fixtures/status_ok.json", encoding="utf-8", ) as json_file: response = json.loads(await json_file.read()) def gen_json_data(state): return { "json": { "home": { "id": "91763b24c43d3e344f424e8b", "modules": [ { "id": module_id, "floodlight": state, }, ], }, }, } with patch( "pyatmo.auth.AbstractAsyncAuth.async_post_api_request", AsyncMock(return_value=MockResponse(response, 200)), ) as mock_resp: assert await module.async_floodlight_on() mock_resp.assert_awaited_with( params=gen_json_data("on"), endpoint="api/setstate", ) assert await module.async_floodlight_off() mock_resp.assert_awaited_with( params=gen_json_data("off"), endpoint="api/setstate", ) assert await module.async_floodlight_auto() mock_resp.assert_awaited_with( params=gen_json_data("auto"), endpoint="api/setstate", ) async def test_async_camera_monitoring(async_home): """Test basic camera monitoring functionality.""" module_id = "12:34:56:10:b9:0e" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_type == DeviceType.NOC assert module.is_local is False async with await anyio.open_file( "fixtures/status_ok.json", encoding="utf-8", ) as json_file: response = json.loads(await json_file.read()) def gen_json_data(state): return { "json": { "home": { "id": "91763b24c43d3e344f424e8b", "modules": [ { "id": module_id, "monitoring": state, }, ], }, }, } with patch( "pyatmo.auth.AbstractAsyncAuth.async_post_api_request", AsyncMock(return_value=MockResponse(response, 200)), ) as mock_resp: assert await module.async_monitoring_on() mock_resp.assert_awaited_with( params=gen_json_data("on"), endpoint="api/setstate", ) assert await module.async_monitoring_off() mock_resp.assert_awaited_with( params=gen_json_data("off"), endpoint="api/setstate", ) pyatmo-9.2.1/tests/test_climate.py000066400000000000000000000247201501740523400172330ustar00rootroot00000000000000"""Define tests for climate module.""" import json from unittest.mock import AsyncMock, patch import anyio import pytest from pyatmo import DeviceType, NoScheduleError from pyatmo.modules import NATherm1 from pyatmo.modules.device_types import DeviceCategory from tests.common import MockResponse, fake_post_request from tests.conftest import does_not_raise async def test_async_climate_room(async_home): """Test room with climate devices.""" room_id = "2746182631" assert room_id in async_home.rooms room = async_home.rooms[room_id] assert room.reachable is True assert room.device_types == {DeviceType.NATherm1} module_id = "12:34:56:00:01:ae" assert module_id in room.modules assert len(room.modules) == 1 async def test_async_climate_NATherm1(async_home): """Test NATherm1 climate device.""" module_id = "12:34:56:00:01:ae" module = async_home.modules[module_id] assert module.name == "Livingroom" assert module.device_type == DeviceType.NATherm1 assert module.reachable is True assert module.boiler_status is False assert module.firmware_revision == 65 assert module.battery == 75 assert module.rf_strength == 58 async def test_async_climate_NRV(async_home): """Test NRV climate device.""" module_id = "12:34:56:03:a5:54" module = async_home.modules[module_id] assert module.name == "Valve1" assert async_home.rooms[module.room_id].name == "Entrada" assert module.device_type == DeviceType.NRV assert module.reachable is True assert module.rf_strength == 51 assert module.battery == 90 assert module.firmware_revision == 79 async def test_async_climate_NAPlug(async_home): """Test NAPlug climate device.""" module_id = "12:34:56:00:fa:d0" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_type == DeviceType.NAPlug assert len(module.modules) == 3 assert module.rf_strength == 107 assert module.wifi_strength == 42 assert module.firmware_revision == 174 async def test_async_climate_NIS(async_home): """Test Netatmo siren.""" module_id = "12:34:56:00:e3:9b" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_type == DeviceType.NIS assert module.firmware_revision == 209 assert module.status == "no_sound" assert module.monitoring is False async def test_async_climate_OTM(async_home): """Test OTM climate device.""" module_id = "12:34:56:20:f5:8c" module = async_home.modules[module_id] assert module.name == "Bureau Modulate" assert module.device_type == DeviceType.OTM assert module.reachable is True assert module.boiler_status is False assert module.firmware_revision == 6 assert module.battery == 90 assert module.rf_strength == 64 async def test_async_climate_OTH(async_home): """Test OTH climate device.""" module_id = "12:34:56:20:f5:44" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_type == DeviceType.OTH assert len(module.modules) == 1 assert module.wifi_strength == 57 assert module.firmware_revision == 22 async def test_async_climate_BNS(async_home): """Test Smarther BNS climate module.""" module_id = "10:20:30:bd:b8:1e" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_type == DeviceType.BNS assert module.name == "Smarther" room = async_home.rooms[module.room_id] assert room.name == "Corridor" assert room.device_types == { DeviceType.BNS, } assert room.features == {"humidity", DeviceCategory.climate} async def test_async_climate_update(async_account): """Test basic climate state update.""" home_id = "91763b24c43d3e344f424e8b" await async_account.async_update_status(home_id) home = async_account.homes[home_id] room_id = "2746182631" room = home.rooms[room_id] module_id = "12:34:56:00:01:ae" module = home.modules[module_id] assert room.reachable is True assert room.humidity is None assert module.name == "Livingroom" assert module.device_type == DeviceType.NATherm1 assert module.reachable is True assert module.boiler_status is False assert module.battery == 75 assert isinstance(module, NATherm1) async with await anyio.open_file( "fixtures/home_status_error_disconnected.json", encoding="utf-8", ) as json_file: content = await json_file.read() home_status_fixture = json.loads(content) mock_home_status_resp = MockResponse(home_status_fixture, 200) with patch( "pyatmo.auth.AbstractAsyncAuth.async_post_api_request", AsyncMock(return_value=mock_home_status_resp), ) as mock_request: await async_account.async_update_status(home_id) mock_request.assert_called() assert room.reachable is None assert module.reachable is False async with await anyio.open_file( "fixtures/home_status_simple.json", encoding="utf-8", ) as json_file: home_status_fixture = json.loads(await json_file.read()) mock_home_status_resp = MockResponse(home_status_fixture, 200) with patch( "pyatmo.auth.AbstractAsyncAuth.async_post_api_request", AsyncMock(return_value=mock_home_status_resp), ) as mock_request: await async_account.async_update_status(home_id) mock_request.assert_called() assert room.reachable is True assert module.reachable is True assert module.battery == 75 assert module.rf_strength == 58 @pytest.mark.parametrize( ("t_sched_id", "expected"), [ ("591b54a2764ff4d50d8b5795", does_not_raise()), ( "123456789abcdefg12345678", pytest.raises(NoScheduleError), ), ], ) async def test_async_climate_switch_schedule( async_home, t_sched_id, expected, ): async with await anyio.open_file( "fixtures/status_ok.json", encoding="utf-8", ) as json_file: response = json.loads(await json_file.read()) with ( patch( "pyatmo.auth.AbstractAsyncAuth.async_post_api_request", AsyncMock(return_value=MockResponse(response, 200)), ), expected, ): await async_home.async_switch_schedule( schedule_id=t_sched_id, ) @pytest.mark.parametrize( ("temp", "end_time"), [ ( 14, None, ), ( 14, 1559162650, ), ( None, None, ), ( None, 1559162650, ), ], ) async def test_async_climate_room_therm_set( async_home, temp, end_time, ): room_id = "2746182631" mode = "home" expected_params = { "home_id": "91763b24c43d3e344f424e8b", "room_id": room_id, "mode": mode, } if temp: expected_params["temp"] = str(temp) if end_time: expected_params["endtime"] = str(end_time) async with await anyio.open_file( "fixtures/status_ok.json", encoding="utf-8", ) as json_file: response = json.loads(await json_file.read()) with patch( "pyatmo.auth.AbstractAsyncAuth.async_post_api_request", AsyncMock(return_value=MockResponse(response, 200)), ) as mock_post: room = async_home.rooms[room_id] await room.async_therm_set( mode=mode, temp=temp, end_time=end_time, ) mock_post.assert_awaited_once_with( endpoint="api/setroomthermpoint", params=expected_params, ) @pytest.mark.parametrize( ("mode", "end_time", "schedule_id", "json_fixture", "expected", "exception"), [ ( "away", None, None, "status_ok.json", True, does_not_raise(), ), ( "away", 1559162650, None, "status_ok.json", True, does_not_raise(), ), ( "schedule", None, "591b54a2764ff4d50d8b5795", "status_ok.json", True, does_not_raise(), ), ( "schedule", 1559162650, "591b54a2764ff4d50d8b5795", "status_ok.json", True, does_not_raise(), ), ( None, None, None, "home_status_error_mode_is_missing.json", False, pytest.raises(NoScheduleError), ), ( "away", 1559162650, 0000000, "status_ok.json", True, pytest.raises(NoScheduleError), ), ( "schedule", None, "blahblahblah", "home_status_error_invalid_schedule_id.json", False, pytest.raises(NoScheduleError), ), ], ) async def test_async_climate_set_thermmode( async_home, mode, end_time, schedule_id, json_fixture, expected, exception, ): async with await anyio.open_file( f"fixtures/{json_fixture}", encoding="utf-8", ) as json_file: response = json.loads(await json_file.read()) with ( patch( "pyatmo.auth.AbstractAsyncAuth.async_post_api_request", AsyncMock(return_value=MockResponse(response, 200)), ), exception, ): resp = await async_home.async_set_thermmode( mode=mode, end_time=end_time, schedule_id=schedule_id, ) assert expected is resp async def test_async_climate_empty_home(async_account): """Test climate setup with empty home.""" home_id = "91763b24c43d3e344f424e8c" with patch( "pyatmo.auth.AbstractAsyncAuth.async_post_api_request", fake_post_request, ): await async_account.async_update_status(home_id) assert home_id in async_account.homes home = async_account.homes[home_id] assert len(home.rooms) == 0 async def test_power_wire(async_home_multi): """Test room with climate devices.""" room_id = "3707962039" assert room_id in async_home_multi.rooms room = async_home_multi.rooms[room_id] assert room.climate_type == DeviceType.NLC assert DeviceType.NLC in room.device_types assert room.support_pilot_wire is True pyatmo-9.2.1/tests/test_energy.py000066400000000000000000000112661501740523400171070ustar00rootroot00000000000000"""Define tests for energy module.""" import datetime as dt import json from unittest.mock import patch import anyio import pytest import time_machine from pyatmo import ApiHomeReachabilityError, DeviceType from pyatmo.modules.module import EnergyHistoryMixin, MeasureInterval from tests.common import MockResponse async def test_async_energy_NLPC(async_home): """Test Legrand / BTicino connected energy meter module.""" module_id = "12:34:56:00:00:a1:4c:da" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_type == DeviceType.NLPC assert module.power == 476 @time_machine.travel(dt.datetime(2022, 2, 12, 7, 59, 49)) async def test_historical_data_retrieval(async_account): """Test retrieval of historical measurements.""" home_id = "91763b24c43d3e344f424e8b" await async_account.async_update_events(home_id=home_id) home = async_account.homes[home_id] module_id = "12:34:56:00:00:a1:4c:da" assert module_id in home.modules module = home.modules[module_id] assert module.device_type == DeviceType.NLPC await async_account.async_update_measures(home_id=home_id, module_id=module_id) # changed the reference here as start and stop data was not calculated in the spirit of the netatmo api where their time data is in the fact representing the "middle" of the range and not the begining assert module.historical_data[0] == { "Wh": 197, "duration": 60, "endTime": "2022-02-05T08:59:49Z", "endTimeUnix": 1644051589, "energyMode": ["basic"], "WhPerModes": [197], "startTime": "2022-02-05T07:59:50Z", "startTimeUnix": 1644047989, } assert module.historical_data[-1] == { "Wh": 259, "duration": 60, "endTime": "2022-02-12T07:59:49Z", "endTimeUnix": 1644652789, "energyMode": ["basic"], "WhPerModes": [259], "startTime": "2022-02-12T06:59:50Z", "startTimeUnix": 1644649189, } assert len(module.historical_data) == 168 @time_machine.travel(dt.datetime(2024, 7, 24, 22, 00, 10)) async def test_historical_data_retrieval_multi(async_account_multi): """Test retrieval of historical measurements.""" home_id = "aaaaaaaaaaabbbbbbbbbbccc" home = async_account_multi.homes[home_id] module_id = "98:76:54:32:10:00:00:69" assert module_id in home.modules module = home.modules[module_id] assert module.device_type == DeviceType.NLPC strt = int(dt.datetime.fromisoformat("2024-07-24 00:00:00").timestamp()) end_time = int(dt.datetime.fromisoformat("2024-07-24 22:27:00").timestamp()) await async_account_multi.async_update_measures( home_id=home_id, module_id=module_id, interval=MeasureInterval.HALF_HOUR, start_time=strt, end_time=end_time, ) assert isinstance(module, EnergyHistoryMixin) assert module.historical_data[0] == { "Wh": 20, "duration": 30, "endTime": "2024-07-23T22:30:00Z", "endTimeUnix": 1721773800, "energyMode": ["basic"], "WhPerModes": [20], "startTime": "2024-07-23T22:00:01Z", "startTimeUnix": 1721772000, } assert module.historical_data[17] == { "Wh": 710, "WhPerModes": [498, 212], "duration": 30, "endTime": "2024-07-24T07:00:00Z", "endTimeUnix": 1721804400, "energyMode": ["basic", "peak"], "startTime": "2024-07-24T06:30:01Z", "startTimeUnix": 1721802600, } assert module.historical_data[-1] == { "Wh": 16, "WhPerModes": [16], "duration": 30, "endTime": "2024-07-24T17:30:00Z", "endTimeUnix": 1721842200, "energyMode": ["peak"], "startTime": "2024-07-24T17:00:01Z", "startTimeUnix": 1721840400, } assert len(module.historical_data) == 39 assert module.sum_energy_elec == 17547 assert module.sum_energy_elec_off_peak == 4290 assert module.sum_energy_elec_peak == 10177 @patch("pyatmo.auth.AbstractAsyncAuth.async_post_api_request") async def test_disconnected_main_bridge(mock_home_status, async_account_multi): """Test retrieval of historical measurements.""" home_id = "aaaaaaaaaaabbbbbbbbbbccc" async with await anyio.open_file( "fixtures/home_multi_status_error_disconnected.json", encoding="utf-8", ) as json_file: content = await json_file.read() home_status_fixture = json.loads(content) mock_home_status_resp = MockResponse(home_status_fixture, 200) mock_home_status.return_value = mock_home_status_resp with pytest.raises(ApiHomeReachabilityError): await async_account_multi.async_update_status(home_id) pyatmo-9.2.1/tests/test_fan.py000066400000000000000000000007111501740523400163530ustar00rootroot00000000000000"""Define tests for fan module.""" from pyatmo import DeviceType async def test_async_fan_NLLF(async_home): """Test NLLF Legrand centralized ventilation controller.""" module_id = "12:34:56:00:01:01:01:b1" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_type == DeviceType.NLLF assert module.power == 11 assert module.firmware_revision == 60 assert module.fan_speed == 1 pyatmo-9.2.1/tests/test_home.py000066400000000000000000000175071501740523400165520ustar00rootroot00000000000000"""Define tests for home module.""" import json from unittest.mock import AsyncMock, patch import anyio import pytest import pyatmo from pyatmo import DeviceType, InvalidScheduleError, NoDeviceError from tests.common import MockResponse async def test_async_home(async_home): """Test basic home setup.""" room_id = "3688132631" room = async_home.rooms[room_id] assert room.device_types == { DeviceType.NDB, DeviceType.NACamera, DeviceType.NBR, DeviceType.NIS, DeviceType.NBO, DeviceType.NPC, DeviceType.NLPD, } assert len(async_home.rooms) == 9 assert len(async_home.modules) == 51 assert async_home.modules != room.modules module_id = "12:34:56:10:f1:66" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_type == DeviceType.NDB module_id = "12:34:56:10:b9:0e" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_type == DeviceType.NOC assert async_home.temperature_control_mode == "cooling" async def test_async_home_set_schedule(async_home): """Test home schedule.""" schedule_id = "591b54a2764ff4d50d8b5795" selected_schedule = async_home.get_selected_schedule() assert selected_schedule.entity_id == schedule_id assert async_home.is_valid_schedule(schedule_id) assert not async_home.is_valid_schedule("123") assert async_home.get_hg_temp() == 7 assert async_home.get_away_temp() == 14 async def test_async_set_schedule_temperatures(async_home): """Test setting schedule temperatures.""" schedule_id = "591b54a2764ff4d50d8b5795" schedule = async_home.get_selected_schedule() assert schedule.entity_id == schedule_id zone = next((zone for zone in schedule.zones if zone.entity_id == 1), None) assert zone is not None room = next((room for room in zone.rooms if room.entity_id == "2746182631"), None) assert room is not None assert room.therm_setpoint_temperature == 17 temps = {"2746182631": 15} async with await anyio.open_file( "fixtures/sync_schedule_591b54a2764ff4d50d8b5795.json", encoding="utf-8", ) as fixture_file: json_fixture = json.loads(await fixture_file.read()) with patch( "pyatmo.auth.AbstractAsyncAuth.async_post_api_request", AsyncMock(return_value=MockResponse({"status": "ok"}, 200)), ) as mock_resp: await async_home.async_set_schedule_temperatures(1, temps) mock_resp.assert_awaited_with( endpoint="api/synchomeschedule", params={ "params": { "home_id": "91763b24c43d3e344f424e8b", "schedule_id": schedule_id, "name": "Default", }, "json": json_fixture, }, ) async def test_async_sync_schedule(async_home): """Test setting schedule temperatures.""" schedule_id = "b1b54a2f45795764f59d50d8" schedule = async_home.schedules.get(schedule_id) assert schedule is not None assert schedule.entity_id == schedule_id zone = next((zone for zone in schedule.zones if zone.entity_id == 1), None) assert zone is not None room = next((room for room in zone.rooms if room.entity_id == "2746182631"), None) assert room is not None assert room.therm_setpoint_temperature == 17 # set a new room temperature room.therm_setpoint_temperature = 14 async with await anyio.open_file( "fixtures/sync_schedule_b1b54a2f45795764f59d50d8.json", encoding="utf-8", ) as fixture_file: json_fixture = json.loads(await fixture_file.read()) with patch( "pyatmo.auth.AbstractAsyncAuth.async_post_api_request", AsyncMock(return_value=MockResponse({"status": "ok"}, 200)), ) as mock_resp: await async_home.async_sync_schedule(schedule) mock_resp.assert_awaited_with( endpoint="api/synchomeschedule", params={ "params": { "home_id": "91763b24c43d3e344f424e8b", "schedule_id": schedule_id, "name": "Default", }, "json": json_fixture, }, ) async def test_async_sync_schedule_invalid_schedule(async_home): """Test syncing an invalid schedule.""" invalid_schedule = {"invalid": "data"} with ( pytest.raises(InvalidScheduleError), patch( "pyatmo.home.is_valid_schedule", return_value=False, ), ): await async_home.async_sync_schedule(invalid_schedule) async def test_async_home_data_no_body(async_auth): """Test home data with no body.""" async with await anyio.open_file( "fixtures/homesdata_empty.json", encoding="utf-8", ) as fixture_file: json_fixture = json.loads(await fixture_file.read()) mock_request = AsyncMock(return_value=MockResponse(json_fixture, 200)) with patch( "pyatmo.auth.AbstractAsyncAuth.async_post_api_request", mock_request, ): climate = pyatmo.AsyncAccount(async_auth) with pytest.raises(NoDeviceError): await climate.async_update_topology() mock_request.assert_awaited_once() async def test_async_set_persons_home(async_account): """Test marking a person being at home.""" home_id = "91763b24c43d3e344f424e8b" home = async_account.homes[home_id] person_ids = [ "91827374-7e04-5298-83ad-a0cb8372dff1", "91827375-7e04-5298-83ae-a0cb8372dff2", ] async with await anyio.open_file( "fixtures/status_ok.json", encoding="utf-8", ) as json_file: response = json.loads(await json_file.read()) with patch( "pyatmo.auth.AbstractAsyncAuth.async_post_api_request", AsyncMock(return_value=MockResponse(response, 200)), ) as mock_resp: await home.async_set_persons_home(person_ids) mock_resp.assert_awaited_with( params={"home_id": home_id, "person_ids[]": person_ids}, endpoint="api/setpersonshome", ) async def test_async_set_persons_away(async_account): """Test marking a set of persons being away.""" home_id = "91763b24c43d3e344f424e8b" home = async_account.homes[home_id] async with await anyio.open_file( "fixtures/status_ok.json", encoding="utf-8", ) as json_file: response = json.loads(await json_file.read()) with patch( "pyatmo.auth.AbstractAsyncAuth.async_post_api_request", AsyncMock(return_value=MockResponse(response, 200)), ) as mock_resp: person_id = "91827374-7e04-5298-83ad-a0cb8372dff1" await home.async_set_persons_away(person_id) mock_resp.assert_awaited_with( params={"home_id": home_id, "person_id": person_id}, endpoint="api/setpersonsaway", ) await home.async_set_persons_away() mock_resp.assert_awaited_with( params={"home_id": home_id}, endpoint="api/setpersonsaway", ) async def test_home_event_update(async_account): """Test basic event update.""" home_id = "91763b24c43d3e344f424e8b" await async_account.async_update_events(home_id=home_id) home = async_account.homes[home_id] events = home.events assert len(events) == 8 module_id = "12:34:56:10:b9:0e" assert module_id in home.modules module = home.modules[module_id] events = module.events assert len(events) == 5 assert events[0].event_type == "outdoor" assert events[0].video_id == "11111111-2222-3333-4444-b42f0fc4cfad" assert events[1].event_type == "connection" def test_device_types_missing(): """Test handling of missing device types.""" assert DeviceType("NOC") == DeviceType.NOC assert DeviceType("UNKNOWN") == DeviceType.NLunknown pyatmo-9.2.1/tests/test_shutter.py000066400000000000000000000067341501740523400173200ustar00rootroot00000000000000"""Define tests for shutter module.""" import json from unittest.mock import AsyncMock, patch import anyio from pyatmo import DeviceType from tests.common import MockResponse async def test_async_shutter_NBR(async_home): """Test NLP Bubendorf iDiamant roller shutter.""" module_id = "0009999992" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_type == DeviceType.NBR assert module.firmware_revision == 16 assert module.current_position == 0 async def test_async_shutter_Z3V(async_home): """Test NLG Legrand roller shutter 3rd party.""" module_id = "12:34:56:80:00:c3:69:3d" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_type == DeviceType.Z3V assert module.firmware_revision == 16 assert module.current_position == 0 async def test_async_shutter_NBO(async_home): """Test NBO Bubendorf iDiamant roller shutter.""" module_id = "0009999993" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_type == DeviceType.NBO assert module.firmware_revision == 22 assert module.current_position == 0 async def test_async_shutters(async_home): """Test basic shutter functionality.""" room_id = "3688132631" assert room_id in async_home.rooms module_id = "0009999992" module = async_home.modules[module_id] assert module.device_type == DeviceType.NBR async with await anyio.open_file( "fixtures/status_ok.json", encoding="utf-8", ) as json_file: response = json.loads(await json_file.read()) def gen_json_data(position): return { "json": { "home": { "id": "91763b24c43d3e344f424e8b", "modules": [ { "bridge": "12:34:56:30:d5:d4", "id": module_id, "target_position": position, }, ], }, }, } with patch( "pyatmo.auth.AbstractAsyncAuth.async_post_api_request", AsyncMock(return_value=MockResponse(response, 200)), ) as mock_resp: assert await module.async_open() mock_resp.assert_awaited_with( params=gen_json_data(100), endpoint="api/setstate", ) assert await module.async_close() mock_resp.assert_awaited_with( params=gen_json_data(0), endpoint="api/setstate", ) assert await module.async_stop() mock_resp.assert_awaited_with( params=gen_json_data(-1), endpoint="api/setstate", ) assert await module.async_move_to_preferred_position() mock_resp.assert_awaited_with( params=gen_json_data(-2), endpoint="api/setstate", ) assert await module.async_set_target_position(47) mock_resp.assert_awaited_with( params=gen_json_data(47), endpoint="api/setstate", ) assert await module.async_set_target_position(-10) mock_resp.assert_awaited_with( params=gen_json_data(-1), endpoint="api/setstate", ) assert await module.async_set_target_position(101) mock_resp.assert_awaited_with( params=gen_json_data(100), endpoint="api/setstate", ) pyatmo-9.2.1/tests/test_switch.py000066400000000000000000000027321501740523400171150ustar00rootroot00000000000000"""Define tests for switch module.""" from pyatmo import DeviceType from pyatmo.modules.device_types import DeviceCategory async def test_async_switch_NLP(async_home): """Test NLP Legrand plug.""" module_id = "12:34:56:80:00:12:ac:f2" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_type == DeviceType.NLP assert module.firmware_revision == 62 assert module.on assert module.power == 0 async def test_async_switch_NLF(async_home): """Test NLF Legrand dimmer.""" module_id = "00:11:22:33:00:11:45:fe" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_type == DeviceType.NLF assert module.firmware_revision == 57 assert module.on is False assert module.brightness == 63 assert module.power == 0 async def test_async_switch_NLIS(async_home): """Test NLIS Legrand module.""" module_id = "12:34:56:00:01:01:01:b6" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_category is None module_id = "12:34:56:00:01:01:01:b6#1" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_category == DeviceCategory.switch module_id = "12:34:56:00:01:01:01:b6#2" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_category == DeviceCategory.switch pyatmo-9.2.1/tests/test_weather.py000066400000000000000000000247321501740523400172570ustar00rootroot00000000000000"""Define tests for weaather module.""" import pyatmo from pyatmo import DeviceType from pyatmo.modules.base_class import Location, Place async def test_async_weather_NAMain(async_home): """Test Netatmo weather station main module.""" module_id = "12:34:56:80:bb:26" assert module_id in async_home.modules module = async_home.modules[module_id] assert module.device_type == DeviceType.NAMain async def test_async_weather_update_main(async_account): """Test main weather station module.""" home_id = "91763b24c43d3e344f424e8b" await async_account.async_update_weather_stations() home = async_account.homes[home_id] module_id = "12:34:56:80:bb:26" assert module_id in home.modules module = home.modules[module_id] assert module.device_type == DeviceType.NAMain assert module.name == "Villa" assert module.modules == [ "12:34:56:80:44:92", "12:34:56:80:7e:18", "12:34:56:80:1c:42", "12:34:56:80:c1:ea", ] assert module.features == { "temperature", "humidity", "co2", "noise", "pressure", "absolute_pressure", "temp_trend", "pressure_trend", "min_temp", "max_temp", "temp_max", "temp_min", "reachable", "wifi_strength", "place", } assert module.firmware_revision == 181 assert module.wifi_strength == 57 assert module.temperature == 21.1 assert module.humidity == 45 assert module.co2 == 1339 assert module.pressure == 1026.8 assert module.noise == 35 assert module.absolute_pressure == 974.5 assert module.place == Place( { "altitude": 329, "city": "Someplace", "country": "FR", "location": Location(longitude=6.1234567, latitude=46.123456), "timezone": "Europe/Paris", }, ) async def test_async_weather_update_indoor(async_account): """Test indoor weather module.""" home_id = "91763b24c43d3e344f424e8b" await async_account.async_update_weather_stations() home = async_account.homes[home_id] module_id = "12:34:56:80:44:92" assert module_id in home.modules module = home.modules[module_id] assert module.name == "Villa Bedroom" assert module.features == { "temperature", "temp_trend", "min_temp", "max_temp", "temp_max", "temp_min", "reachable", "rf_strength", "co2", "humidity", "battery", "place", } assert module.device_type == DeviceType.NAModule4 assert module.modules is None assert module.firmware_revision == 51 assert module.rf_strength == 67 assert module.temperature == 19.3 assert module.humidity == 53 assert module.battery == 28 async def test_async_weather_update_rain(async_account): """Test rain module.""" home_id = "91763b24c43d3e344f424e8b" await async_account.async_update_weather_stations() home = async_account.homes[home_id] module_id = "12:34:56:80:c1:ea" assert module_id in home.modules module = home.modules[module_id] assert module.name == "Villa Rain" assert module.features == { "sum_rain_1", "sum_rain_24", "rain", "reachable", "rf_strength", "battery", "place", } assert module.device_type == DeviceType.NAModule3 assert module.modules is None assert module.firmware_revision == 12 assert module.rf_strength == 79 assert module.rain == 3.7 async def test_async_weather_update_outdoor(async_account): """Test outdoor module.""" home_id = "91763b24c43d3e344f424e8b" await async_account.async_update_weather_stations() home = async_account.homes[home_id] module_id = "12:34:56:80:1c:42" assert module_id in home.modules module = home.modules[module_id] assert module.name == "Villa Outdoor" assert module.features == { "temperature", "humidity", "temp_trend", "min_temp", "max_temp", "temp_max", "temp_min", "reachable", "rf_strength", "battery", "place", } assert module.device_type == DeviceType.NAModule1 assert module.modules is None assert module.firmware_revision == 50 assert module.rf_strength == 68 assert module.reachable is False async def test_async_weather_update_wind(async_account): """Test wind module.""" home_id = "91763b24c43d3e344f424e8b" await async_account.async_update_weather_stations() home = async_account.homes[home_id] module_id = "12:34:56:03:1b:e4" assert module_id in home.modules module = home.modules[module_id] assert module.name == "Villa Garden" assert module.features == { "wind_strength", "gust_strength", "gust_angle", "gust_direction", "wind_angle", "wind_direction", "reachable", "rf_strength", "battery", "place", } assert module.device_type == DeviceType.NAModule2 assert module.modules is None assert module.firmware_revision == 19 assert module.rf_strength == 59 assert module.wind_strength == 4 assert module.wind_angle == 217 assert module.gust_strength == 9 assert module.gust_angle == 206 async def test_async_weather_favorite(async_account): """Test favorite weather station.""" await async_account.async_update_weather_stations() module_id = "00:11:22:2c:be:c8" assert module_id in async_account.modules module = async_account.modules[module_id] assert module.device_type == DeviceType.NAMain assert module.name == "Zuhause (Kinderzimmer)" assert module.modules == ["00:11:22:2c:ce:b6"] assert module.features == { "temperature", "humidity", "co2", "noise", "pressure", "absolute_pressure", "temp_trend", "pressure_trend", "min_temp", "max_temp", "temp_max", "temp_min", "reachable", "wifi_strength", "place", } assert module.pressure == 1015.6 assert module.absolute_pressure == 1000.4 assert module.place == Place( { "altitude": 127, "city": "Wiesbaden", "country": "DE", "location": Location( longitude=8.238054275512695, latitude=50.07585525512695, ), "timezone": "Europe/Berlin", }, ) module_id = "00:11:22:2c:ce:b6" assert module_id in async_account.modules module = async_account.modules[module_id] assert module.device_type == DeviceType.NAModule1 assert module.name == "Unknown" assert module.modules is None assert module.features == { "temperature", "humidity", "temp_trend", "min_temp", "max_temp", "temp_max", "temp_min", "reachable", "rf_strength", "battery", "place", } assert module.temperature == 7.8 assert module.humidity == 87 async def test_async_air_care_update(async_account): """Test basic air care update.""" await async_account.async_update_air_care() module_id = "12:34:56:26:68:92" assert module_id in async_account.modules module = async_account.modules[module_id] assert module.device_type == DeviceType.NHC assert module.name == "Baby Bedroom" assert module.features == { "temperature", "humidity", "co2", "noise", "pressure", "absolute_pressure", "temp_trend", "pressure_trend", "min_temp", "max_temp", "temp_max", "temp_min", "health_idx", "reachable", "wifi_strength", "place", } assert module.modules is None assert module.firmware_revision == 45 assert module.wifi_strength == 68 assert module.temperature == 21.6 assert module.humidity == 66 assert module.co2 == 1053 assert module.pressure == 1021.4 assert module.noise == 45 assert module.absolute_pressure == 1011 assert module.health_idx == 1 async def test_async_public_weather_update(async_account): """Test basic public weather update.""" lon_ne = "6.221652" lat_ne = "46.610870" lon_sw = "6.217828" lat_sw = "46.596485" area_id = async_account.register_public_weather_area(lat_ne, lon_ne, lat_sw, lon_sw) await async_account.async_update_public_weather(area_id) area = async_account.public_weather_areas[area_id] assert area.location == pyatmo.modules.Location( lat_ne, lon_ne, lat_sw, lon_sw, ) assert area.stations_in_area() == 8 assert area.get_latest_rain() == { "70:ee:50:1f:68:9e": 0, "70:ee:50:27:25:b0": 0, "70:ee:50:36:94:7c": 0.5, "70:ee:50:36:a9:fc": 0, } assert area.get_60_min_rain() == { "70:ee:50:1f:68:9e": 0, "70:ee:50:27:25:b0": 0, "70:ee:50:36:94:7c": 0.2, "70:ee:50:36:a9:fc": 0, } assert area.get_24_h_rain() == { "70:ee:50:1f:68:9e": 9.999, "70:ee:50:27:25:b0": 11.716000000000001, "70:ee:50:36:94:7c": 12.322000000000001, "70:ee:50:36:a9:fc": 11.009, } assert area.get_latest_pressures() == { "70:ee:50:1f:68:9e": 1007.3, "70:ee:50:27:25:b0": 1012.8, "70:ee:50:36:94:7c": 1010.6, "70:ee:50:36:a9:fc": 1010, "70:ee:50:01:20:fa": 1014.4, "70:ee:50:04:ed:7a": 1005.4, "70:ee:50:27:9f:2c": 1010.6, "70:ee:50:3c:02:78": 1011.7, } assert area.get_latest_temperatures() == { "70:ee:50:1f:68:9e": 21.1, "70:ee:50:27:25:b0": 23.2, "70:ee:50:36:94:7c": 21.4, "70:ee:50:36:a9:fc": 20.1, "70:ee:50:01:20:fa": 27.4, "70:ee:50:04:ed:7a": 19.8, "70:ee:50:27:9f:2c": 25.5, "70:ee:50:3c:02:78": 23.3, } assert area.get_latest_humidities() == { "70:ee:50:1f:68:9e": 69, "70:ee:50:27:25:b0": 60, "70:ee:50:36:94:7c": 62, "70:ee:50:36:a9:fc": 67, "70:ee:50:01:20:fa": 58, "70:ee:50:04:ed:7a": 76, "70:ee:50:27:9f:2c": 56, "70:ee:50:3c:02:78": 58, } assert area.get_latest_wind_strengths() == {"70:ee:50:36:a9:fc": 15} assert area.get_latest_wind_angles() == {"70:ee:50:36:a9:fc": 17} assert area.get_latest_gust_strengths() == {"70:ee:50:36:a9:fc": 31} assert area.get_latest_gust_angles() == {"70:ee:50:36:a9:fc": 217} pyatmo-9.2.1/tests/testing_main_template.py000066400000000000000000000017031501740523400211260ustar00rootroot00000000000000import asyncio from aiohttp import ClientSession import pyatmo from pyatmo.auth import AbstractAsyncAuth from pyatmo.modules.module import MeasureInterval MY_TOKEN_FROM_NETATMO = "MY_TOKEN" class MyAuth(AbstractAsyncAuth): async def async_get_access_token(self): return MY_TOKEN_FROM_NETATMO async def main(): session = ClientSession() async_auth = MyAuth(session) account = pyatmo.AsyncAccount(async_auth) t = asyncio.create_task(account.async_update_topology()) home_id = "MY_HOME_ID" module_id = "MY_MODULE_ID" await asyncio.gather(t) await account.async_update_status(home_id=home_id) strt = 1709766000 + 10 * 60 end = 1709852400 + 10 * 60 await account.async_update_measures( home_id=home_id, module_id=module_id, interval=MeasureInterval.HALF_HOUR, start_time=strt, end_time=end, ) if __name__ == "__main__": topology = asyncio.run(main()) pyatmo-9.2.1/tox.ini000066400000000000000000000012771501740523400143570ustar00rootroot00000000000000[tox] envlist = py311,py312,mypy isolated_build = True skip_missing_interpreters = True [gh-actions] python = 3.11: py311 3.12: py312,mypy [testenv:py311,py312] deps = pytest-cov pytest-mock pytest-asyncio requests-mock time-machine anyio setenv = COVERAGE_FILE = {envlogdir}/.coverage commands = python -m pytest --cov {envsitepackagesdir}/pyatmo {posargs} [coverage:paths] source = pyatmo .tox/*/lib/python*/site-packages/pyatmo [coverage:run] branch = True omit = */__main__.py source = pyatmo [coverage:report] show_missing = True precision = 2 fail_under = 78 [testenv:mypy] deps = mypy types-requests commands = mypy -p pyatmo pyatmo-9.2.1/uv.lock000066400000000000000000007754031501740523400143610ustar00rootroot00000000000000version = 1 revision = 2 requires-python = ">=3.11" [[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.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, { name = "aiosignal" }, { name = "attrs" }, { name = "frozenlist" }, { name = "multidict" }, { name = "propcache" }, { name = "yarl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/eb/62/95588e933dfea06a3af0332990bd19f6768f8f37fa4c0fe33fe4c55cf9d0/aiohttp-3.12.7.tar.gz", hash = "sha256:08bf55b216c779eddb6e41c1841c17d7ddd12776c7d7b36051c0a292a9ca828e", size = 7806530, upload-time = "2025-06-02T16:34:10.399Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/af/19/37560cc111d6fd95ff6c4bd14445e3c629269fce406c89cc7a69a2865ecf/aiohttp-3.12.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:388b5947aa6931ef4ce3ed4edde6853e84980677886992cfadcf733dd06eed63", size = 707169, upload-time = "2025-06-02T16:31:39.107Z" }, { url = "https://files.pythonhosted.org/packages/b9/18/29bbefb094f81a687473c1d31391bf8a4c48c7b5b8559c3679fc14e67597/aiohttp-3.12.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9ed5af1cce257cca27a3e920b003b3b397f63418a203064b7d804ea3b45782af", size = 479443, upload-time = "2025-06-02T16:31:41.185Z" }, { url = "https://files.pythonhosted.org/packages/cf/7d/119f3e012c75a3fe38f86ac1d77f1452779e0e940770d5827d4e62aa5655/aiohttp-3.12.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f466ae8f9c02993b7d167be685bdbeb527cf254a3cfcc757697e0e336399d0a2", size = 467706, upload-time = "2025-06-02T16:31:43.401Z" }, { url = "https://files.pythonhosted.org/packages/83/f1/f61d8573d648e17347ab9a112063e4363664b5b6100792467fbb26028bde/aiohttp-3.12.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2be095a420a9f9a12eff343d877ae180dd919238b539431af08cef929e874759", size = 1737902, upload-time = "2025-06-02T16:31:45.948Z" }, { url = "https://files.pythonhosted.org/packages/4b/f8/7a8a000bc63de3c79aaa8f03b0784e29e9982276f4579c5e2e56d560e403/aiohttp-3.12.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b058cf2ba6adba699960d7bc403411c8a99ab5d3e5ea3eb01473638ae7d1a30e", size = 1686569, upload-time = "2025-06-02T16:31:47.749Z" }, { url = "https://files.pythonhosted.org/packages/5c/4e/29a5b35ca9a598f51dc7deff4e8403bf813988f30a8b250e25a8442641b7/aiohttp-3.12.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9b6a660163b055686dbb0acc961978fd14537eba5d9da6cbdb4dced7a8d3be1a", size = 1785359, upload-time = "2025-06-02T16:31:49.687Z" }, { url = "https://files.pythonhosted.org/packages/f9/36/0521398a69c40ac24c659b130597e2544cde1d7dd00291b8a6206bb552d0/aiohttp-3.12.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d741923905f267ad5d5c8f86a56f9d2beac9f32a36c217c5d9ef65cd74fd8ca0", size = 1824408, upload-time = "2025-06-02T16:31:51.518Z" }, { url = "https://files.pythonhosted.org/packages/c1/41/79506d76da96399b6b700acbe10b14291547a3b49a1cc7ed2c5edaa199ce/aiohttp-3.12.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:519f5454b6018158ae0e789b8f6a88726c47dd680982eb318ef3ca4dee727314", size = 1726867, upload-time = "2025-06-02T16:31:53.277Z" }, { url = "https://files.pythonhosted.org/packages/32/d1/d59ed16962934b46c7569d04af2dc9638a38ae5812680b9d6c7ee42d770e/aiohttp-3.12.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e4eebfe470e22cc4b374d7e32c07e96d777a5c0fa51f3824de68e697da037ec", size = 1663943, upload-time = "2025-06-02T16:31:55.094Z" }, { url = "https://files.pythonhosted.org/packages/15/d5/971d1b277e6a3d5b679f0c9ba076c343a5125ea2eacc51c23ea7d875d43a/aiohttp-3.12.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:74ff39445f94923cf595e9e6dd602ecbe66b12364e2207e61342b8834417f8da", size = 1712217, upload-time = "2025-06-02T16:31:57.336Z" }, { url = "https://files.pythonhosted.org/packages/e1/9c/c21fd0ba87772f3d1d43cdbfcfd40fe29f37d36a5d73997a8a4d4d1485c3/aiohttp-3.12.7-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:77cb9dba16486ecfeac8076763600b9714941e0ff696e53a30e8d408d9a196ca", size = 1707375, upload-time = "2025-06-02T16:31:59.12Z" }, { url = "https://files.pythonhosted.org/packages/85/48/bb97ef3a694df852b70e6f5c1aaf3621a3a26b35f0a0d90481f3fdb1ce8b/aiohttp-3.12.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a7b3b9cbe83e3918a1918b0de274884f17b64224c1c9210a6fb0f7c10d246636", size = 1687561, upload-time = "2025-06-02T16:32:01.385Z" }, { url = "https://files.pythonhosted.org/packages/d5/75/0b85f30ba9eb1dbdb5d3a53d3a0db29990220f69187acb24d06903686c5d/aiohttp-3.12.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6055f53c70938498884e71ca966abe8e9e7558489e13a7e40b6384dee7230d1d", size = 1781163, upload-time = "2025-06-02T16:32:03.176Z" }, { url = "https://files.pythonhosted.org/packages/92/51/6350a4c485c7d2fb794101d46085c3830485ec1c37738d8af6c9c5ed8e1a/aiohttp-3.12.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:8493a42d5b2a736c6804239b985feebeea1c60f8fcb46a3607d6dce3c1a42b12", size = 1801624, upload-time = "2025-06-02T16:32:05.027Z" }, { url = "https://files.pythonhosted.org/packages/4f/dd/6a75eaaac93b5552090e42c38a576062028ce4af50f0b50ac550332d332c/aiohttp-3.12.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:372f2237cade45f563d973c2a913895f2699a892c0eb11c55c6880b6f0acf219", size = 1714679, upload-time = "2025-06-02T16:32:06.837Z" }, { url = "https://files.pythonhosted.org/packages/de/ad/0574964387d8eed7fcd0c2fe6ef20c4affe0b265c710938d5fffdb3776b5/aiohttp-3.12.7-cp311-cp311-win32.whl", hash = "sha256:41f686749a099b507563a5c0cb4fd77367b05448a2c1758784ad506a28e9e579", size = 424709, upload-time = "2025-06-02T16:32:08.671Z" }, { url = "https://files.pythonhosted.org/packages/4f/ab/6b82b43abb0990e4452aaef509cf1403ab50c04b5c090f92fb1b255fb319/aiohttp-3.12.7-cp311-cp311-win_amd64.whl", hash = "sha256:7a3691583470d4397aca70fbf8e0f0778b63a2c2a6a23263bdeeb68395972f29", size = 449100, upload-time = "2025-06-02T16:32:10.373Z" }, { url = "https://files.pythonhosted.org/packages/5d/65/0bd8ccbffa33ee69db9f5c43f3f62fb8b600b607388e9a8deab8962d0523/aiohttp-3.12.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9b9345918f5b5156a5712c37d1d331baf320df67547ea032a49a609b773c3606", size = 698263, upload-time = "2025-06-02T16:32:12.107Z" }, { url = "https://files.pythonhosted.org/packages/99/64/a48a8abc4e684fb447d1f7b61e7adcb19865b91e20b50595f49b2942fbb3/aiohttp-3.12.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3091b4883f405dbabeb9ea821a25dec16d03a51c3e0d2752fc3ab48b652bf196", size = 472877, upload-time = "2025-06-02T16:32:14.386Z" }, { url = "https://files.pythonhosted.org/packages/7d/e4/994bc56a7d7733e9cd1f45db8b656e78d51d7a61cefff8043ec4f7d4a23f/aiohttp-3.12.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:97fd97abd4cf199eff4041d0346a7dc68b60deab177f01de87283be513ffc3ab", size = 465716, upload-time = "2025-06-02T16:32:16.108Z" }, { url = "https://files.pythonhosted.org/packages/39/b0/bddc489288a0e3b05fa05387db9caebc38577204a17db0d5428abae524ba/aiohttp-3.12.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a5938973105cd5ff17176e8cb36bc19cac7c82ae7c58c0dbd7e023972d0c708", size = 1712513, upload-time = "2025-06-02T16:32:17.898Z" }, { url = "https://files.pythonhosted.org/packages/4d/4a/c06d3ce0dc5f96338cc8d18da57d74608585a3751234eeef5952e4f48ade/aiohttp-3.12.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e506ae5c4c05d1a1e87edd64b994cea2d49385d41d32e1c6be8764f31cf2245c", size = 1695167, upload-time = "2025-06-02T16:32:20.131Z" }, { url = "https://files.pythonhosted.org/packages/79/ec/e847fdfe2b1c1f1a2b0ba5343a9b2bd033a0545f8eaf1f7894a6614473ae/aiohttp-3.12.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b780b402e6361c4cfcec252580f5ecdd86cb68376520ac34748d3f8b262dd598", size = 1750261, upload-time = "2025-06-02T16:32:22.717Z" }, { url = "https://files.pythonhosted.org/packages/2c/5e/b832ff59737d99cc5ae51b737c52976d19990ccee922ba6fe811f615e7f9/aiohttp-3.12.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf981bbfb7ff2ebc1b3bfae49d2efe2c51ca1cf3d90867f47c310df65398e85e", size = 1796416, upload-time = "2025-06-02T16:32:25.15Z" }, { url = "https://files.pythonhosted.org/packages/e0/ff/51ae87efce9b53aafd384179f58923bf178f561897cf80054a440fdf8363/aiohttp-3.12.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94f98e0e5a49f89b252e115844f756c04fc8050f38252a32a3dd994ce8121f10", size = 1715855, upload-time = "2025-06-02T16:32:27.236Z" }, { url = "https://files.pythonhosted.org/packages/b1/54/5a77116498f84d2503f5588e687eccfa43a85aa2450bc195ee6e5bb75695/aiohttp-3.12.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:410e96cc6824fc4ced9703fb2ac2d06c6190d21fc6f5b588f62b1918628449c1", size = 1631656, upload-time = "2025-06-02T16:32:29.15Z" }, { url = "https://files.pythonhosted.org/packages/46/34/554220592f8ade7f3cabebfb9325e95078f842140f293ced3ab977fd13ec/aiohttp-3.12.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:43e93987fe9df4349db8deae7c391695538c35e4ba893133c7e823234f6e4537", size = 1692718, upload-time = "2025-06-02T16:32:31.295Z" }, { url = "https://files.pythonhosted.org/packages/ff/9d/ae7103bb8c73c3521e38ae8cde301ddc937024b1681ce134bb1ef01be7d0/aiohttp-3.12.7-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:cb3f3dcb59f3e16819a1c7d3fa32e7b87255b661c1e139a1b5940bde270704ab", size = 1714171, upload-time = "2025-06-02T16:32:33.767Z" }, { url = "https://files.pythonhosted.org/packages/5d/4d/9b8b8f362e36392939019340321f7efcc1807bb2c4cdea8eb1019d3398ff/aiohttp-3.12.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4a46fe4a4c66b2712059e48a8384eb93565fbe3251af4844860fed846ef4ca75", size = 1654822, upload-time = "2025-06-02T16:32:36.23Z" }, { url = "https://files.pythonhosted.org/packages/48/30/0ca82df423ee346206bc167852c825cd210c11d2f1fa0064a2a55d7f60d5/aiohttp-3.12.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:ad01793164661af70918490ef8efc2c09df7a3c686b6c84ca90a2d69cdbc3911", size = 1734385, upload-time = "2025-06-02T16:32:38.171Z" }, { url = "https://files.pythonhosted.org/packages/43/bd/96d12318c0f82ac8323bd4459ee26291ad220f688988077a21e538b0872c/aiohttp-3.12.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e85c6833be3f49cead2e7bc79080e5c18d6dab9af32226ab5a01dc20c523e7d9", size = 1762356, upload-time = "2025-06-02T16:32:40.142Z" }, { url = "https://files.pythonhosted.org/packages/6c/39/7a9b706bf42f293415584d60cf35e80d0558929ab70e72cb40b747f0dfc7/aiohttp-3.12.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3c9f52149d8249566e72c50c7985c2345521b3b78f84aa86f6f492cd50b14793", size = 1721970, upload-time = "2025-06-02T16:32:42.187Z" }, { url = "https://files.pythonhosted.org/packages/19/f2/8899367a52dec8100f43036e5a792cfdbae317bf3a80549da90290083ff4/aiohttp-3.12.7-cp312-cp312-win32.whl", hash = "sha256:0e1c33ac0f6a396bcefe9c1d52c9d38a051861885a5c102ca5c8298aba0108fa", size = 419443, upload-time = "2025-06-02T16:32:44.335Z" }, { url = "https://files.pythonhosted.org/packages/e8/34/ad5225b4edbcc23496537011d67ef1a147c03205c07340f4a50993b219b9/aiohttp-3.12.7-cp312-cp312-win_amd64.whl", hash = "sha256:b4aed5233a9d13e34e8624ecb798533aa2da97e7048cc69671b7a6d7a2efe7e8", size = 445544, upload-time = "2025-06-02T16:32:46.631Z" }, { url = "https://files.pythonhosted.org/packages/fb/a0/c6b01de500e6a115c185bd892d41fcad47b680cc3383c3a01f1f6ab44335/aiohttp-3.12.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:adbb2046600a60e37a54ea9b77b0ddef280029b0a853624a8e9b2b71a037c890", size = 692665, upload-time = "2025-06-02T16:32:48.962Z" }, { url = "https://files.pythonhosted.org/packages/c1/30/afc2b7c23fccdb1efd056bc6a9aa62077dee59448551631cb80ed3c893dd/aiohttp-3.12.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76392cbadc1ccc0a8c02098b74c0240d53c644b10a81e1addbc1666dce3cd62a", size = 470331, upload-time = "2025-06-02T16:32:50.89Z" }, { url = "https://files.pythonhosted.org/packages/35/03/61318657ba49899defd70dde622e85fa2fc69dcbafe20bc26ce10dbbcfe0/aiohttp-3.12.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6f04af3bf040dc8fd9b2bc0e465f5aca6fc5349fa08bd7f08142974a2ded21bf", size = 462635, upload-time = "2025-06-02T16:32:52.778Z" }, { url = "https://files.pythonhosted.org/packages/10/1e/20ff25b33d39a604094e6d0f9e32c110d63b48a0f8394fa33fd6228ea0dd/aiohttp-3.12.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b19763f88f058e9c605f79cde8a800660f7e259162b80982111cc631dfc54bf0", size = 1701455, upload-time = "2025-06-02T16:32:55.209Z" }, { url = "https://files.pythonhosted.org/packages/6a/37/43adcb8e2940b888a743acfa54e754b1932b5665a0728944928e8bda93a2/aiohttp-3.12.7-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6600550593c440ef29ca2a14b8a52ac91b9f494d85f75294409ec6ad5637476f", size = 1682720, upload-time = "2025-06-02T16:32:57.743Z" }, { url = "https://files.pythonhosted.org/packages/c5/b3/b4830455bcbac491904c0fbfc9e1cd70445f3ed745ba3b2b5e196964249e/aiohttp-3.12.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c7b83c829be3cddaf958dee8108e09b1502c215e95064d3045015298dbded54a", size = 1734788, upload-time = "2025-06-02T16:32:59.738Z" }, { url = "https://files.pythonhosted.org/packages/97/87/21eca23f8c3f2fcf96661029533596a520a44a47707040782762bc948588/aiohttp-3.12.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffa9928fd37061c8e35b85d3f1b4a256d0c3e8cbd421c1d8bd0ab45461b6a838", size = 1784163, upload-time = "2025-06-02T16:33:01.855Z" }, { url = "https://files.pythonhosted.org/packages/ce/2f/5692c1d0bce47c733beca21e30da28a9fa9b9013c777be5537b81924ef9a/aiohttp-3.12.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc8086515dd1016b67db9ccebb7159234226dba99fb6a895a0c9270b644cf525", size = 1706492, upload-time = "2025-06-02T16:33:03.951Z" }, { url = "https://files.pythonhosted.org/packages/a0/40/bb2ae33973c23cb7d96676c2c342d55a46e718906c267b05368b063420bb/aiohttp-3.12.7-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8c19b1de25703560fa64f998dfc3685040b52996056e048b3406c8e97dcfa1e3", size = 1620197, upload-time = "2025-06-02T16:33:06.69Z" }, { url = "https://files.pythonhosted.org/packages/5e/39/45d2ca30a6275445764cfefecebcc9ec41461a3b41c3beebff33ba080fe3/aiohttp-3.12.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6357abdc7a2cfb113274c4f4a7f086bdca36905924953bf7a9e3f6add3aec7c5", size = 1673219, upload-time = "2025-06-02T16:33:08.9Z" }, { url = "https://files.pythonhosted.org/packages/21/91/05864e93472dcc52e95cb33c808c212cb248069d11d730c1c726aefd42d5/aiohttp-3.12.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:29ff7876ff7e4a8029642334a81891cb5a842f1e405195c2946f697102756670", size = 1704882, upload-time = "2025-06-02T16:33:11.046Z" }, { url = "https://files.pythonhosted.org/packages/3c/90/a4585fa7b8603dd5c6778d4471245c50048c13b41f95e9e855d7ce1bd6f0/aiohttp-3.12.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5e7741c53d473204f89dd26f3b087a5883c742add8d6504d0d7d3ad3ff1cd1b7", size = 1647478, upload-time = "2025-06-02T16:33:13.473Z" }, { url = "https://files.pythonhosted.org/packages/8f/37/f2f30aceb3b6977033deab11f54728e46c990950e3206dfc91677219d3e3/aiohttp-3.12.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:38dc536059cc0624e22273905a1df74b231ac903d73af59ee6e6e3139f05a28b", size = 1723613, upload-time = "2025-06-02T16:33:15.883Z" }, { url = "https://files.pythonhosted.org/packages/29/92/8ef582e9c286cf285f1788fef10b95a8b9178ee68759071ff5ef3a7c2aa6/aiohttp-3.12.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:82a59cf086396a409d6d2350c122aada07f1f56bb529734994d37bcafc8cf101", size = 1757083, upload-time = "2025-06-02T16:33:18.553Z" }, { url = "https://files.pythonhosted.org/packages/6d/84/e0e010286781187e3bce69ac9e2b51d3264293a9295db5791ffa084aeaf9/aiohttp-3.12.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7cd6e299292ba085a3642cb4085b393f45bbca45c067182d15e33c2e3473283c", size = 1705975, upload-time = "2025-06-02T16:33:20.849Z" }, { url = "https://files.pythonhosted.org/packages/ff/6a/a956e2634f9c3af533a60b2c001a484edd52fea05572d144d5efbf8c313e/aiohttp-3.12.7-cp313-cp313-win32.whl", hash = "sha256:4acec2b5de65adc469837260be8408d5f53d4c8ae60631be868e9d7eb8563167", size = 418469, upload-time = "2025-06-02T16:33:23.566Z" }, { url = "https://files.pythonhosted.org/packages/86/7a/944963ccf6651dd593a00370423dd74fad745b439fc89502f81620cd93c9/aiohttp-3.12.7-cp313-cp313-win_amd64.whl", hash = "sha256:93317649d65cc895ba1fe5384353cb6c44638db39ebb55dabe3dade34a1b1177", size = 444406, upload-time = "2025-06-02T16:33:26.213Z" }, ] [[package]] name = "aiosignal" version = "1.3.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "frozenlist" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ba/b5/6d55e80f6d8a08ce22b982eafa278d823b541c925f11ee774b0b9c43473d/aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54", size = 19424, upload-time = "2024-12-13T17:10:40.86Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ec/6a/bc7e17a3e87a2985d3e8f4da4cd0f481060eb78fb08596c42be62c90a4d9/aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5", size = 7597, upload-time = "2024-12-13T17:10:38.469Z" }, ] [[package]] name = "anyio" version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "sniffio" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949, upload-time = "2025-03-17T00:02:54.77Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916, upload-time = "2025-03-17T00:02:52.713Z" }, ] [[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 = "backports-tarfile" version = "1.2.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/86/72/cd9b395f25e290e633655a100af28cb253e4393396264a98bd5f5951d50f/backports_tarfile-1.2.0.tar.gz", hash = "sha256:d75e02c268746e1b8144c278978b6e98e85de6ad16f8e4b0844a154557eca991", size = 86406, upload-time = "2024-05-28T17:01:54.731Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b9/fa/123043af240e49752f1c4bd24da5053b6bd00cad78c2be53c0d1e8b975bc/backports.tarfile-1.2.0-py3-none-any.whl", hash = "sha256:77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34", size = 30181, upload-time = "2024-05-28T17:01:53.112Z" }, ] [[package]] name = "black" version = "25.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "mypy-extensions" }, { name = "packaging" }, { name = "pathspec" }, { name = "platformdirs" }, ] sdist = { url = "https://files.pythonhosted.org/packages/94/49/26a7b0f3f35da4b5a65f081943b7bcd22d7002f5f0fb8098ec1ff21cb6ef/black-25.1.0.tar.gz", hash = "sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666", size = 649449, upload-time = "2025-01-29T04:15:40.373Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7e/4f/87f596aca05c3ce5b94b8663dbfe242a12843caaa82dd3f85f1ffdc3f177/black-25.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a39337598244de4bae26475f77dda852ea00a93bd4c728e09eacd827ec929df0", size = 1614372, upload-time = "2025-01-29T05:37:11.71Z" }, { url = "https://files.pythonhosted.org/packages/e7/d0/2c34c36190b741c59c901e56ab7f6e54dad8df05a6272a9747ecef7c6036/black-25.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96c1c7cd856bba8e20094e36e0f948718dc688dba4a9d78c3adde52b9e6c2299", size = 1442865, upload-time = "2025-01-29T05:37:14.309Z" }, { url = "https://files.pythonhosted.org/packages/21/d4/7518c72262468430ead45cf22bd86c883a6448b9eb43672765d69a8f1248/black-25.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bce2e264d59c91e52d8000d507eb20a9aca4a778731a08cfff7e5ac4a4bb7096", size = 1749699, upload-time = "2025-01-29T04:18:17.688Z" }, { url = "https://files.pythonhosted.org/packages/58/db/4f5beb989b547f79096e035c4981ceb36ac2b552d0ac5f2620e941501c99/black-25.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:172b1dbff09f86ce6f4eb8edf9dede08b1fce58ba194c87d7a4f1a5aa2f5b3c2", size = 1428028, upload-time = "2025-01-29T04:18:51.711Z" }, { url = "https://files.pythonhosted.org/packages/83/71/3fe4741df7adf015ad8dfa082dd36c94ca86bb21f25608eb247b4afb15b2/black-25.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4b60580e829091e6f9238c848ea6750efed72140b91b048770b64e74fe04908b", size = 1650988, upload-time = "2025-01-29T05:37:16.707Z" }, { url = "https://files.pythonhosted.org/packages/13/f3/89aac8a83d73937ccd39bbe8fc6ac8860c11cfa0af5b1c96d081facac844/black-25.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e2978f6df243b155ef5fa7e558a43037c3079093ed5d10fd84c43900f2d8ecc", size = 1453985, upload-time = "2025-01-29T05:37:18.273Z" }, { url = "https://files.pythonhosted.org/packages/6f/22/b99efca33f1f3a1d2552c714b1e1b5ae92efac6c43e790ad539a163d1754/black-25.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b48735872ec535027d979e8dcb20bf4f70b5ac75a8ea99f127c106a7d7aba9f", size = 1783816, upload-time = "2025-01-29T04:18:33.823Z" }, { url = "https://files.pythonhosted.org/packages/18/7e/a27c3ad3822b6f2e0e00d63d58ff6299a99a5b3aee69fa77cd4b0076b261/black-25.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:ea0213189960bda9cf99be5b8c8ce66bb054af5e9e861249cd23471bd7b0b3ba", size = 1440860, upload-time = "2025-01-29T04:19:12.944Z" }, { url = "https://files.pythonhosted.org/packages/98/87/0edf98916640efa5d0696e1abb0a8357b52e69e82322628f25bf14d263d1/black-25.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f", size = 1650673, upload-time = "2025-01-29T05:37:20.574Z" }, { url = "https://files.pythonhosted.org/packages/52/e5/f7bf17207cf87fa6e9b676576749c6b6ed0d70f179a3d812c997870291c3/black-25.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3", size = 1453190, upload-time = "2025-01-29T05:37:22.106Z" }, { url = "https://files.pythonhosted.org/packages/e3/ee/adda3d46d4a9120772fae6de454c8495603c37c4c3b9c60f25b1ab6401fe/black-25.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171", size = 1782926, upload-time = "2025-01-29T04:18:58.564Z" }, { url = "https://files.pythonhosted.org/packages/cc/64/94eb5f45dcb997d2082f097a3944cfc7fe87e071907f677e80788a2d7b7a/black-25.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:a22f402b410566e2d1c950708c77ebf5ebd5d0d88a6a2e87c86d9fb48afa0d18", size = 1442613, upload-time = "2025-01-29T04:19:27.63Z" }, { url = "https://files.pythonhosted.org/packages/09/71/54e999902aed72baf26bca0d50781b01838251a462612966e9fc4891eadd/black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717", size = 207646, upload-time = "2025-01-29T04:15:38.082Z" }, ] [[package]] name = "cachetools" version = "6.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/c0/b0/f539a1ddff36644c28a61490056e5bae43bd7386d9f9c69beae2d7e7d6d1/cachetools-6.0.0.tar.gz", hash = "sha256:f225782b84438f828328fc2ad74346522f27e5b1440f4e9fd18b20ebfd1aa2cf", size = 30160, upload-time = "2025-05-23T20:01:13.076Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/6a/c3/8bb087c903c95a570015ce84e0c23ae1d79f528c349cbc141b5c4e250293/cachetools-6.0.0-py3-none-any.whl", hash = "sha256:82e73ba88f7b30228b5507dce1a1f878498fc669d972aef2dde4f3a3c24f103e", size = 10964, upload-time = "2025-05-23T20:01:11.323Z" }, ] [[package]] name = "certifi" version = "2025.4.26" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" }, ] [[package]] name = "cffi" version = "1.17.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pycparser" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259, upload-time = "2024-09-04T20:43:56.123Z" }, { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200, upload-time = "2024-09-04T20:43:57.891Z" }, { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235, upload-time = "2024-09-04T20:44:00.18Z" }, { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721, upload-time = "2024-09-04T20:44:01.585Z" }, { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242, upload-time = "2024-09-04T20:44:03.467Z" }, { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999, upload-time = "2024-09-04T20:44:05.023Z" }, { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242, upload-time = "2024-09-04T20:44:06.444Z" }, { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604, upload-time = "2024-09-04T20:44:08.206Z" }, { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803, upload-time = "2024-09-04T20:44:15.231Z" }, { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850, upload-time = "2024-09-04T20:44:17.188Z" }, { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729, upload-time = "2024-09-04T20:44:18.688Z" }, { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256, upload-time = "2024-09-04T20:44:20.248Z" }, { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424, upload-time = "2024-09-04T20:44:21.673Z" }, { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568, upload-time = "2024-09-04T20:44:23.245Z" }, { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736, upload-time = "2024-09-04T20:44:24.757Z" }, { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload-time = "2024-09-04T20:44:32.01Z" }, { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload-time = "2024-09-04T20:44:33.606Z" }, { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload-time = "2024-09-04T20:44:35.191Z" }, { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload-time = "2024-09-04T20:44:36.743Z" }, { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload-time = "2024-09-04T20:44:38.492Z" }, { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload-time = "2024-09-04T20:44:40.046Z" }, { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload-time = "2024-09-04T20:44:41.616Z" }, ] [[package]] name = "cfgv" version = "3.4.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114, upload-time = "2023-08-12T20:38:17.776Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249, upload-time = "2023-08-12T20:38:16.269Z" }, ] [[package]] name = "chardet" version = "5.2.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/f7b6ab21ec75897ed80c17d79b15951a719226b9fababf1e40ea74d69079/chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7", size = 2069618, upload-time = "2023-08-01T19:23:02.662Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970", size = 199385, upload-time = "2023-08-01T19:23:00.661Z" }, ] [[package]] name = "charset-normalizer" version = "3.4.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e4/33/89c2ced2b67d1c2a61c19c6751aa8902d46ce3dacb23600a283619f5a12d/charset_normalizer-3.4.2.tar.gz", hash = "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63", size = 126367, upload-time = "2025-05-02T08:34:42.01Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/05/85/4c40d00dcc6284a1c1ad5de5e0996b06f39d8232f1031cd23c2f5c07ee86/charset_normalizer-3.4.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:be1e352acbe3c78727a16a455126d9ff83ea2dfdcbc83148d2982305a04714c2", size = 198794, upload-time = "2025-05-02T08:32:11.945Z" }, { url = "https://files.pythonhosted.org/packages/41/d9/7a6c0b9db952598e97e93cbdfcb91bacd89b9b88c7c983250a77c008703c/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa88ca0b1932e93f2d961bf3addbb2db902198dca337d88c89e1559e066e7645", size = 142846, upload-time = "2025-05-02T08:32:13.946Z" }, { url = "https://files.pythonhosted.org/packages/66/82/a37989cda2ace7e37f36c1a8ed16c58cf48965a79c2142713244bf945c89/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d524ba3f1581b35c03cb42beebab4a13e6cdad7b36246bd22541fa585a56cccd", size = 153350, upload-time = "2025-05-02T08:32:15.873Z" }, { url = "https://files.pythonhosted.org/packages/df/68/a576b31b694d07b53807269d05ec3f6f1093e9545e8607121995ba7a8313/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28a1005facc94196e1fb3e82a3d442a9d9110b8434fc1ded7a24a2983c9888d8", size = 145657, upload-time = "2025-05-02T08:32:17.283Z" }, { url = "https://files.pythonhosted.org/packages/92/9b/ad67f03d74554bed3aefd56fe836e1623a50780f7c998d00ca128924a499/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f", size = 147260, upload-time = "2025-05-02T08:32:18.807Z" }, { url = "https://files.pythonhosted.org/packages/a6/e6/8aebae25e328160b20e31a7e9929b1578bbdc7f42e66f46595a432f8539e/charset_normalizer-3.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f5d9ed7f254402c9e7d35d2f5972c9bbea9040e99cd2861bd77dc68263277c7", size = 149164, upload-time = "2025-05-02T08:32:20.333Z" }, { url = "https://files.pythonhosted.org/packages/8b/f2/b3c2f07dbcc248805f10e67a0262c93308cfa149a4cd3d1fe01f593e5fd2/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:efd387a49825780ff861998cd959767800d54f8308936b21025326de4b5a42b9", size = 144571, upload-time = "2025-05-02T08:32:21.86Z" }, { url = "https://files.pythonhosted.org/packages/60/5b/c3f3a94bc345bc211622ea59b4bed9ae63c00920e2e8f11824aa5708e8b7/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f0aa37f3c979cf2546b73e8222bbfa3dc07a641585340179d768068e3455e544", size = 151952, upload-time = "2025-05-02T08:32:23.434Z" }, { url = "https://files.pythonhosted.org/packages/e2/4d/ff460c8b474122334c2fa394a3f99a04cf11c646da895f81402ae54f5c42/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e70e990b2137b29dc5564715de1e12701815dacc1d056308e2b17e9095372a82", size = 155959, upload-time = "2025-05-02T08:32:24.993Z" }, { url = "https://files.pythonhosted.org/packages/a2/2b/b964c6a2fda88611a1fe3d4c400d39c66a42d6c169c924818c848f922415/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0c8c57f84ccfc871a48a47321cfa49ae1df56cd1d965a09abe84066f6853b9c0", size = 153030, upload-time = "2025-05-02T08:32:26.435Z" }, { url = "https://files.pythonhosted.org/packages/59/2e/d3b9811db26a5ebf444bc0fa4f4be5aa6d76fc6e1c0fd537b16c14e849b6/charset_normalizer-3.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6b66f92b17849b85cad91259efc341dce9c1af48e2173bf38a85c6329f1033e5", size = 148015, upload-time = "2025-05-02T08:32:28.376Z" }, { url = "https://files.pythonhosted.org/packages/90/07/c5fd7c11eafd561bb51220d600a788f1c8d77c5eef37ee49454cc5c35575/charset_normalizer-3.4.2-cp311-cp311-win32.whl", hash = "sha256:daac4765328a919a805fa5e2720f3e94767abd632ae410a9062dff5412bae65a", size = 98106, upload-time = "2025-05-02T08:32:30.281Z" }, { url = "https://files.pythonhosted.org/packages/a8/05/5e33dbef7e2f773d672b6d79f10ec633d4a71cd96db6673625838a4fd532/charset_normalizer-3.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:e53efc7c7cee4c1e70661e2e112ca46a575f90ed9ae3fef200f2a25e954f4b28", size = 105402, upload-time = "2025-05-02T08:32:32.191Z" }, { url = "https://files.pythonhosted.org/packages/d7/a4/37f4d6035c89cac7930395a35cc0f1b872e652eaafb76a6075943754f095/charset_normalizer-3.4.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7", size = 199936, upload-time = "2025-05-02T08:32:33.712Z" }, { url = "https://files.pythonhosted.org/packages/ee/8a/1a5e33b73e0d9287274f899d967907cd0bf9c343e651755d9307e0dbf2b3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3", size = 143790, upload-time = "2025-05-02T08:32:35.768Z" }, { url = "https://files.pythonhosted.org/packages/66/52/59521f1d8e6ab1482164fa21409c5ef44da3e9f653c13ba71becdd98dec3/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a", size = 153924, upload-time = "2025-05-02T08:32:37.284Z" }, { url = "https://files.pythonhosted.org/packages/86/2d/fb55fdf41964ec782febbf33cb64be480a6b8f16ded2dbe8db27a405c09f/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214", size = 146626, upload-time = "2025-05-02T08:32:38.803Z" }, { url = "https://files.pythonhosted.org/packages/8c/73/6ede2ec59bce19b3edf4209d70004253ec5f4e319f9a2e3f2f15601ed5f7/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a", size = 148567, upload-time = "2025-05-02T08:32:40.251Z" }, { url = "https://files.pythonhosted.org/packages/09/14/957d03c6dc343c04904530b6bef4e5efae5ec7d7990a7cbb868e4595ee30/charset_normalizer-3.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd", size = 150957, upload-time = "2025-05-02T08:32:41.705Z" }, { url = "https://files.pythonhosted.org/packages/0d/c8/8174d0e5c10ccebdcb1b53cc959591c4c722a3ad92461a273e86b9f5a302/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981", size = 145408, upload-time = "2025-05-02T08:32:43.709Z" }, { url = "https://files.pythonhosted.org/packages/58/aa/8904b84bc8084ac19dc52feb4f5952c6df03ffb460a887b42615ee1382e8/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c", size = 153399, upload-time = "2025-05-02T08:32:46.197Z" }, { url = "https://files.pythonhosted.org/packages/c2/26/89ee1f0e264d201cb65cf054aca6038c03b1a0c6b4ae998070392a3ce605/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b", size = 156815, upload-time = "2025-05-02T08:32:48.105Z" }, { url = "https://files.pythonhosted.org/packages/fd/07/68e95b4b345bad3dbbd3a8681737b4338ff2c9df29856a6d6d23ac4c73cb/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d", size = 154537, upload-time = "2025-05-02T08:32:49.719Z" }, { url = "https://files.pythonhosted.org/packages/77/1a/5eefc0ce04affb98af07bc05f3bac9094513c0e23b0562d64af46a06aae4/charset_normalizer-3.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f", size = 149565, upload-time = "2025-05-02T08:32:51.404Z" }, { url = "https://files.pythonhosted.org/packages/37/a0/2410e5e6032a174c95e0806b1a6585eb21e12f445ebe239fac441995226a/charset_normalizer-3.4.2-cp312-cp312-win32.whl", hash = "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c", size = 98357, upload-time = "2025-05-02T08:32:53.079Z" }, { url = "https://files.pythonhosted.org/packages/6c/4f/c02d5c493967af3eda9c771ad4d2bbc8df6f99ddbeb37ceea6e8716a32bc/charset_normalizer-3.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e", size = 105776, upload-time = "2025-05-02T08:32:54.573Z" }, { url = "https://files.pythonhosted.org/packages/ea/12/a93df3366ed32db1d907d7593a94f1fe6293903e3e92967bebd6950ed12c/charset_normalizer-3.4.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0", size = 199622, upload-time = "2025-05-02T08:32:56.363Z" }, { url = "https://files.pythonhosted.org/packages/04/93/bf204e6f344c39d9937d3c13c8cd5bbfc266472e51fc8c07cb7f64fcd2de/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf", size = 143435, upload-time = "2025-05-02T08:32:58.551Z" }, { url = "https://files.pythonhosted.org/packages/22/2a/ea8a2095b0bafa6c5b5a55ffdc2f924455233ee7b91c69b7edfcc9e02284/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e", size = 153653, upload-time = "2025-05-02T08:33:00.342Z" }, { url = "https://files.pythonhosted.org/packages/b6/57/1b090ff183d13cef485dfbe272e2fe57622a76694061353c59da52c9a659/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1", size = 146231, upload-time = "2025-05-02T08:33:02.081Z" }, { url = "https://files.pythonhosted.org/packages/e2/28/ffc026b26f441fc67bd21ab7f03b313ab3fe46714a14b516f931abe1a2d8/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c", size = 148243, upload-time = "2025-05-02T08:33:04.063Z" }, { url = "https://files.pythonhosted.org/packages/c0/0f/9abe9bd191629c33e69e47c6ef45ef99773320e9ad8e9cb08b8ab4a8d4cb/charset_normalizer-3.4.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691", size = 150442, upload-time = "2025-05-02T08:33:06.418Z" }, { url = "https://files.pythonhosted.org/packages/67/7c/a123bbcedca91d5916c056407f89a7f5e8fdfce12ba825d7d6b9954a1a3c/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0", size = 145147, upload-time = "2025-05-02T08:33:08.183Z" }, { url = "https://files.pythonhosted.org/packages/ec/fe/1ac556fa4899d967b83e9893788e86b6af4d83e4726511eaaad035e36595/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b", size = 153057, upload-time = "2025-05-02T08:33:09.986Z" }, { url = "https://files.pythonhosted.org/packages/2b/ff/acfc0b0a70b19e3e54febdd5301a98b72fa07635e56f24f60502e954c461/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff", size = 156454, upload-time = "2025-05-02T08:33:11.814Z" }, { url = "https://files.pythonhosted.org/packages/92/08/95b458ce9c740d0645feb0e96cea1f5ec946ea9c580a94adfe0b617f3573/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b", size = 154174, upload-time = "2025-05-02T08:33:13.707Z" }, { url = "https://files.pythonhosted.org/packages/78/be/8392efc43487ac051eee6c36d5fbd63032d78f7728cb37aebcc98191f1ff/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148", size = 149166, upload-time = "2025-05-02T08:33:15.458Z" }, { url = "https://files.pythonhosted.org/packages/44/96/392abd49b094d30b91d9fbda6a69519e95802250b777841cf3bda8fe136c/charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7", size = 98064, upload-time = "2025-05-02T08:33:17.06Z" }, { url = "https://files.pythonhosted.org/packages/e9/b0/0200da600134e001d91851ddc797809e2fe0ea72de90e09bec5a2fbdaccb/charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980", size = 105641, upload-time = "2025-05-02T08:33:18.753Z" }, { url = "https://files.pythonhosted.org/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626, upload-time = "2025-05-02T08:34:40.053Z" }, ] [[package]] name = "click" version = "8.2.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "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 = "codespell" version = "2.4.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/15/e0/709453393c0ea77d007d907dd436b3ee262e28b30995ea1aa36c6ffbccaf/codespell-2.4.1.tar.gz", hash = "sha256:299fcdcb09d23e81e35a671bbe746d5ad7e8385972e65dbb833a2eaac33c01e5", size = 344740, upload-time = "2025-01-28T18:52:39.411Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/20/01/b394922252051e97aab231d416c86da3d8a6d781eeadcdca1082867de64e/codespell-2.4.1-py3-none-any.whl", hash = "sha256:3dadafa67df7e4a3dbf51e0d7315061b80d265f9552ebd699b3dd6834b47e425", size = 344501, upload-time = "2025-01-28T18:52:37.057Z" }, ] [[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 = "coverage" version = "7.8.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ba/07/998afa4a0ecdf9b1981ae05415dad2d4e7716e1b1f00abbd91691ac09ac9/coverage-7.8.2.tar.gz", hash = "sha256:a886d531373a1f6ff9fad2a2ba4a045b68467b779ae729ee0b3b10ac20033b27", size = 812759, upload-time = "2025-05-23T11:39:57.856Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/6a/4d/1ff618ee9f134d0de5cc1661582c21a65e06823f41caf801aadf18811a8e/coverage-7.8.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b99058eef42e6a8dcd135afb068b3d53aff3921ce699e127602efff9956457a9", size = 211692, upload-time = "2025-05-23T11:38:08.485Z" }, { url = "https://files.pythonhosted.org/packages/96/fa/c3c1b476de96f2bc7a8ca01a9f1fcb51c01c6b60a9d2c3e66194b2bdb4af/coverage-7.8.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5feb7f2c3e6ea94d3b877def0270dff0947b8d8c04cfa34a17be0a4dc1836879", size = 212115, upload-time = "2025-05-23T11:38:09.989Z" }, { url = "https://files.pythonhosted.org/packages/f7/c2/5414c5a1b286c0f3881ae5adb49be1854ac5b7e99011501f81c8c1453065/coverage-7.8.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:670a13249b957bb9050fab12d86acef7bf8f6a879b9d1a883799276e0d4c674a", size = 244740, upload-time = "2025-05-23T11:38:11.947Z" }, { url = "https://files.pythonhosted.org/packages/cd/46/1ae01912dfb06a642ef3dd9cf38ed4996fda8fe884dab8952da616f81a2b/coverage-7.8.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bdc8bf760459a4a4187b452213e04d039990211f98644c7292adf1e471162b5", size = 242429, upload-time = "2025-05-23T11:38:13.955Z" }, { url = "https://files.pythonhosted.org/packages/06/58/38c676aec594bfe2a87c7683942e5a30224791d8df99bcc8439fde140377/coverage-7.8.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07a989c867986c2a75f158f03fdb413128aad29aca9d4dbce5fc755672d96f11", size = 244218, upload-time = "2025-05-23T11:38:15.631Z" }, { url = "https://files.pythonhosted.org/packages/80/0c/95b1023e881ce45006d9abc250f76c6cdab7134a1c182d9713878dfefcb2/coverage-7.8.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2db10dedeb619a771ef0e2949ccba7b75e33905de959c2643a4607bef2f3fb3a", size = 243865, upload-time = "2025-05-23T11:38:17.622Z" }, { url = "https://files.pythonhosted.org/packages/57/37/0ae95989285a39e0839c959fe854a3ae46c06610439350d1ab860bf020ac/coverage-7.8.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e6ea7dba4e92926b7b5f0990634b78ea02f208d04af520c73a7c876d5a8d36cb", size = 242038, upload-time = "2025-05-23T11:38:19.966Z" }, { url = "https://files.pythonhosted.org/packages/4d/82/40e55f7c0eb5e97cc62cbd9d0746fd24e8caf57be5a408b87529416e0c70/coverage-7.8.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ef2f22795a7aca99fc3c84393a55a53dd18ab8c93fb431004e4d8f0774150f54", size = 242567, upload-time = "2025-05-23T11:38:21.912Z" }, { url = "https://files.pythonhosted.org/packages/f9/35/66a51adc273433a253989f0d9cc7aa6bcdb4855382cf0858200afe578861/coverage-7.8.2-cp311-cp311-win32.whl", hash = "sha256:641988828bc18a6368fe72355df5f1703e44411adbe49bba5644b941ce6f2e3a", size = 214194, upload-time = "2025-05-23T11:38:23.571Z" }, { url = "https://files.pythonhosted.org/packages/f6/8f/a543121f9f5f150eae092b08428cb4e6b6d2d134152c3357b77659d2a605/coverage-7.8.2-cp311-cp311-win_amd64.whl", hash = "sha256:8ab4a51cb39dc1933ba627e0875046d150e88478dbe22ce145a68393e9652975", size = 215109, upload-time = "2025-05-23T11:38:25.137Z" }, { url = "https://files.pythonhosted.org/packages/77/65/6cc84b68d4f35186463cd7ab1da1169e9abb59870c0f6a57ea6aba95f861/coverage-7.8.2-cp311-cp311-win_arm64.whl", hash = "sha256:8966a821e2083c74d88cca5b7dcccc0a3a888a596a04c0b9668a891de3a0cc53", size = 213521, upload-time = "2025-05-23T11:38:27.123Z" }, { url = "https://files.pythonhosted.org/packages/8d/2a/1da1ada2e3044fcd4a3254fb3576e160b8fe5b36d705c8a31f793423f763/coverage-7.8.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e2f6fe3654468d061942591aef56686131335b7a8325684eda85dacdf311356c", size = 211876, upload-time = "2025-05-23T11:38:29.01Z" }, { url = "https://files.pythonhosted.org/packages/70/e9/3d715ffd5b6b17a8be80cd14a8917a002530a99943cc1939ad5bb2aa74b9/coverage-7.8.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76090fab50610798cc05241bf83b603477c40ee87acd358b66196ab0ca44ffa1", size = 212130, upload-time = "2025-05-23T11:38:30.675Z" }, { url = "https://files.pythonhosted.org/packages/a0/02/fdce62bb3c21649abfd91fbdcf041fb99be0d728ff00f3f9d54d97ed683e/coverage-7.8.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bd0a0a5054be160777a7920b731a0570284db5142abaaf81bcbb282b8d99279", size = 246176, upload-time = "2025-05-23T11:38:32.395Z" }, { url = "https://files.pythonhosted.org/packages/a7/52/decbbed61e03b6ffe85cd0fea360a5e04a5a98a7423f292aae62423b8557/coverage-7.8.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da23ce9a3d356d0affe9c7036030b5c8f14556bd970c9b224f9c8205505e3b99", size = 243068, upload-time = "2025-05-23T11:38:33.989Z" }, { url = "https://files.pythonhosted.org/packages/38/6c/d0e9c0cce18faef79a52778219a3c6ee8e336437da8eddd4ab3dbd8fadff/coverage-7.8.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9392773cffeb8d7e042a7b15b82a414011e9d2b5fdbbd3f7e6a6b17d5e21b20", size = 245328, upload-time = "2025-05-23T11:38:35.568Z" }, { url = "https://files.pythonhosted.org/packages/f0/70/f703b553a2f6b6c70568c7e398ed0789d47f953d67fbba36a327714a7bca/coverage-7.8.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:876cbfd0b09ce09d81585d266c07a32657beb3eaec896f39484b631555be0fe2", size = 245099, upload-time = "2025-05-23T11:38:37.627Z" }, { url = "https://files.pythonhosted.org/packages/ec/fb/4cbb370dedae78460c3aacbdad9d249e853f3bc4ce5ff0e02b1983d03044/coverage-7.8.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3da9b771c98977a13fbc3830f6caa85cae6c9c83911d24cb2d218e9394259c57", size = 243314, upload-time = "2025-05-23T11:38:39.238Z" }, { url = "https://files.pythonhosted.org/packages/39/9f/1afbb2cb9c8699b8bc38afdce00a3b4644904e6a38c7bf9005386c9305ec/coverage-7.8.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a990f6510b3292686713bfef26d0049cd63b9c7bb17e0864f133cbfd2e6167f", size = 244489, upload-time = "2025-05-23T11:38:40.845Z" }, { url = "https://files.pythonhosted.org/packages/79/fa/f3e7ec7d220bff14aba7a4786ae47043770cbdceeea1803083059c878837/coverage-7.8.2-cp312-cp312-win32.whl", hash = "sha256:bf8111cddd0f2b54d34e96613e7fbdd59a673f0cf5574b61134ae75b6f5a33b8", size = 214366, upload-time = "2025-05-23T11:38:43.551Z" }, { url = "https://files.pythonhosted.org/packages/54/aa/9cbeade19b7e8e853e7ffc261df885d66bf3a782c71cba06c17df271f9e6/coverage-7.8.2-cp312-cp312-win_amd64.whl", hash = "sha256:86a323a275e9e44cdf228af9b71c5030861d4d2610886ab920d9945672a81223", size = 215165, upload-time = "2025-05-23T11:38:45.148Z" }, { url = "https://files.pythonhosted.org/packages/c4/73/e2528bf1237d2448f882bbebaec5c3500ef07301816c5c63464b9da4d88a/coverage-7.8.2-cp312-cp312-win_arm64.whl", hash = "sha256:820157de3a589e992689ffcda8639fbabb313b323d26388d02e154164c57b07f", size = 213548, upload-time = "2025-05-23T11:38:46.74Z" }, { url = "https://files.pythonhosted.org/packages/1a/93/eb6400a745ad3b265bac36e8077fdffcf0268bdbbb6c02b7220b624c9b31/coverage-7.8.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ea561010914ec1c26ab4188aef8b1567272ef6de096312716f90e5baa79ef8ca", size = 211898, upload-time = "2025-05-23T11:38:49.066Z" }, { url = "https://files.pythonhosted.org/packages/1b/7c/bdbf113f92683024406a1cd226a199e4200a2001fc85d6a6e7e299e60253/coverage-7.8.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cb86337a4fcdd0e598ff2caeb513ac604d2f3da6d53df2c8e368e07ee38e277d", size = 212171, upload-time = "2025-05-23T11:38:51.207Z" }, { url = "https://files.pythonhosted.org/packages/91/22/594513f9541a6b88eb0dba4d5da7d71596dadef6b17a12dc2c0e859818a9/coverage-7.8.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26a4636ddb666971345541b59899e969f3b301143dd86b0ddbb570bd591f1e85", size = 245564, upload-time = "2025-05-23T11:38:52.857Z" }, { url = "https://files.pythonhosted.org/packages/1f/f4/2860fd6abeebd9f2efcfe0fd376226938f22afc80c1943f363cd3c28421f/coverage-7.8.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5040536cf9b13fb033f76bcb5e1e5cb3b57c4807fef37db9e0ed129c6a094257", size = 242719, upload-time = "2025-05-23T11:38:54.529Z" }, { url = "https://files.pythonhosted.org/packages/89/60/f5f50f61b6332451520e6cdc2401700c48310c64bc2dd34027a47d6ab4ca/coverage-7.8.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc67994df9bcd7e0150a47ef41278b9e0a0ea187caba72414b71dc590b99a108", size = 244634, upload-time = "2025-05-23T11:38:57.326Z" }, { url = "https://files.pythonhosted.org/packages/3b/70/7f4e919039ab7d944276c446b603eea84da29ebcf20984fb1fdf6e602028/coverage-7.8.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6e6c86888fd076d9e0fe848af0a2142bf606044dc5ceee0aa9eddb56e26895a0", size = 244824, upload-time = "2025-05-23T11:38:59.421Z" }, { url = "https://files.pythonhosted.org/packages/26/45/36297a4c0cea4de2b2c442fe32f60c3991056c59cdc3cdd5346fbb995c97/coverage-7.8.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:684ca9f58119b8e26bef860db33524ae0365601492e86ba0b71d513f525e7050", size = 242872, upload-time = "2025-05-23T11:39:01.049Z" }, { url = "https://files.pythonhosted.org/packages/a4/71/e041f1b9420f7b786b1367fa2a375703889ef376e0d48de9f5723fb35f11/coverage-7.8.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8165584ddedb49204c4e18da083913bdf6a982bfb558632a79bdaadcdafd0d48", size = 244179, upload-time = "2025-05-23T11:39:02.709Z" }, { url = "https://files.pythonhosted.org/packages/bd/db/3c2bf49bdc9de76acf2491fc03130c4ffc51469ce2f6889d2640eb563d77/coverage-7.8.2-cp313-cp313-win32.whl", hash = "sha256:34759ee2c65362163699cc917bdb2a54114dd06d19bab860725f94ef45a3d9b7", size = 214393, upload-time = "2025-05-23T11:39:05.457Z" }, { url = "https://files.pythonhosted.org/packages/c6/dc/947e75d47ebbb4b02d8babb1fad4ad381410d5bc9da7cfca80b7565ef401/coverage-7.8.2-cp313-cp313-win_amd64.whl", hash = "sha256:2f9bc608fbafaee40eb60a9a53dbfb90f53cc66d3d32c2849dc27cf5638a21e3", size = 215194, upload-time = "2025-05-23T11:39:07.171Z" }, { url = "https://files.pythonhosted.org/packages/90/31/a980f7df8a37eaf0dc60f932507fda9656b3a03f0abf188474a0ea188d6d/coverage-7.8.2-cp313-cp313-win_arm64.whl", hash = "sha256:9fe449ee461a3b0c7105690419d0b0aba1232f4ff6d120a9e241e58a556733f7", size = 213580, upload-time = "2025-05-23T11:39:08.862Z" }, { url = "https://files.pythonhosted.org/packages/8a/6a/25a37dd90f6c95f59355629417ebcb74e1c34e38bb1eddf6ca9b38b0fc53/coverage-7.8.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8369a7c8ef66bded2b6484053749ff220dbf83cba84f3398c84c51a6f748a008", size = 212734, upload-time = "2025-05-23T11:39:11.109Z" }, { url = "https://files.pythonhosted.org/packages/36/8b/3a728b3118988725f40950931abb09cd7f43b3c740f4640a59f1db60e372/coverage-7.8.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:159b81df53a5fcbc7d45dae3adad554fdbde9829a994e15227b3f9d816d00b36", size = 212959, upload-time = "2025-05-23T11:39:12.751Z" }, { url = "https://files.pythonhosted.org/packages/53/3c/212d94e6add3a3c3f412d664aee452045ca17a066def8b9421673e9482c4/coverage-7.8.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6fcbbd35a96192d042c691c9e0c49ef54bd7ed865846a3c9d624c30bb67ce46", size = 257024, upload-time = "2025-05-23T11:39:15.569Z" }, { url = "https://files.pythonhosted.org/packages/a4/40/afc03f0883b1e51bbe804707aae62e29c4e8c8bbc365c75e3e4ddeee9ead/coverage-7.8.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05364b9cc82f138cc86128dc4e2e1251c2981a2218bfcd556fe6b0fbaa3501be", size = 252867, upload-time = "2025-05-23T11:39:17.64Z" }, { url = "https://files.pythonhosted.org/packages/18/a2/3699190e927b9439c6ded4998941a3c1d6fa99e14cb28d8536729537e307/coverage-7.8.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46d532db4e5ff3979ce47d18e2fe8ecad283eeb7367726da0e5ef88e4fe64740", size = 255096, upload-time = "2025-05-23T11:39:19.328Z" }, { url = "https://files.pythonhosted.org/packages/b4/06/16e3598b9466456b718eb3e789457d1a5b8bfb22e23b6e8bbc307df5daf0/coverage-7.8.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4000a31c34932e7e4fa0381a3d6deb43dc0c8f458e3e7ea6502e6238e10be625", size = 256276, upload-time = "2025-05-23T11:39:21.077Z" }, { url = "https://files.pythonhosted.org/packages/a7/d5/4b5a120d5d0223050a53d2783c049c311eea1709fa9de12d1c358e18b707/coverage-7.8.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:43ff5033d657cd51f83015c3b7a443287250dc14e69910577c3e03bd2e06f27b", size = 254478, upload-time = "2025-05-23T11:39:22.838Z" }, { url = "https://files.pythonhosted.org/packages/ba/85/f9ecdb910ecdb282b121bfcaa32fa8ee8cbd7699f83330ee13ff9bbf1a85/coverage-7.8.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:94316e13f0981cbbba132c1f9f365cac1d26716aaac130866ca812006f662199", size = 255255, upload-time = "2025-05-23T11:39:24.644Z" }, { url = "https://files.pythonhosted.org/packages/50/63/2d624ac7d7ccd4ebbd3c6a9eba9d7fc4491a1226071360d59dd84928ccb2/coverage-7.8.2-cp313-cp313t-win32.whl", hash = "sha256:3f5673888d3676d0a745c3d0e16da338c5eea300cb1f4ada9c872981265e76d8", size = 215109, upload-time = "2025-05-23T11:39:26.722Z" }, { url = "https://files.pythonhosted.org/packages/22/5e/7053b71462e970e869111c1853afd642212568a350eba796deefdfbd0770/coverage-7.8.2-cp313-cp313t-win_amd64.whl", hash = "sha256:2c08b05ee8d7861e45dc5a2cc4195c8c66dca5ac613144eb6ebeaff2d502e73d", size = 216268, upload-time = "2025-05-23T11:39:28.429Z" }, { url = "https://files.pythonhosted.org/packages/07/69/afa41aa34147655543dbe96994f8a246daf94b361ccf5edfd5df62ce066a/coverage-7.8.2-cp313-cp313t-win_arm64.whl", hash = "sha256:1e1448bb72b387755e1ff3ef1268a06617afd94188164960dba8d0245a46004b", size = 214071, upload-time = "2025-05-23T11:39:30.55Z" }, { url = "https://files.pythonhosted.org/packages/69/2f/572b29496d8234e4a7773200dd835a0d32d9e171f2d974f3fe04a9dbc271/coverage-7.8.2-pp39.pp310.pp311-none-any.whl", hash = "sha256:ec455eedf3ba0bbdf8f5a570012617eb305c63cb9f03428d39bf544cb2b94837", size = 203636, upload-time = "2025-05-23T11:39:52.002Z" }, { url = "https://files.pythonhosted.org/packages/a0/1a/0b9c32220ad694d66062f571cc5cedfa9997b64a591e8a500bb63de1bd40/coverage-7.8.2-py3-none-any.whl", hash = "sha256:726f32ee3713f7359696331a18daf0c3b3a70bb0ae71141b9d3c52be7c595e32", size = 203623, upload-time = "2025-05-23T11:39:53.846Z" }, ] [package.optional-dependencies] toml = [ { name = "tomli", marker = "python_full_version <= '3.11'" }, ] [[package]] name = "cryptography" version = "45.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/13/1f/9fa001e74a1993a9cadd2333bb889e50c66327b8594ac538ab8a04f915b7/cryptography-45.0.3.tar.gz", hash = "sha256:ec21313dd335c51d7877baf2972569f40a4291b76a0ce51391523ae358d05899", size = 744738, upload-time = "2025-05-25T14:17:24.777Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/71/3d/ac361649a0bfffc105e2298b720d8b862330a767dab27c06adc2ddbef96a/cryptography-45.0.3-cp311-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d377dde61c5d67eb4311eace661c3efda46c62113ff56bf05e2d679e02aebb5b", size = 4205541, upload-time = "2025-05-25T14:16:14.333Z" }, { url = "https://files.pythonhosted.org/packages/70/3e/c02a043750494d5c445f769e9c9f67e550d65060e0bfce52d91c1362693d/cryptography-45.0.3-cp311-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fae1e637f527750811588e4582988932c222f8251f7b7ea93739acb624e1487f", size = 4433275, upload-time = "2025-05-25T14:16:16.421Z" }, { url = "https://files.pythonhosted.org/packages/40/7a/9af0bfd48784e80eef3eb6fd6fde96fe706b4fc156751ce1b2b965dada70/cryptography-45.0.3-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ca932e11218bcc9ef812aa497cdf669484870ecbcf2d99b765d6c27a86000942", size = 4209173, upload-time = "2025-05-25T14:16:18.163Z" }, { url = "https://files.pythonhosted.org/packages/31/5f/d6f8753c8708912df52e67969e80ef70b8e8897306cd9eb8b98201f8c184/cryptography-45.0.3-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:af3f92b1dc25621f5fad065288a44ac790c5798e986a34d393ab27d2b27fcff9", size = 3898150, upload-time = "2025-05-25T14:16:20.34Z" }, { url = "https://files.pythonhosted.org/packages/8b/50/f256ab79c671fb066e47336706dc398c3b1e125f952e07d54ce82cf4011a/cryptography-45.0.3-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2f8f8f0b73b885ddd7f3d8c2b2234a7d3ba49002b0223f58cfde1bedd9563c56", size = 4466473, upload-time = "2025-05-25T14:16:22.605Z" }, { url = "https://files.pythonhosted.org/packages/62/e7/312428336bb2df0848d0768ab5a062e11a32d18139447a76dfc19ada8eed/cryptography-45.0.3-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9cc80ce69032ffa528b5e16d217fa4d8d4bb7d6ba8659c1b4d74a1b0f4235fca", size = 4211890, upload-time = "2025-05-25T14:16:24.738Z" }, { url = "https://files.pythonhosted.org/packages/e7/53/8a130e22c1e432b3c14896ec5eb7ac01fb53c6737e1d705df7e0efb647c6/cryptography-45.0.3-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c824c9281cb628015bfc3c59335163d4ca0540d49de4582d6c2637312907e4b1", size = 4466300, upload-time = "2025-05-25T14:16:26.768Z" }, { url = "https://files.pythonhosted.org/packages/ba/75/6bb6579688ef805fd16a053005fce93944cdade465fc92ef32bbc5c40681/cryptography-45.0.3-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:5833bb4355cb377ebd880457663a972cd044e7f49585aee39245c0d592904578", size = 4332483, upload-time = "2025-05-25T14:16:28.316Z" }, { url = "https://files.pythonhosted.org/packages/2f/11/2538f4e1ce05c6c4f81f43c1ef2bd6de7ae5e24ee284460ff6c77e42ca77/cryptography-45.0.3-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:9bb5bf55dcb69f7067d80354d0a348368da907345a2c448b0babc4215ccd3497", size = 4573714, upload-time = "2025-05-25T14:16:30.474Z" }, { url = "https://files.pythonhosted.org/packages/46/c7/c7d05d0e133a09fc677b8a87953815c522697bdf025e5cac13ba419e7240/cryptography-45.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5edcb90da1843df85292ef3a313513766a78fbbb83f584a5a58fb001a5a9d57", size = 4196181, upload-time = "2025-05-25T14:16:37.934Z" }, { url = "https://files.pythonhosted.org/packages/08/7a/6ad3aa796b18a683657cef930a986fac0045417e2dc428fd336cfc45ba52/cryptography-45.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38deed72285c7ed699864f964a3f4cf11ab3fb38e8d39cfcd96710cd2b5bb716", size = 4423370, upload-time = "2025-05-25T14:16:39.502Z" }, { url = "https://files.pythonhosted.org/packages/4f/58/ec1461bfcb393525f597ac6a10a63938d18775b7803324072974b41a926b/cryptography-45.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5555365a50efe1f486eed6ac7062c33b97ccef409f5970a0b6f205a7cfab59c8", size = 4197839, upload-time = "2025-05-25T14:16:41.322Z" }, { url = "https://files.pythonhosted.org/packages/d4/3d/5185b117c32ad4f40846f579369a80e710d6146c2baa8ce09d01612750db/cryptography-45.0.3-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9e4253ed8f5948a3589b3caee7ad9a5bf218ffd16869c516535325fece163dcc", size = 3886324, upload-time = "2025-05-25T14:16:43.041Z" }, { url = "https://files.pythonhosted.org/packages/67/85/caba91a57d291a2ad46e74016d1f83ac294f08128b26e2a81e9b4f2d2555/cryptography-45.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cfd84777b4b6684955ce86156cfb5e08d75e80dc2585e10d69e47f014f0a5342", size = 4450447, upload-time = "2025-05-25T14:16:44.759Z" }, { url = "https://files.pythonhosted.org/packages/ae/d1/164e3c9d559133a38279215c712b8ba38e77735d3412f37711b9f8f6f7e0/cryptography-45.0.3-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:a2b56de3417fd5f48773ad8e91abaa700b678dc7fe1e0c757e1ae340779acf7b", size = 4200576, upload-time = "2025-05-25T14:16:46.438Z" }, { url = "https://files.pythonhosted.org/packages/71/7a/e002d5ce624ed46dfc32abe1deff32190f3ac47ede911789ee936f5a4255/cryptography-45.0.3-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:57a6500d459e8035e813bd8b51b671977fb149a8c95ed814989da682314d0782", size = 4450308, upload-time = "2025-05-25T14:16:48.228Z" }, { url = "https://files.pythonhosted.org/packages/87/ad/3fbff9c28cf09b0a71e98af57d74f3662dea4a174b12acc493de00ea3f28/cryptography-45.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f22af3c78abfbc7cbcdf2c55d23c3e022e1a462ee2481011d518c7fb9c9f3d65", size = 4325125, upload-time = "2025-05-25T14:16:49.844Z" }, { url = "https://files.pythonhosted.org/packages/f5/b4/51417d0cc01802304c1984d76e9592f15e4801abd44ef7ba657060520bf0/cryptography-45.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:232954730c362638544758a8160c4ee1b832dc011d2c41a306ad8f7cccc5bb0b", size = 4560038, upload-time = "2025-05-25T14:16:51.398Z" }, { url = "https://files.pythonhosted.org/packages/96/61/751ebea58c87b5be533c429f01996050a72c7283b59eee250275746632ea/cryptography-45.0.3-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:555e5e2d3a53b4fabeca32835878b2818b3f23966a4efb0d566689777c5a12c8", size = 4146964, upload-time = "2025-05-25T14:17:09.538Z" }, { url = "https://files.pythonhosted.org/packages/8d/01/28c90601b199964de383da0b740b5156f5d71a1da25e7194fdf793d373ef/cryptography-45.0.3-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:25286aacb947286620a31f78f2ed1a32cded7be5d8b729ba3fb2c988457639e4", size = 4388103, upload-time = "2025-05-25T14:17:11.978Z" }, { url = "https://files.pythonhosted.org/packages/3d/ec/cd892180b9e42897446ef35c62442f5b8b039c3d63a05f618aa87ec9ebb5/cryptography-45.0.3-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:050ce5209d5072472971e6efbfc8ec5a8f9a841de5a4db0ebd9c2e392cb81972", size = 4150031, upload-time = "2025-05-25T14:17:14.131Z" }, { url = "https://files.pythonhosted.org/packages/db/d4/22628c2dedd99289960a682439c6d3aa248dff5215123ead94ac2d82f3f5/cryptography-45.0.3-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:dc10ec1e9f21f33420cc05214989544727e776286c1c16697178978327b95c9c", size = 4387389, upload-time = "2025-05-25T14:17:17.303Z" }, ] [[package]] name = "distlib" version = "0.3.9" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/0d/dd/1bec4c5ddb504ca60fc29472f3d27e8d4da1257a854e1d96742f15c1d02d/distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403", size = 613923, upload-time = "2024-10-09T18:35:47.551Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/91/a1/cf2472db20f7ce4a6be1253a81cfdf85ad9c7885ffbed7047fb72c24cf87/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", size = 468973, upload-time = "2024-10-09T18:35:44.272Z" }, ] [[package]] name = "docutils" version = "0.21.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444, upload-time = "2024-04-23T18:57:18.24Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408, upload-time = "2024-04-23T18:57:14.835Z" }, ] [[package]] name = "filelock" version = "3.18.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/0a/10/c23352565a6544bdc5353e0b15fc1c563352101f30e24bf500207a54df9a/filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2", size = 18075, upload-time = "2025-03-14T07:11:40.47Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/4d/36/2a115987e2d8c300a974597416d9de88f2444426de9571f4b59b2cca3acc/filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de", size = 16215, upload-time = "2025-03-14T07:11:39.145Z" }, ] [[package]] name = "frozenlist" version = "1.6.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ee/f4/d744cba2da59b5c1d88823cf9e8a6c74e4659e2b27604ed973be2a0bf5ab/frozenlist-1.6.0.tar.gz", hash = "sha256:b99655c32c1c8e06d111e7f41c06c29a5318cb1835df23a45518e02a47c63b68", size = 42831, upload-time = "2025-04-17T22:38:53.099Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/53/b5/bc883b5296ec902115c00be161da93bf661199c465ec4c483feec6ea4c32/frozenlist-1.6.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ae8337990e7a45683548ffb2fee1af2f1ed08169284cd829cdd9a7fa7470530d", size = 160912, upload-time = "2025-04-17T22:36:17.235Z" }, { url = "https://files.pythonhosted.org/packages/6f/93/51b058b563d0704b39c56baa222828043aafcac17fd3734bec5dbeb619b1/frozenlist-1.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8c952f69dd524558694818a461855f35d36cc7f5c0adddce37e962c85d06eac0", size = 124315, upload-time = "2025-04-17T22:36:18.735Z" }, { url = "https://files.pythonhosted.org/packages/c9/e0/46cd35219428d350558b874d595e132d1c17a9471a1bd0d01d518a261e7c/frozenlist-1.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8f5fef13136c4e2dee91bfb9a44e236fff78fc2cd9f838eddfc470c3d7d90afe", size = 122230, upload-time = "2025-04-17T22:36:20.6Z" }, { url = "https://files.pythonhosted.org/packages/d1/0f/7ad2ce928ad06d6dd26a61812b959ded573d3e9d0ee6109d96c2be7172e9/frozenlist-1.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:716bbba09611b4663ecbb7cd022f640759af8259e12a6ca939c0a6acd49eedba", size = 314842, upload-time = "2025-04-17T22:36:22.088Z" }, { url = "https://files.pythonhosted.org/packages/34/76/98cbbd8a20a5c3359a2004ae5e5b216af84a150ccbad67c8f8f30fb2ea91/frozenlist-1.6.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7b8c4dc422c1a3ffc550b465090e53b0bf4839047f3e436a34172ac67c45d595", size = 304919, upload-time = "2025-04-17T22:36:24.247Z" }, { url = "https://files.pythonhosted.org/packages/9a/fa/258e771ce3a44348c05e6b01dffc2bc67603fba95761458c238cd09a2c77/frozenlist-1.6.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b11534872256e1666116f6587a1592ef395a98b54476addb5e8d352925cb5d4a", size = 324074, upload-time = "2025-04-17T22:36:26.291Z" }, { url = "https://files.pythonhosted.org/packages/d5/a4/047d861fd8c538210e12b208c0479912273f991356b6bdee7ea8356b07c9/frozenlist-1.6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c6eceb88aaf7221f75be6ab498dc622a151f5f88d536661af3ffc486245a626", size = 321292, upload-time = "2025-04-17T22:36:27.909Z" }, { url = "https://files.pythonhosted.org/packages/c0/25/cfec8af758b4525676cabd36efcaf7102c1348a776c0d1ad046b8a7cdc65/frozenlist-1.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62c828a5b195570eb4b37369fcbbd58e96c905768d53a44d13044355647838ff", size = 301569, upload-time = "2025-04-17T22:36:29.448Z" }, { url = "https://files.pythonhosted.org/packages/87/2f/0c819372fa9f0c07b153124bf58683b8d0ca7bb73ea5ccde9b9ef1745beb/frozenlist-1.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1c6bd2c6399920c9622362ce95a7d74e7f9af9bfec05fff91b8ce4b9647845a", size = 313625, upload-time = "2025-04-17T22:36:31.55Z" }, { url = "https://files.pythonhosted.org/packages/50/5f/f0cf8b0fdedffdb76b3745aa13d5dbe404d63493cc211ce8250f2025307f/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:49ba23817781e22fcbd45fd9ff2b9b8cdb7b16a42a4851ab8025cae7b22e96d0", size = 312523, upload-time = "2025-04-17T22:36:33.078Z" }, { url = "https://files.pythonhosted.org/packages/e1/6c/38c49108491272d3e84125bbabf2c2d0b304899b52f49f0539deb26ad18d/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:431ef6937ae0f853143e2ca67d6da76c083e8b1fe3df0e96f3802fd37626e606", size = 322657, upload-time = "2025-04-17T22:36:34.688Z" }, { url = "https://files.pythonhosted.org/packages/bd/4b/3bd3bad5be06a9d1b04b1c22be80b5fe65b502992d62fab4bdb25d9366ee/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9d124b38b3c299ca68433597ee26b7819209cb8a3a9ea761dfe9db3a04bba584", size = 303414, upload-time = "2025-04-17T22:36:36.363Z" }, { url = "https://files.pythonhosted.org/packages/5b/89/7e225a30bef6e85dbfe22622c24afe932e9444de3b40d58b1ea589a14ef8/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:118e97556306402e2b010da1ef21ea70cb6d6122e580da64c056b96f524fbd6a", size = 320321, upload-time = "2025-04-17T22:36:38.16Z" }, { url = "https://files.pythonhosted.org/packages/22/72/7e3acef4dd9e86366cb8f4d8f28e852c2b7e116927e9722b31a6f71ea4b0/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fb3b309f1d4086b5533cf7bbcf3f956f0ae6469664522f1bde4feed26fba60f1", size = 323975, upload-time = "2025-04-17T22:36:40.289Z" }, { url = "https://files.pythonhosted.org/packages/d8/85/e5da03d20507e13c66ce612c9792b76811b7a43e3320cce42d95b85ac755/frozenlist-1.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54dece0d21dce4fdb188a1ffc555926adf1d1c516e493c2914d7c370e454bc9e", size = 316553, upload-time = "2025-04-17T22:36:42.045Z" }, { url = "https://files.pythonhosted.org/packages/ac/8e/6c609cbd0580ae8a0661c408149f196aade7d325b1ae7adc930501b81acb/frozenlist-1.6.0-cp311-cp311-win32.whl", hash = "sha256:654e4ba1d0b2154ca2f096bed27461cf6160bc7f504a7f9a9ef447c293caf860", size = 115511, upload-time = "2025-04-17T22:36:44.067Z" }, { url = "https://files.pythonhosted.org/packages/f2/13/a84804cfde6de12d44ed48ecbf777ba62b12ff09e761f76cdd1ff9e14bb1/frozenlist-1.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:3e911391bffdb806001002c1f860787542f45916c3baf764264a52765d5a5603", size = 120863, upload-time = "2025-04-17T22:36:45.465Z" }, { url = "https://files.pythonhosted.org/packages/9c/8a/289b7d0de2fbac832ea80944d809759976f661557a38bb8e77db5d9f79b7/frozenlist-1.6.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:c5b9e42ace7d95bf41e19b87cec8f262c41d3510d8ad7514ab3862ea2197bfb1", size = 160193, upload-time = "2025-04-17T22:36:47.382Z" }, { url = "https://files.pythonhosted.org/packages/19/80/2fd17d322aec7f430549f0669f599997174f93ee17929ea5b92781ec902c/frozenlist-1.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ca9973735ce9f770d24d5484dcb42f68f135351c2fc81a7a9369e48cf2998a29", size = 123831, upload-time = "2025-04-17T22:36:49.401Z" }, { url = "https://files.pythonhosted.org/packages/99/06/f5812da431273f78c6543e0b2f7de67dfd65eb0a433978b2c9c63d2205e4/frozenlist-1.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6ac40ec76041c67b928ca8aaffba15c2b2ee3f5ae8d0cb0617b5e63ec119ca25", size = 121862, upload-time = "2025-04-17T22:36:51.899Z" }, { url = "https://files.pythonhosted.org/packages/d0/31/9e61c6b5fc493cf24d54881731204d27105234d09878be1a5983182cc4a5/frozenlist-1.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95b7a8a3180dfb280eb044fdec562f9b461614c0ef21669aea6f1d3dac6ee576", size = 316361, upload-time = "2025-04-17T22:36:53.402Z" }, { url = "https://files.pythonhosted.org/packages/9d/55/22ca9362d4f0222324981470fd50192be200154d51509ee6eb9baa148e96/frozenlist-1.6.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c444d824e22da6c9291886d80c7d00c444981a72686e2b59d38b285617cb52c8", size = 307115, upload-time = "2025-04-17T22:36:55.016Z" }, { url = "https://files.pythonhosted.org/packages/ae/39/4fff42920a57794881e7bb3898dc7f5f539261711ea411b43bba3cde8b79/frozenlist-1.6.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb52c8166499a8150bfd38478248572c924c003cbb45fe3bcd348e5ac7c000f9", size = 322505, upload-time = "2025-04-17T22:36:57.12Z" }, { url = "https://files.pythonhosted.org/packages/55/f2/88c41f374c1e4cf0092a5459e5f3d6a1e17ed274c98087a76487783df90c/frozenlist-1.6.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b35298b2db9c2468106278537ee529719228950a5fdda686582f68f247d1dc6e", size = 322666, upload-time = "2025-04-17T22:36:58.735Z" }, { url = "https://files.pythonhosted.org/packages/75/51/034eeb75afdf3fd03997856195b500722c0b1a50716664cde64e28299c4b/frozenlist-1.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d108e2d070034f9d57210f22fefd22ea0d04609fc97c5f7f5a686b3471028590", size = 302119, upload-time = "2025-04-17T22:37:00.512Z" }, { url = "https://files.pythonhosted.org/packages/2b/a6/564ecde55ee633270a793999ef4fd1d2c2b32b5a7eec903b1012cb7c5143/frozenlist-1.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e1be9111cb6756868ac242b3c2bd1f09d9aea09846e4f5c23715e7afb647103", size = 316226, upload-time = "2025-04-17T22:37:02.102Z" }, { url = "https://files.pythonhosted.org/packages/f1/c8/6c0682c32377f402b8a6174fb16378b683cf6379ab4d2827c580892ab3c7/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:94bb451c664415f02f07eef4ece976a2c65dcbab9c2f1705b7031a3a75349d8c", size = 312788, upload-time = "2025-04-17T22:37:03.578Z" }, { url = "https://files.pythonhosted.org/packages/b6/b8/10fbec38f82c5d163ca1750bfff4ede69713badf236a016781cf1f10a0f0/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d1a686d0b0949182b8faddea596f3fc11f44768d1f74d4cad70213b2e139d821", size = 325914, upload-time = "2025-04-17T22:37:05.213Z" }, { url = "https://files.pythonhosted.org/packages/62/ca/2bf4f3a1bd40cdedd301e6ecfdbb291080d5afc5f9ce350c0739f773d6b9/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ea8e59105d802c5a38bdbe7362822c522230b3faba2aa35c0fa1765239b7dd70", size = 305283, upload-time = "2025-04-17T22:37:06.985Z" }, { url = "https://files.pythonhosted.org/packages/09/64/20cc13ccf94abc2a1f482f74ad210703dc78a590d0b805af1c9aa67f76f9/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:abc4e880a9b920bc5020bf6a431a6bb40589d9bca3975c980495f63632e8382f", size = 319264, upload-time = "2025-04-17T22:37:08.618Z" }, { url = "https://files.pythonhosted.org/packages/20/ff/86c6a2bbe98cfc231519f5e6d712a0898488ceac804a917ce014f32e68f6/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9a79713adfe28830f27a3c62f6b5406c37376c892b05ae070906f07ae4487046", size = 326482, upload-time = "2025-04-17T22:37:10.196Z" }, { url = "https://files.pythonhosted.org/packages/2f/da/8e381f66367d79adca245d1d71527aac774e30e291d41ef161ce2d80c38e/frozenlist-1.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a0318c2068e217a8f5e3b85e35899f5a19e97141a45bb925bb357cfe1daf770", size = 318248, upload-time = "2025-04-17T22:37:12.284Z" }, { url = "https://files.pythonhosted.org/packages/39/24/1a1976563fb476ab6f0fa9fefaac7616a4361dbe0461324f9fd7bf425dbe/frozenlist-1.6.0-cp312-cp312-win32.whl", hash = "sha256:853ac025092a24bb3bf09ae87f9127de9fe6e0c345614ac92536577cf956dfcc", size = 115161, upload-time = "2025-04-17T22:37:13.902Z" }, { url = "https://files.pythonhosted.org/packages/80/2e/fb4ed62a65f8cd66044706b1013f0010930d8cbb0729a2219561ea075434/frozenlist-1.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:2bdfe2d7e6c9281c6e55523acd6c2bf77963cb422fdc7d142fb0cb6621b66878", size = 120548, upload-time = "2025-04-17T22:37:15.326Z" }, { url = "https://files.pythonhosted.org/packages/6f/e5/04c7090c514d96ca00887932417f04343ab94904a56ab7f57861bf63652d/frozenlist-1.6.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1d7fb014fe0fbfee3efd6a94fc635aeaa68e5e1720fe9e57357f2e2c6e1a647e", size = 158182, upload-time = "2025-04-17T22:37:16.837Z" }, { url = "https://files.pythonhosted.org/packages/e9/8f/60d0555c61eec855783a6356268314d204137f5e0c53b59ae2fc28938c99/frozenlist-1.6.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01bcaa305a0fdad12745502bfd16a1c75b14558dabae226852f9159364573117", size = 122838, upload-time = "2025-04-17T22:37:18.352Z" }, { url = "https://files.pythonhosted.org/packages/5a/a7/d0ec890e3665b4b3b7c05dc80e477ed8dc2e2e77719368e78e2cd9fec9c8/frozenlist-1.6.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8b314faa3051a6d45da196a2c495e922f987dc848e967d8cfeaee8a0328b1cd4", size = 120980, upload-time = "2025-04-17T22:37:19.857Z" }, { url = "https://files.pythonhosted.org/packages/cc/19/9b355a5e7a8eba903a008579964192c3e427444752f20b2144b10bb336df/frozenlist-1.6.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da62fecac21a3ee10463d153549d8db87549a5e77eefb8c91ac84bb42bb1e4e3", size = 305463, upload-time = "2025-04-17T22:37:21.328Z" }, { url = "https://files.pythonhosted.org/packages/9c/8d/5b4c758c2550131d66935ef2fa700ada2461c08866aef4229ae1554b93ca/frozenlist-1.6.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1eb89bf3454e2132e046f9599fbcf0a4483ed43b40f545551a39316d0201cd1", size = 297985, upload-time = "2025-04-17T22:37:23.55Z" }, { url = "https://files.pythonhosted.org/packages/48/2c/537ec09e032b5865715726b2d1d9813e6589b571d34d01550c7aeaad7e53/frozenlist-1.6.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18689b40cb3936acd971f663ccb8e2589c45db5e2c5f07e0ec6207664029a9c", size = 311188, upload-time = "2025-04-17T22:37:25.221Z" }, { url = "https://files.pythonhosted.org/packages/31/2f/1aa74b33f74d54817055de9a4961eff798f066cdc6f67591905d4fc82a84/frozenlist-1.6.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e67ddb0749ed066b1a03fba812e2dcae791dd50e5da03be50b6a14d0c1a9ee45", size = 311874, upload-time = "2025-04-17T22:37:26.791Z" }, { url = "https://files.pythonhosted.org/packages/bf/f0/cfec18838f13ebf4b37cfebc8649db5ea71a1b25dacd691444a10729776c/frozenlist-1.6.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc5e64626e6682638d6e44398c9baf1d6ce6bc236d40b4b57255c9d3f9761f1f", size = 291897, upload-time = "2025-04-17T22:37:28.958Z" }, { url = "https://files.pythonhosted.org/packages/ea/a5/deb39325cbbea6cd0a46db8ccd76150ae2fcbe60d63243d9df4a0b8c3205/frozenlist-1.6.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:437cfd39564744ae32ad5929e55b18ebd88817f9180e4cc05e7d53b75f79ce85", size = 305799, upload-time = "2025-04-17T22:37:30.889Z" }, { url = "https://files.pythonhosted.org/packages/78/22/6ddec55c5243a59f605e4280f10cee8c95a449f81e40117163383829c241/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:62dd7df78e74d924952e2feb7357d826af8d2f307557a779d14ddf94d7311be8", size = 302804, upload-time = "2025-04-17T22:37:32.489Z" }, { url = "https://files.pythonhosted.org/packages/5d/b7/d9ca9bab87f28855063c4d202936800219e39db9e46f9fb004d521152623/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a66781d7e4cddcbbcfd64de3d41a61d6bdde370fc2e38623f30b2bd539e84a9f", size = 316404, upload-time = "2025-04-17T22:37:34.59Z" }, { url = "https://files.pythonhosted.org/packages/a6/3a/1255305db7874d0b9eddb4fe4a27469e1fb63720f1fc6d325a5118492d18/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:482fe06e9a3fffbcd41950f9d890034b4a54395c60b5e61fae875d37a699813f", size = 295572, upload-time = "2025-04-17T22:37:36.337Z" }, { url = "https://files.pythonhosted.org/packages/2a/f2/8d38eeee39a0e3a91b75867cc102159ecccf441deb6ddf67be96d3410b84/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e4f9373c500dfc02feea39f7a56e4f543e670212102cc2eeb51d3a99c7ffbde6", size = 307601, upload-time = "2025-04-17T22:37:37.923Z" }, { url = "https://files.pythonhosted.org/packages/38/04/80ec8e6b92f61ef085422d7b196822820404f940950dde5b2e367bede8bc/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e69bb81de06827147b7bfbaeb284d85219fa92d9f097e32cc73675f279d70188", size = 314232, upload-time = "2025-04-17T22:37:39.669Z" }, { url = "https://files.pythonhosted.org/packages/3a/58/93b41fb23e75f38f453ae92a2f987274c64637c450285577bd81c599b715/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7613d9977d2ab4a9141dde4a149f4357e4065949674c5649f920fec86ecb393e", size = 308187, upload-time = "2025-04-17T22:37:41.662Z" }, { url = "https://files.pythonhosted.org/packages/6a/a2/e64df5c5aa36ab3dee5a40d254f3e471bb0603c225f81664267281c46a2d/frozenlist-1.6.0-cp313-cp313-win32.whl", hash = "sha256:4def87ef6d90429f777c9d9de3961679abf938cb6b7b63d4a7eb8a268babfce4", size = 114772, upload-time = "2025-04-17T22:37:43.132Z" }, { url = "https://files.pythonhosted.org/packages/a0/77/fead27441e749b2d574bb73d693530d59d520d4b9e9679b8e3cb779d37f2/frozenlist-1.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:37a8a52c3dfff01515e9bbbee0e6063181362f9de3db2ccf9bc96189b557cbfd", size = 119847, upload-time = "2025-04-17T22:37:45.118Z" }, { url = "https://files.pythonhosted.org/packages/df/bd/cc6d934991c1e5d9cafda83dfdc52f987c7b28343686aef2e58a9cf89f20/frozenlist-1.6.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:46138f5a0773d064ff663d273b309b696293d7a7c00a0994c5c13a5078134b64", size = 174937, upload-time = "2025-04-17T22:37:46.635Z" }, { url = "https://files.pythonhosted.org/packages/f2/a2/daf945f335abdbfdd5993e9dc348ef4507436936ab3c26d7cfe72f4843bf/frozenlist-1.6.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:f88bc0a2b9c2a835cb888b32246c27cdab5740059fb3688852bf91e915399b91", size = 136029, upload-time = "2025-04-17T22:37:48.192Z" }, { url = "https://files.pythonhosted.org/packages/51/65/4c3145f237a31247c3429e1c94c384d053f69b52110a0d04bfc8afc55fb2/frozenlist-1.6.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:777704c1d7655b802c7850255639672e90e81ad6fa42b99ce5ed3fbf45e338dd", size = 134831, upload-time = "2025-04-17T22:37:50.485Z" }, { url = "https://files.pythonhosted.org/packages/77/38/03d316507d8dea84dfb99bdd515ea245628af964b2bf57759e3c9205cc5e/frozenlist-1.6.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85ef8d41764c7de0dcdaf64f733a27352248493a85a80661f3c678acd27e31f2", size = 392981, upload-time = "2025-04-17T22:37:52.558Z" }, { url = "https://files.pythonhosted.org/packages/37/02/46285ef9828f318ba400a51d5bb616ded38db8466836a9cfa39f3903260b/frozenlist-1.6.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:da5cb36623f2b846fb25009d9d9215322318ff1c63403075f812b3b2876c8506", size = 371999, upload-time = "2025-04-17T22:37:54.092Z" }, { url = "https://files.pythonhosted.org/packages/0d/64/1212fea37a112c3c5c05bfb5f0a81af4836ce349e69be75af93f99644da9/frozenlist-1.6.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cbb56587a16cf0fb8acd19e90ff9924979ac1431baea8681712716a8337577b0", size = 392200, upload-time = "2025-04-17T22:37:55.951Z" }, { url = "https://files.pythonhosted.org/packages/81/ce/9a6ea1763e3366e44a5208f76bf37c76c5da570772375e4d0be85180e588/frozenlist-1.6.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6154c3ba59cda3f954c6333025369e42c3acd0c6e8b6ce31eb5c5b8116c07e0", size = 390134, upload-time = "2025-04-17T22:37:57.633Z" }, { url = "https://files.pythonhosted.org/packages/bc/36/939738b0b495b2c6d0c39ba51563e453232813042a8d908b8f9544296c29/frozenlist-1.6.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e8246877afa3f1ae5c979fe85f567d220f86a50dc6c493b9b7d8191181ae01e", size = 365208, upload-time = "2025-04-17T22:37:59.742Z" }, { url = "https://files.pythonhosted.org/packages/b4/8b/939e62e93c63409949c25220d1ba8e88e3960f8ef6a8d9ede8f94b459d27/frozenlist-1.6.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b0f6cce16306d2e117cf9db71ab3a9e8878a28176aeaf0dbe35248d97b28d0c", size = 385548, upload-time = "2025-04-17T22:38:01.416Z" }, { url = "https://files.pythonhosted.org/packages/62/38/22d2873c90102e06a7c5a3a5b82ca47e393c6079413e8a75c72bff067fa8/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:1b8e8cd8032ba266f91136d7105706ad57770f3522eac4a111d77ac126a25a9b", size = 391123, upload-time = "2025-04-17T22:38:03.049Z" }, { url = "https://files.pythonhosted.org/packages/44/78/63aaaf533ee0701549500f6d819be092c6065cb5c577edb70c09df74d5d0/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:e2ada1d8515d3ea5378c018a5f6d14b4994d4036591a52ceaf1a1549dec8e1ad", size = 394199, upload-time = "2025-04-17T22:38:04.776Z" }, { url = "https://files.pythonhosted.org/packages/54/45/71a6b48981d429e8fbcc08454dc99c4c2639865a646d549812883e9c9dd3/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:cdb2c7f071e4026c19a3e32b93a09e59b12000751fc9b0b7758da899e657d215", size = 373854, upload-time = "2025-04-17T22:38:06.576Z" }, { url = "https://files.pythonhosted.org/packages/3f/f3/dbf2a5e11736ea81a66e37288bf9f881143a7822b288a992579ba1b4204d/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:03572933a1969a6d6ab509d509e5af82ef80d4a5d4e1e9f2e1cdd22c77a3f4d2", size = 395412, upload-time = "2025-04-17T22:38:08.197Z" }, { url = "https://files.pythonhosted.org/packages/b3/f1/c63166806b331f05104d8ea385c4acd511598568b1f3e4e8297ca54f2676/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:77effc978947548b676c54bbd6a08992759ea6f410d4987d69feea9cd0919911", size = 394936, upload-time = "2025-04-17T22:38:10.056Z" }, { url = "https://files.pythonhosted.org/packages/ef/ea/4f3e69e179a430473eaa1a75ff986526571215fefc6b9281cdc1f09a4eb8/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a2bda8be77660ad4089caf2223fdbd6db1858462c4b85b67fbfa22102021e497", size = 391459, upload-time = "2025-04-17T22:38:11.826Z" }, { url = "https://files.pythonhosted.org/packages/d3/c3/0fc2c97dea550df9afd072a37c1e95421652e3206bbeaa02378b24c2b480/frozenlist-1.6.0-cp313-cp313t-win32.whl", hash = "sha256:a4d96dc5bcdbd834ec6b0f91027817214216b5b30316494d2b1aebffb87c534f", size = 128797, upload-time = "2025-04-17T22:38:14.013Z" }, { url = "https://files.pythonhosted.org/packages/ae/f5/79c9320c5656b1965634fe4be9c82b12a3305bdbc58ad9cb941131107b20/frozenlist-1.6.0-cp313-cp313t-win_amd64.whl", hash = "sha256:e18036cb4caa17ea151fd5f3d70be9d354c99eb8cf817a3ccde8a7873b074348", size = 134709, upload-time = "2025-04-17T22:38:15.551Z" }, { url = "https://files.pythonhosted.org/packages/71/3e/b04a0adda73bd52b390d730071c0d577073d3d26740ee1bad25c3ad0f37b/frozenlist-1.6.0-py3-none-any.whl", hash = "sha256:535eec9987adb04701266b92745d6cdcef2e77669299359c3009c3404dd5d191", size = 12404, upload-time = "2025-04-17T22:38:51.668Z" }, ] [[package]] name = "id" version = "1.5.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "requests" }, ] sdist = { url = "https://files.pythonhosted.org/packages/22/11/102da08f88412d875fa2f1a9a469ff7ad4c874b0ca6fed0048fe385bdb3d/id-1.5.0.tar.gz", hash = "sha256:292cb8a49eacbbdbce97244f47a97b4c62540169c976552e497fd57df0734c1d", size = 15237, upload-time = "2024-12-04T19:53:05.575Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/9f/cb/18326d2d89ad3b0dd143da971e77afd1e6ca6674f1b1c3df4b6bec6279fc/id-1.5.0-py3-none-any.whl", hash = "sha256:f1434e1cef91f2cbb8a4ec64663d5a23b9ed43ef44c4c957d02583d61714c658", size = 13611, upload-time = "2024-12-04T19:53:03.02Z" }, ] [[package]] name = "identify" version = "2.6.12" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a2/88/d193a27416618628a5eea64e3223acd800b40749a96ffb322a9b55a49ed1/identify-2.6.12.tar.gz", hash = "sha256:d8de45749f1efb108badef65ee8386f0f7bb19a7f26185f74de6367bffbaf0e6", size = 99254, upload-time = "2025-05-23T20:37:53.3Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7a/cd/18f8da995b658420625f7ef13f037be53ae04ec5ad33f9b718240dcfd48c/identify-2.6.12-py2.py3-none-any.whl", hash = "sha256:ad9672d5a72e0d2ff7c5c8809b62dfa60458626352fb0eb7b55e69bdc45334a2", size = 99145, upload-time = "2025-05-23T20:37:51.495Z" }, ] [[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 = "importlib-metadata" version = "8.7.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "zipp" }, ] sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641, upload-time = "2025-04-27T15:29:01.736Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd", size = 27656, upload-time = "2025-04-27T15:29:00.214Z" }, ] [[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 = "jaraco-classes" version = "3.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "more-itertools" }, ] sdist = { url = "https://files.pythonhosted.org/packages/06/c0/ed4a27bc5571b99e3cff68f8a9fa5b56ff7df1c2251cc715a652ddd26402/jaraco.classes-3.4.0.tar.gz", hash = "sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd", size = 11780, upload-time = "2024-03-31T07:27:36.643Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl", hash = "sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790", size = 6777, upload-time = "2024-03-31T07:27:34.792Z" }, ] [[package]] name = "jaraco-context" version = "6.0.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "backports-tarfile", marker = "python_full_version < '3.12'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/df/ad/f3777b81bf0b6e7bc7514a1656d3e637b2e8e15fab2ce3235730b3e7a4e6/jaraco_context-6.0.1.tar.gz", hash = "sha256:9bae4ea555cf0b14938dc0aee7c9f32ed303aa20a3b73e7dc80111628792d1b3", size = 13912, upload-time = "2024-08-20T03:39:27.358Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ff/db/0c52c4cf5e4bd9f5d7135ec7669a3a767af21b3a308e1ed3674881e52b62/jaraco.context-6.0.1-py3-none-any.whl", hash = "sha256:f797fc481b490edb305122c9181830a3a5b76d84ef6d1aef2fb9b47ab956f9e4", size = 6825, upload-time = "2024-08-20T03:39:25.966Z" }, ] [[package]] name = "jaraco-functools" version = "4.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "more-itertools" }, ] sdist = { url = "https://files.pythonhosted.org/packages/ab/23/9894b3df5d0a6eb44611c36aec777823fc2e07740dabbd0b810e19594013/jaraco_functools-4.1.0.tar.gz", hash = "sha256:70f7e0e2ae076498e212562325e805204fc092d7b4c17e0e86c959e249701a9d", size = 19159, upload-time = "2024-09-27T19:47:09.122Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/9f/4f/24b319316142c44283d7540e76c7b5a6dbd5db623abd86bb7b3491c21018/jaraco.functools-4.1.0-py3-none-any.whl", hash = "sha256:ad159f13428bc4acbf5541ad6dec511f91573b90fba04df61dafa2a1231cf649", size = 10187, upload-time = "2024-09-27T19:47:07.14Z" }, ] [[package]] name = "jeepney" version = "0.9.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/7b/6f/357efd7602486741aa73ffc0617fb310a29b588ed0fd69c2399acbb85b0c/jeepney-0.9.0.tar.gz", hash = "sha256:cf0e9e845622b81e4a28df94c40345400256ec608d0e55bb8a3feaa9163f5732", size = 106758, upload-time = "2025-02-27T18:51:01.684Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b2/a3/e137168c9c44d18eff0376253da9f1e9234d0239e0ee230d2fee6cea8e55/jeepney-0.9.0-py3-none-any.whl", hash = "sha256:97e5714520c16fc0a45695e5365a2e11b81ea79bba796e26f9f1d178cb182683", size = 49010, upload-time = "2025-02-27T18:51:00.104Z" }, ] [[package]] name = "keyring" version = "25.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "importlib-metadata", marker = "python_full_version < '3.12'" }, { name = "jaraco-classes" }, { name = "jaraco-context" }, { name = "jaraco-functools" }, { name = "jeepney", marker = "sys_platform == 'linux'" }, { name = "pywin32-ctypes", marker = "sys_platform == 'win32'" }, { name = "secretstorage", marker = "sys_platform == 'linux'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/70/09/d904a6e96f76ff214be59e7aa6ef7190008f52a0ab6689760a98de0bf37d/keyring-25.6.0.tar.gz", hash = "sha256:0b39998aa941431eb3d9b0d4b2460bc773b9df6fed7621c2dfb291a7e0187a66", size = 62750, upload-time = "2024-12-25T15:26:45.782Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/d3/32/da7f44bcb1105d3e88a0b74ebdca50c59121d2ddf71c9e34ba47df7f3a56/keyring-25.6.0-py3-none-any.whl", hash = "sha256:552a3f7af126ece7ed5c89753650eec89c7eaae8617d0aa4d9ad2b75111266bd", size = 39085, upload-time = "2024-12-25T15:26:44.377Z" }, ] [[package]] name = "markdown-it-py" version = "3.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" }, ] [[package]] name = "mdurl" version = "0.1.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] [[package]] name = "more-itertools" version = "10.7.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ce/a0/834b0cebabbfc7e311f30b46c8188790a37f89fc8d756660346fe5abfd09/more_itertools-10.7.0.tar.gz", hash = "sha256:9fddd5403be01a94b204faadcff459ec3568cf110265d3c54323e1e866ad29d3", size = 127671, upload-time = "2025-04-22T14:17:41.838Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2b/9f/7ba6f94fc1e9ac3d2b853fdff3035fb2fa5afbed898c4a72b8a020610594/more_itertools-10.7.0-py3-none-any.whl", hash = "sha256:d43980384673cb07d2f7d2d918c616b30c659c089ee23953f601d6609c67510e", size = 65278, upload-time = "2025-04-22T14:17:40.49Z" }, ] [[package]] name = "multidict" version = "6.4.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/91/2f/a3470242707058fe856fe59241eee5635d79087100b7042a867368863a27/multidict-6.4.4.tar.gz", hash = "sha256:69ee9e6ba214b5245031b76233dd95408a0fd57fdb019ddcc1ead4790932a8e8", size = 90183, upload-time = "2025-05-19T14:16:37.381Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/19/1b/4c6e638195851524a63972c5773c7737bea7e47b1ba402186a37773acee2/multidict-6.4.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4f5f29794ac0e73d2a06ac03fd18870adc0135a9d384f4a306a951188ed02f95", size = 65515, upload-time = "2025-05-19T14:14:19.767Z" }, { url = "https://files.pythonhosted.org/packages/25/d5/10e6bca9a44b8af3c7f920743e5fc0c2bcf8c11bf7a295d4cfe00b08fb46/multidict-6.4.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c04157266344158ebd57b7120d9b0b35812285d26d0e78193e17ef57bfe2979a", size = 38609, upload-time = "2025-05-19T14:14:21.538Z" }, { url = "https://files.pythonhosted.org/packages/26/b4/91fead447ccff56247edc7f0535fbf140733ae25187a33621771ee598a18/multidict-6.4.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bb61ffd3ab8310d93427e460f565322c44ef12769f51f77277b4abad7b6f7223", size = 37871, upload-time = "2025-05-19T14:14:22.666Z" }, { url = "https://files.pythonhosted.org/packages/3b/37/cbc977cae59277e99d15bbda84cc53b5e0c4929ffd91d958347200a42ad0/multidict-6.4.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e0ba18a9afd495f17c351d08ebbc4284e9c9f7971d715f196b79636a4d0de44", size = 226661, upload-time = "2025-05-19T14:14:24.124Z" }, { url = "https://files.pythonhosted.org/packages/15/cd/7e0b57fbd4dc2fc105169c4ecce5be1a63970f23bb4ec8c721b67e11953d/multidict-6.4.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9faf1b1dcaadf9f900d23a0e6d6c8eadd6a95795a0e57fcca73acce0eb912065", size = 223422, upload-time = "2025-05-19T14:14:25.437Z" }, { url = "https://files.pythonhosted.org/packages/f1/01/1de268da121bac9f93242e30cd3286f6a819e5f0b8896511162d6ed4bf8d/multidict-6.4.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a4d1cb1327c6082c4fce4e2a438483390964c02213bc6b8d782cf782c9b1471f", size = 235447, upload-time = "2025-05-19T14:14:26.793Z" }, { url = "https://files.pythonhosted.org/packages/d2/8c/8b9a5e4aaaf4f2de14e86181a3a3d7b105077f668b6a06f043ec794f684c/multidict-6.4.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:941f1bec2f5dbd51feeb40aea654c2747f811ab01bdd3422a48a4e4576b7d76a", size = 231455, upload-time = "2025-05-19T14:14:28.149Z" }, { url = "https://files.pythonhosted.org/packages/35/db/e1817dcbaa10b319c412769cf999b1016890849245d38905b73e9c286862/multidict-6.4.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5f8a146184da7ea12910a4cec51ef85e44f6268467fb489c3caf0cd512f29c2", size = 223666, upload-time = "2025-05-19T14:14:29.584Z" }, { url = "https://files.pythonhosted.org/packages/4a/e1/66e8579290ade8a00e0126b3d9a93029033ffd84f0e697d457ed1814d0fc/multidict-6.4.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:232b7237e57ec3c09be97206bfb83a0aa1c5d7d377faa019c68a210fa35831f1", size = 217392, upload-time = "2025-05-19T14:14:30.961Z" }, { url = "https://files.pythonhosted.org/packages/7b/6f/f8639326069c24a48c7747c2a5485d37847e142a3f741ff3340c88060a9a/multidict-6.4.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:55ae0721c1513e5e3210bca4fc98456b980b0c2c016679d3d723119b6b202c42", size = 228969, upload-time = "2025-05-19T14:14:32.672Z" }, { url = "https://files.pythonhosted.org/packages/d2/c3/3d58182f76b960eeade51c89fcdce450f93379340457a328e132e2f8f9ed/multidict-6.4.4-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:51d662c072579f63137919d7bb8fc250655ce79f00c82ecf11cab678f335062e", size = 217433, upload-time = "2025-05-19T14:14:34.016Z" }, { url = "https://files.pythonhosted.org/packages/e1/4b/f31a562906f3bd375f3d0e83ce314e4a660c01b16c2923e8229b53fba5d7/multidict-6.4.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0e05c39962baa0bb19a6b210e9b1422c35c093b651d64246b6c2e1a7e242d9fd", size = 225418, upload-time = "2025-05-19T14:14:35.376Z" }, { url = "https://files.pythonhosted.org/packages/99/89/78bb95c89c496d64b5798434a3deee21996114d4d2c28dd65850bf3a691e/multidict-6.4.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d5b1cc3ab8c31d9ebf0faa6e3540fb91257590da330ffe6d2393d4208e638925", size = 235042, upload-time = "2025-05-19T14:14:36.723Z" }, { url = "https://files.pythonhosted.org/packages/74/91/8780a6e5885a8770442a8f80db86a0887c4becca0e5a2282ba2cae702bc4/multidict-6.4.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:93ec84488a384cd7b8a29c2c7f467137d8a73f6fe38bb810ecf29d1ade011a7c", size = 230280, upload-time = "2025-05-19T14:14:38.194Z" }, { url = "https://files.pythonhosted.org/packages/68/c1/fcf69cabd542eb6f4b892469e033567ee6991d361d77abdc55e3a0f48349/multidict-6.4.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b308402608493638763abc95f9dc0030bbd6ac6aff784512e8ac3da73a88af08", size = 223322, upload-time = "2025-05-19T14:14:40.015Z" }, { url = "https://files.pythonhosted.org/packages/b8/85/5b80bf4b83d8141bd763e1d99142a9cdfd0db83f0739b4797172a4508014/multidict-6.4.4-cp311-cp311-win32.whl", hash = "sha256:343892a27d1a04d6ae455ecece12904d242d299ada01633d94c4f431d68a8c49", size = 35070, upload-time = "2025-05-19T14:14:41.904Z" }, { url = "https://files.pythonhosted.org/packages/09/66/0bed198ffd590ab86e001f7fa46b740d58cf8ff98c2f254e4a36bf8861ad/multidict-6.4.4-cp311-cp311-win_amd64.whl", hash = "sha256:73484a94f55359780c0f458bbd3c39cb9cf9c182552177d2136e828269dee529", size = 38667, upload-time = "2025-05-19T14:14:43.534Z" }, { url = "https://files.pythonhosted.org/packages/d2/b5/5675377da23d60875fe7dae6be841787755878e315e2f517235f22f59e18/multidict-6.4.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:dc388f75a1c00000824bf28b7633e40854f4127ede80512b44c3cfeeea1839a2", size = 64293, upload-time = "2025-05-19T14:14:44.724Z" }, { url = "https://files.pythonhosted.org/packages/34/a7/be384a482754bb8c95d2bbe91717bf7ccce6dc38c18569997a11f95aa554/multidict-6.4.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:98af87593a666f739d9dba5d0ae86e01b0e1a9cfcd2e30d2d361fbbbd1a9162d", size = 38096, upload-time = "2025-05-19T14:14:45.95Z" }, { url = "https://files.pythonhosted.org/packages/66/6d/d59854bb4352306145bdfd1704d210731c1bb2c890bfee31fb7bbc1c4c7f/multidict-6.4.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aff4cafea2d120327d55eadd6b7f1136a8e5a0ecf6fb3b6863e8aca32cd8e50a", size = 37214, upload-time = "2025-05-19T14:14:47.158Z" }, { url = "https://files.pythonhosted.org/packages/99/e0/c29d9d462d7cfc5fc8f9bf24f9c6843b40e953c0b55e04eba2ad2cf54fba/multidict-6.4.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:169c4ba7858176b797fe551d6e99040c531c775d2d57b31bcf4de6d7a669847f", size = 224686, upload-time = "2025-05-19T14:14:48.366Z" }, { url = "https://files.pythonhosted.org/packages/dc/4a/da99398d7fd8210d9de068f9a1b5f96dfaf67d51e3f2521f17cba4ee1012/multidict-6.4.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b9eb4c59c54421a32b3273d4239865cb14ead53a606db066d7130ac80cc8ec93", size = 231061, upload-time = "2025-05-19T14:14:49.952Z" }, { url = "https://files.pythonhosted.org/packages/21/f5/ac11add39a0f447ac89353e6ca46666847051103649831c08a2800a14455/multidict-6.4.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7cf3bd54c56aa16fdb40028d545eaa8d051402b61533c21e84046e05513d5780", size = 232412, upload-time = "2025-05-19T14:14:51.812Z" }, { url = "https://files.pythonhosted.org/packages/d9/11/4b551e2110cded705a3c13a1d4b6a11f73891eb5a1c449f1b2b6259e58a6/multidict-6.4.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f682c42003c7264134bfe886376299db4cc0c6cd06a3295b41b347044bcb5482", size = 231563, upload-time = "2025-05-19T14:14:53.262Z" }, { url = "https://files.pythonhosted.org/packages/4c/02/751530c19e78fe73b24c3da66618eda0aa0d7f6e7aa512e46483de6be210/multidict-6.4.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920f9cf2abdf6e493c519492d892c362007f113c94da4c239ae88429835bad1", size = 223811, upload-time = "2025-05-19T14:14:55.232Z" }, { url = "https://files.pythonhosted.org/packages/c7/cb/2be8a214643056289e51ca356026c7b2ce7225373e7a1f8c8715efee8988/multidict-6.4.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:530d86827a2df6504526106b4c104ba19044594f8722d3e87714e847c74a0275", size = 216524, upload-time = "2025-05-19T14:14:57.226Z" }, { url = "https://files.pythonhosted.org/packages/19/f3/6d5011ec375c09081f5250af58de85f172bfcaafebff286d8089243c4bd4/multidict-6.4.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ecde56ea2439b96ed8a8d826b50c57364612ddac0438c39e473fafad7ae1c23b", size = 229012, upload-time = "2025-05-19T14:14:58.597Z" }, { url = "https://files.pythonhosted.org/packages/67/9c/ca510785df5cf0eaf5b2a8132d7d04c1ce058dcf2c16233e596ce37a7f8e/multidict-6.4.4-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:dc8c9736d8574b560634775ac0def6bdc1661fc63fa27ffdfc7264c565bcb4f2", size = 226765, upload-time = "2025-05-19T14:15:00.048Z" }, { url = "https://files.pythonhosted.org/packages/36/c8/ca86019994e92a0f11e642bda31265854e6ea7b235642f0477e8c2e25c1f/multidict-6.4.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:7f3d3b3c34867579ea47cbd6c1f2ce23fbfd20a273b6f9e3177e256584f1eacc", size = 222888, upload-time = "2025-05-19T14:15:01.568Z" }, { url = "https://files.pythonhosted.org/packages/c6/67/bc25a8e8bd522935379066950ec4e2277f9b236162a73548a2576d4b9587/multidict-6.4.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:87a728af265e08f96b6318ebe3c0f68b9335131f461efab2fc64cc84a44aa6ed", size = 234041, upload-time = "2025-05-19T14:15:03.759Z" }, { url = "https://files.pythonhosted.org/packages/f1/a0/70c4c2d12857fccbe607b334b7ee28b6b5326c322ca8f73ee54e70d76484/multidict-6.4.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9f193eeda1857f8e8d3079a4abd258f42ef4a4bc87388452ed1e1c4d2b0c8740", size = 231046, upload-time = "2025-05-19T14:15:05.698Z" }, { url = "https://files.pythonhosted.org/packages/c1/0f/52954601d02d39742aab01d6b92f53c1dd38b2392248154c50797b4df7f1/multidict-6.4.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be06e73c06415199200e9a2324a11252a3d62030319919cde5e6950ffeccf72e", size = 227106, upload-time = "2025-05-19T14:15:07.124Z" }, { url = "https://files.pythonhosted.org/packages/af/24/679d83ec4379402d28721790dce818e5d6b9f94ce1323a556fb17fa9996c/multidict-6.4.4-cp312-cp312-win32.whl", hash = "sha256:622f26ea6a7e19b7c48dd9228071f571b2fbbd57a8cd71c061e848f281550e6b", size = 35351, upload-time = "2025-05-19T14:15:08.556Z" }, { url = "https://files.pythonhosted.org/packages/52/ef/40d98bc5f986f61565f9b345f102409534e29da86a6454eb6b7c00225a13/multidict-6.4.4-cp312-cp312-win_amd64.whl", hash = "sha256:5e2bcda30d5009996ff439e02a9f2b5c3d64a20151d34898c000a6281faa3781", size = 38791, upload-time = "2025-05-19T14:15:09.825Z" }, { url = "https://files.pythonhosted.org/packages/df/2a/e166d2ffbf4b10131b2d5b0e458f7cee7d986661caceae0de8753042d4b2/multidict-6.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:82ffabefc8d84c2742ad19c37f02cde5ec2a1ee172d19944d380f920a340e4b9", size = 64123, upload-time = "2025-05-19T14:15:11.044Z" }, { url = "https://files.pythonhosted.org/packages/8c/96/e200e379ae5b6f95cbae472e0199ea98913f03d8c9a709f42612a432932c/multidict-6.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6a2f58a66fe2c22615ad26156354005391e26a2f3721c3621504cd87c1ea87bf", size = 38049, upload-time = "2025-05-19T14:15:12.902Z" }, { url = "https://files.pythonhosted.org/packages/75/fb/47afd17b83f6a8c7fa863c6d23ac5ba6a0e6145ed8a6bcc8da20b2b2c1d2/multidict-6.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5883d6ee0fd9d8a48e9174df47540b7545909841ac82354c7ae4cbe9952603bd", size = 37078, upload-time = "2025-05-19T14:15:14.282Z" }, { url = "https://files.pythonhosted.org/packages/fa/70/1af3143000eddfb19fd5ca5e78393985ed988ac493bb859800fe0914041f/multidict-6.4.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9abcf56a9511653fa1d052bfc55fbe53dbee8f34e68bd6a5a038731b0ca42d15", size = 224097, upload-time = "2025-05-19T14:15:15.566Z" }, { url = "https://files.pythonhosted.org/packages/b1/39/d570c62b53d4fba844e0378ffbcd02ac25ca423d3235047013ba2f6f60f8/multidict-6.4.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6ed5ae5605d4ad5a049fad2a28bb7193400700ce2f4ae484ab702d1e3749c3f9", size = 230768, upload-time = "2025-05-19T14:15:17.308Z" }, { url = "https://files.pythonhosted.org/packages/fd/f8/ed88f2c4d06f752b015933055eb291d9bc184936903752c66f68fb3c95a7/multidict-6.4.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbfcb60396f9bcfa63e017a180c3105b8c123a63e9d1428a36544e7d37ca9e20", size = 231331, upload-time = "2025-05-19T14:15:18.73Z" }, { url = "https://files.pythonhosted.org/packages/9c/6f/8e07cffa32f483ab887b0d56bbd8747ac2c1acd00dc0af6fcf265f4a121e/multidict-6.4.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0f1987787f5f1e2076b59692352ab29a955b09ccc433c1f6b8e8e18666f608b", size = 230169, upload-time = "2025-05-19T14:15:20.179Z" }, { url = "https://files.pythonhosted.org/packages/e6/2b/5dcf173be15e42f330110875a2668ddfc208afc4229097312212dc9c1236/multidict-6.4.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d0121ccce8c812047d8d43d691a1ad7641f72c4f730474878a5aeae1b8ead8c", size = 222947, upload-time = "2025-05-19T14:15:21.714Z" }, { url = "https://files.pythonhosted.org/packages/39/75/4ddcbcebe5ebcd6faa770b629260d15840a5fc07ce8ad295a32e14993726/multidict-6.4.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ec4967114295b8afd120a8eec579920c882831a3e4c3331d591a8e5bfbbc0f", size = 215761, upload-time = "2025-05-19T14:15:23.242Z" }, { url = "https://files.pythonhosted.org/packages/6a/c9/55e998ae45ff15c5608e384206aa71a11e1b7f48b64d166db400b14a3433/multidict-6.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:995f985e2e268deaf17867801b859a282e0448633f1310e3704b30616d269d69", size = 227605, upload-time = "2025-05-19T14:15:24.763Z" }, { url = "https://files.pythonhosted.org/packages/04/49/c2404eac74497503c77071bd2e6f88c7e94092b8a07601536b8dbe99be50/multidict-6.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:d832c608f94b9f92a0ec8b7e949be7792a642b6e535fcf32f3e28fab69eeb046", size = 226144, upload-time = "2025-05-19T14:15:26.249Z" }, { url = "https://files.pythonhosted.org/packages/62/c5/0cd0c3c6f18864c40846aa2252cd69d308699cb163e1c0d989ca301684da/multidict-6.4.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d21c1212171cf7da703c5b0b7a0e85be23b720818aef502ad187d627316d5645", size = 221100, upload-time = "2025-05-19T14:15:28.303Z" }, { url = "https://files.pythonhosted.org/packages/71/7b/f2f3887bea71739a046d601ef10e689528d4f911d84da873b6be9194ffea/multidict-6.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:cbebaa076aaecad3d4bb4c008ecc73b09274c952cf6a1b78ccfd689e51f5a5b0", size = 232731, upload-time = "2025-05-19T14:15:30.263Z" }, { url = "https://files.pythonhosted.org/packages/e5/b3/d9de808349df97fa75ec1372758701b5800ebad3c46ae377ad63058fbcc6/multidict-6.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:c93a6fb06cc8e5d3628b2b5fda215a5db01e8f08fc15fadd65662d9b857acbe4", size = 229637, upload-time = "2025-05-19T14:15:33.337Z" }, { url = "https://files.pythonhosted.org/packages/5e/57/13207c16b615eb4f1745b44806a96026ef8e1b694008a58226c2d8f5f0a5/multidict-6.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8cd8f81f1310182362fb0c7898145ea9c9b08a71081c5963b40ee3e3cac589b1", size = 225594, upload-time = "2025-05-19T14:15:34.832Z" }, { url = "https://files.pythonhosted.org/packages/3a/e4/d23bec2f70221604f5565000632c305fc8f25ba953e8ce2d8a18842b9841/multidict-6.4.4-cp313-cp313-win32.whl", hash = "sha256:3e9f1cd61a0ab857154205fb0b1f3d3ace88d27ebd1409ab7af5096e409614cd", size = 35359, upload-time = "2025-05-19T14:15:36.246Z" }, { url = "https://files.pythonhosted.org/packages/a7/7a/cfe1a47632be861b627f46f642c1d031704cc1c0f5c0efbde2ad44aa34bd/multidict-6.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:8ffb40b74400e4455785c2fa37eba434269149ec525fc8329858c862e4b35373", size = 38903, upload-time = "2025-05-19T14:15:37.507Z" }, { url = "https://files.pythonhosted.org/packages/68/7b/15c259b0ab49938a0a1c8f3188572802704a779ddb294edc1b2a72252e7c/multidict-6.4.4-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:6a602151dbf177be2450ef38966f4be3467d41a86c6a845070d12e17c858a156", size = 68895, upload-time = "2025-05-19T14:15:38.856Z" }, { url = "https://files.pythonhosted.org/packages/f1/7d/168b5b822bccd88142e0a3ce985858fea612404edd228698f5af691020c9/multidict-6.4.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0d2b9712211b860d123815a80b859075d86a4d54787e247d7fbee9db6832cf1c", size = 40183, upload-time = "2025-05-19T14:15:40.197Z" }, { url = "https://files.pythonhosted.org/packages/e0/b7/d4b8d98eb850ef28a4922ba508c31d90715fd9b9da3801a30cea2967130b/multidict-6.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d2fa86af59f8fc1972e121ade052145f6da22758f6996a197d69bb52f8204e7e", size = 39592, upload-time = "2025-05-19T14:15:41.508Z" }, { url = "https://files.pythonhosted.org/packages/18/28/a554678898a19583548e742080cf55d169733baf57efc48c2f0273a08583/multidict-6.4.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50855d03e9e4d66eab6947ba688ffb714616f985838077bc4b490e769e48da51", size = 226071, upload-time = "2025-05-19T14:15:42.877Z" }, { url = "https://files.pythonhosted.org/packages/ee/dc/7ba6c789d05c310e294f85329efac1bf5b450338d2542498db1491a264df/multidict-6.4.4-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5bce06b83be23225be1905dcdb6b789064fae92499fbc458f59a8c0e68718601", size = 222597, upload-time = "2025-05-19T14:15:44.412Z" }, { url = "https://files.pythonhosted.org/packages/24/4f/34eadbbf401b03768dba439be0fb94b0d187facae9142821a3d5599ccb3b/multidict-6.4.4-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66ed0731f8e5dfd8369a883b6e564aca085fb9289aacabd9decd70568b9a30de", size = 228253, upload-time = "2025-05-19T14:15:46.474Z" }, { url = "https://files.pythonhosted.org/packages/c0/e6/493225a3cdb0d8d80d43a94503fc313536a07dae54a3f030d279e629a2bc/multidict-6.4.4-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:329ae97fc2f56f44d91bc47fe0972b1f52d21c4b7a2ac97040da02577e2daca2", size = 226146, upload-time = "2025-05-19T14:15:48.003Z" }, { url = "https://files.pythonhosted.org/packages/2f/70/e411a7254dc3bff6f7e6e004303b1b0591358e9f0b7c08639941e0de8bd6/multidict-6.4.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c27e5dcf520923d6474d98b96749e6805f7677e93aaaf62656005b8643f907ab", size = 220585, upload-time = "2025-05-19T14:15:49.546Z" }, { url = "https://files.pythonhosted.org/packages/08/8f/beb3ae7406a619100d2b1fb0022c3bb55a8225ab53c5663648ba50dfcd56/multidict-6.4.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:058cc59b9e9b143cc56715e59e22941a5d868c322242278d28123a5d09cdf6b0", size = 212080, upload-time = "2025-05-19T14:15:51.151Z" }, { url = "https://files.pythonhosted.org/packages/9c/ec/355124e9d3d01cf8edb072fd14947220f357e1c5bc79c88dff89297e9342/multidict-6.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:69133376bc9a03f8c47343d33f91f74a99c339e8b58cea90433d8e24bb298031", size = 226558, upload-time = "2025-05-19T14:15:52.665Z" }, { url = "https://files.pythonhosted.org/packages/fd/22/d2b95cbebbc2ada3be3812ea9287dcc9712d7f1a012fad041770afddb2ad/multidict-6.4.4-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:d6b15c55721b1b115c5ba178c77104123745b1417527ad9641a4c5e2047450f0", size = 212168, upload-time = "2025-05-19T14:15:55.279Z" }, { url = "https://files.pythonhosted.org/packages/4d/c5/62bfc0b2f9ce88326dbe7179f9824a939c6c7775b23b95de777267b9725c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a887b77f51d3d41e6e1a63cf3bc7ddf24de5939d9ff69441387dfefa58ac2e26", size = 217970, upload-time = "2025-05-19T14:15:56.806Z" }, { url = "https://files.pythonhosted.org/packages/79/74/977cea1aadc43ff1c75d23bd5bc4768a8fac98c14e5878d6ee8d6bab743c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:632a3bf8f1787f7ef7d3c2f68a7bde5be2f702906f8b5842ad6da9d974d0aab3", size = 226980, upload-time = "2025-05-19T14:15:58.313Z" }, { url = "https://files.pythonhosted.org/packages/48/fc/cc4a1a2049df2eb84006607dc428ff237af38e0fcecfdb8a29ca47b1566c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a145c550900deb7540973c5cdb183b0d24bed6b80bf7bddf33ed8f569082535e", size = 220641, upload-time = "2025-05-19T14:15:59.866Z" }, { url = "https://files.pythonhosted.org/packages/3b/6a/a7444d113ab918701988d4abdde373dbdfd2def7bd647207e2bf645c7eac/multidict-6.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc5d83c6619ca5c9672cb78b39ed8542f1975a803dee2cda114ff73cbb076edd", size = 221728, upload-time = "2025-05-19T14:16:01.535Z" }, { url = "https://files.pythonhosted.org/packages/2b/b0/fdf4c73ad1c55e0f4dbbf2aa59dd37037334091f9a4961646d2b7ac91a86/multidict-6.4.4-cp313-cp313t-win32.whl", hash = "sha256:3312f63261b9df49be9d57aaa6abf53a6ad96d93b24f9cc16cf979956355ce6e", size = 41913, upload-time = "2025-05-19T14:16:03.199Z" }, { url = "https://files.pythonhosted.org/packages/8e/92/27989ecca97e542c0d01d05a98a5ae12198a243a9ee12563a0313291511f/multidict-6.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:ba852168d814b2c73333073e1c7116d9395bea69575a01b0b3c89d2d5a87c8fb", size = 46112, upload-time = "2025-05-19T14:16:04.909Z" }, { url = "https://files.pythonhosted.org/packages/84/5d/e17845bb0fa76334477d5de38654d27946d5b5d3695443987a094a71b440/multidict-6.4.4-py3-none-any.whl", hash = "sha256:bd4557071b561a8b3b6075c3ce93cf9bfb6182cb241805c3d66ced3b75eff4ac", size = 10481, upload-time = "2025-05-19T14:16:36.024Z" }, ] [[package]] name = "mypy" version = "1.16.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions" }, { name = "pathspec" }, { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/d4/38/13c2f1abae94d5ea0354e146b95a1be9b2137a0d506728e0da037c4276f6/mypy-1.16.0.tar.gz", hash = "sha256:84b94283f817e2aa6350a14b4a8fb2a35a53c286f97c9d30f53b63620e7af8ab", size = 3323139, upload-time = "2025-05-29T13:46:12.532Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/24/c4/ff2f79db7075c274fe85b5fff8797d29c6b61b8854c39e3b7feb556aa377/mypy-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9f826aaa7ff8443bac6a494cf743f591488ea940dd360e7dd330e30dd772a5ab", size = 10884498, upload-time = "2025-05-29T13:18:54.066Z" }, { url = "https://files.pythonhosted.org/packages/02/07/12198e83006235f10f6a7808917376b5d6240a2fd5dce740fe5d2ebf3247/mypy-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:82d056e6faa508501af333a6af192c700b33e15865bda49611e3d7d8358ebea2", size = 10011755, upload-time = "2025-05-29T13:34:00.851Z" }, { url = "https://files.pythonhosted.org/packages/f1/9b/5fd5801a72b5d6fb6ec0105ea1d0e01ab2d4971893076e558d4b6d6b5f80/mypy-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:089bedc02307c2548eb51f426e085546db1fa7dd87fbb7c9fa561575cf6eb1ff", size = 11800138, upload-time = "2025-05-29T13:32:55.082Z" }, { url = "https://files.pythonhosted.org/packages/2e/81/a117441ea5dfc3746431e51d78a4aca569c677aa225bca2cc05a7c239b61/mypy-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6a2322896003ba66bbd1318c10d3afdfe24e78ef12ea10e2acd985e9d684a666", size = 12533156, upload-time = "2025-05-29T13:19:12.963Z" }, { url = "https://files.pythonhosted.org/packages/3f/38/88ec57c6c86014d3f06251e00f397b5a7daa6888884d0abf187e4f5f587f/mypy-1.16.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:021a68568082c5b36e977d54e8f1de978baf401a33884ffcea09bd8e88a98f4c", size = 12742426, upload-time = "2025-05-29T13:20:22.72Z" }, { url = "https://files.pythonhosted.org/packages/bd/53/7e9d528433d56e6f6f77ccf24af6ce570986c2d98a5839e4c2009ef47283/mypy-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:54066fed302d83bf5128632d05b4ec68412e1f03ef2c300434057d66866cea4b", size = 9478319, upload-time = "2025-05-29T13:21:17.582Z" }, { url = "https://files.pythonhosted.org/packages/70/cf/158e5055e60ca2be23aec54a3010f89dcffd788732634b344fc9cb1e85a0/mypy-1.16.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c5436d11e89a3ad16ce8afe752f0f373ae9620841c50883dc96f8b8805620b13", size = 11062927, upload-time = "2025-05-29T13:35:52.328Z" }, { url = "https://files.pythonhosted.org/packages/94/34/cfff7a56be1609f5d10ef386342ce3494158e4d506516890142007e6472c/mypy-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f2622af30bf01d8fc36466231bdd203d120d7a599a6d88fb22bdcb9dbff84090", size = 10083082, upload-time = "2025-05-29T13:35:33.378Z" }, { url = "https://files.pythonhosted.org/packages/b3/7f/7242062ec6288c33d8ad89574df87c3903d394870e5e6ba1699317a65075/mypy-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d045d33c284e10a038f5e29faca055b90eee87da3fc63b8889085744ebabb5a1", size = 11828306, upload-time = "2025-05-29T13:21:02.164Z" }, { url = "https://files.pythonhosted.org/packages/6f/5f/b392f7b4f659f5b619ce5994c5c43caab3d80df2296ae54fa888b3d17f5a/mypy-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b4968f14f44c62e2ec4a038c8797a87315be8df7740dc3ee8d3bfe1c6bf5dba8", size = 12702764, upload-time = "2025-05-29T13:20:42.826Z" }, { url = "https://files.pythonhosted.org/packages/9b/c0/7646ef3a00fa39ac9bc0938626d9ff29d19d733011be929cfea59d82d136/mypy-1.16.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:eb14a4a871bb8efb1e4a50360d4e3c8d6c601e7a31028a2c79f9bb659b63d730", size = 12896233, upload-time = "2025-05-29T13:18:37.446Z" }, { url = "https://files.pythonhosted.org/packages/6d/38/52f4b808b3fef7f0ef840ee8ff6ce5b5d77381e65425758d515cdd4f5bb5/mypy-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:bd4e1ebe126152a7bbaa4daedd781c90c8f9643c79b9748caa270ad542f12bec", size = 9565547, upload-time = "2025-05-29T13:20:02.836Z" }, { url = "https://files.pythonhosted.org/packages/97/9c/ca03bdbefbaa03b264b9318a98950a9c683e06472226b55472f96ebbc53d/mypy-1.16.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a9e056237c89f1587a3be1a3a70a06a698d25e2479b9a2f57325ddaaffc3567b", size = 11059753, upload-time = "2025-05-29T13:18:18.167Z" }, { url = "https://files.pythonhosted.org/packages/36/92/79a969b8302cfe316027c88f7dc6fee70129490a370b3f6eb11d777749d0/mypy-1.16.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b07e107affb9ee6ce1f342c07f51552d126c32cd62955f59a7db94a51ad12c0", size = 10073338, upload-time = "2025-05-29T13:19:48.079Z" }, { url = "https://files.pythonhosted.org/packages/14/9b/a943f09319167da0552d5cd722104096a9c99270719b1afeea60d11610aa/mypy-1.16.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c6fb60cbd85dc65d4d63d37cb5c86f4e3a301ec605f606ae3a9173e5cf34997b", size = 11827764, upload-time = "2025-05-29T13:46:04.47Z" }, { url = "https://files.pythonhosted.org/packages/ec/64/ff75e71c65a0cb6ee737287c7913ea155845a556c64144c65b811afdb9c7/mypy-1.16.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7e32297a437cc915599e0578fa6bc68ae6a8dc059c9e009c628e1c47f91495d", size = 12701356, upload-time = "2025-05-29T13:35:13.553Z" }, { url = "https://files.pythonhosted.org/packages/0a/ad/0e93c18987a1182c350f7a5fab70550852f9fabe30ecb63bfbe51b602074/mypy-1.16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:afe420c9380ccec31e744e8baff0d406c846683681025db3531b32db56962d52", size = 12900745, upload-time = "2025-05-29T13:17:24.409Z" }, { url = "https://files.pythonhosted.org/packages/28/5d/036c278d7a013e97e33f08c047fe5583ab4f1fc47c9a49f985f1cdd2a2d7/mypy-1.16.0-cp313-cp313-win_amd64.whl", hash = "sha256:55f9076c6ce55dd3f8cd0c6fff26a008ca8e5131b89d5ba6d86bd3f47e736eeb", size = 9572200, upload-time = "2025-05-29T13:33:44.92Z" }, { url = "https://files.pythonhosted.org/packages/99/a3/6ed10530dec8e0fdc890d81361260c9ef1f5e5c217ad8c9b21ecb2b8366b/mypy-1.16.0-py3-none-any.whl", hash = "sha256:29e1499864a3888bca5c1542f2d7232c6e586295183320caa95758fc84034031", size = 2265773, upload-time = "2025-05-29T13:35:18.762Z" }, ] [[package]] name = "mypy-extensions" version = "1.1.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, ] [[package]] name = "nh3" version = "0.2.21" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/37/30/2f81466f250eb7f591d4d193930df661c8c23e9056bdc78e365b646054d8/nh3-0.2.21.tar.gz", hash = "sha256:4990e7ee6a55490dbf00d61a6f476c9a3258e31e711e13713b2ea7d6616f670e", size = 16581, upload-time = "2025-02-25T13:38:44.619Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7f/81/b83775687fcf00e08ade6d4605f0be9c4584cb44c4973d9f27b7456a31c9/nh3-0.2.21-cp313-cp313t-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:fcff321bd60c6c5c9cb4ddf2554e22772bb41ebd93ad88171bbbb6f271255286", size = 1297678, upload-time = "2025-02-25T13:37:56.063Z" }, { url = "https://files.pythonhosted.org/packages/22/ee/d0ad8fb4b5769f073b2df6807f69a5e57ca9cea504b78809921aef460d20/nh3-0.2.21-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31eedcd7d08b0eae28ba47f43fd33a653b4cdb271d64f1aeda47001618348fde", size = 733774, upload-time = "2025-02-25T13:37:58.419Z" }, { url = "https://files.pythonhosted.org/packages/ea/76/b450141e2d384ede43fe53953552f1c6741a499a8c20955ad049555cabc8/nh3-0.2.21-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d426d7be1a2f3d896950fe263332ed1662f6c78525b4520c8e9861f8d7f0d243", size = 760012, upload-time = "2025-02-25T13:38:01.017Z" }, { url = "https://files.pythonhosted.org/packages/97/90/1182275db76cd8fbb1f6bf84c770107fafee0cb7da3e66e416bcb9633da2/nh3-0.2.21-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9d67709bc0d7d1f5797b21db26e7a8b3d15d21c9c5f58ccfe48b5328483b685b", size = 923619, upload-time = "2025-02-25T13:38:02.617Z" }, { url = "https://files.pythonhosted.org/packages/29/c7/269a7cfbec9693fad8d767c34a755c25ccb8d048fc1dfc7a7d86bc99375c/nh3-0.2.21-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:55823c5ea1f6b267a4fad5de39bc0524d49a47783e1fe094bcf9c537a37df251", size = 1000384, upload-time = "2025-02-25T13:38:04.402Z" }, { url = "https://files.pythonhosted.org/packages/68/a9/48479dbf5f49ad93f0badd73fbb48b3d769189f04c6c69b0df261978b009/nh3-0.2.21-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:818f2b6df3763e058efa9e69677b5a92f9bc0acff3295af5ed013da544250d5b", size = 918908, upload-time = "2025-02-25T13:38:06.693Z" }, { url = "https://files.pythonhosted.org/packages/d7/da/0279c118f8be2dc306e56819880b19a1cf2379472e3b79fc8eab44e267e3/nh3-0.2.21-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:b3b5c58161e08549904ac4abd450dacd94ff648916f7c376ae4b2c0652b98ff9", size = 909180, upload-time = "2025-02-25T13:38:10.941Z" }, { url = "https://files.pythonhosted.org/packages/26/16/93309693f8abcb1088ae143a9c8dbcece9c8f7fb297d492d3918340c41f1/nh3-0.2.21-cp313-cp313t-win32.whl", hash = "sha256:637d4a10c834e1b7d9548592c7aad760611415fcd5bd346f77fd8a064309ae6d", size = 532747, upload-time = "2025-02-25T13:38:12.548Z" }, { url = "https://files.pythonhosted.org/packages/a2/3a/96eb26c56cbb733c0b4a6a907fab8408ddf3ead5d1b065830a8f6a9c3557/nh3-0.2.21-cp313-cp313t-win_amd64.whl", hash = "sha256:713d16686596e556b65e7f8c58328c2df63f1a7abe1277d87625dcbbc012ef82", size = 528908, upload-time = "2025-02-25T13:38:14.059Z" }, { url = "https://files.pythonhosted.org/packages/ba/1d/b1ef74121fe325a69601270f276021908392081f4953d50b03cbb38b395f/nh3-0.2.21-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:a772dec5b7b7325780922dd904709f0f5f3a79fbf756de5291c01370f6df0967", size = 1316133, upload-time = "2025-02-25T13:38:16.601Z" }, { url = "https://files.pythonhosted.org/packages/b8/f2/2c7f79ce6de55b41e7715f7f59b159fd59f6cdb66223c05b42adaee2b645/nh3-0.2.21-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d002b648592bf3033adfd875a48f09b8ecc000abd7f6a8769ed86b6ccc70c759", size = 758328, upload-time = "2025-02-25T13:38:18.972Z" }, { url = "https://files.pythonhosted.org/packages/6d/ad/07bd706fcf2b7979c51b83d8b8def28f413b090cf0cb0035ee6b425e9de5/nh3-0.2.21-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2a5174551f95f2836f2ad6a8074560f261cf9740a48437d6151fd2d4d7d617ab", size = 747020, upload-time = "2025-02-25T13:38:20.571Z" }, { url = "https://files.pythonhosted.org/packages/75/99/06a6ba0b8a0d79c3d35496f19accc58199a1fb2dce5e711a31be7e2c1426/nh3-0.2.21-cp38-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b8d55ea1fc7ae3633d758a92aafa3505cd3cc5a6e40470c9164d54dff6f96d42", size = 944878, upload-time = "2025-02-25T13:38:22.204Z" }, { url = "https://files.pythonhosted.org/packages/79/d4/dc76f5dc50018cdaf161d436449181557373869aacf38a826885192fc587/nh3-0.2.21-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ae319f17cd8960d0612f0f0ddff5a90700fa71926ca800e9028e7851ce44a6f", size = 903460, upload-time = "2025-02-25T13:38:25.951Z" }, { url = "https://files.pythonhosted.org/packages/cd/c3/d4f8037b2ab02ebf5a2e8637bd54736ed3d0e6a2869e10341f8d9085f00e/nh3-0.2.21-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63ca02ac6f27fc80f9894409eb61de2cb20ef0a23740c7e29f9ec827139fa578", size = 839369, upload-time = "2025-02-25T13:38:28.174Z" }, { url = "https://files.pythonhosted.org/packages/11/a9/1cd3c6964ec51daed7b01ca4686a5c793581bf4492cbd7274b3f544c9abe/nh3-0.2.21-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5f77e62aed5c4acad635239ac1290404c7e940c81abe561fd2af011ff59f585", size = 739036, upload-time = "2025-02-25T13:38:30.539Z" }, { url = "https://files.pythonhosted.org/packages/fd/04/bfb3ff08d17a8a96325010ae6c53ba41de6248e63cdb1b88ef6369a6cdfc/nh3-0.2.21-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:087ffadfdcd497658c3adc797258ce0f06be8a537786a7217649fc1c0c60c293", size = 768712, upload-time = "2025-02-25T13:38:32.992Z" }, { url = "https://files.pythonhosted.org/packages/9e/aa/cfc0bf545d668b97d9adea4f8b4598667d2b21b725d83396c343ad12bba7/nh3-0.2.21-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ac7006c3abd097790e611fe4646ecb19a8d7f2184b882f6093293b8d9b887431", size = 930559, upload-time = "2025-02-25T13:38:35.204Z" }, { url = "https://files.pythonhosted.org/packages/78/9d/6f5369a801d3a1b02e6a9a097d56bcc2f6ef98cffebf03c4bb3850d8e0f0/nh3-0.2.21-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:6141caabe00bbddc869665b35fc56a478eb774a8c1dfd6fba9fe1dfdf29e6efa", size = 1008591, upload-time = "2025-02-25T13:38:37.099Z" }, { url = "https://files.pythonhosted.org/packages/a6/df/01b05299f68c69e480edff608248313cbb5dbd7595c5e048abe8972a57f9/nh3-0.2.21-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:20979783526641c81d2f5bfa6ca5ccca3d1e4472474b162c6256745fbfe31cd1", size = 925670, upload-time = "2025-02-25T13:38:38.696Z" }, { url = "https://files.pythonhosted.org/packages/3d/79/bdba276f58d15386a3387fe8d54e980fb47557c915f5448d8c6ac6f7ea9b/nh3-0.2.21-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a7ea28cd49293749d67e4fcf326c554c83ec912cd09cd94aa7ec3ab1921c8283", size = 917093, upload-time = "2025-02-25T13:38:40.249Z" }, { url = "https://files.pythonhosted.org/packages/e7/d8/c6f977a5cd4011c914fb58f5ae573b071d736187ccab31bfb1d539f4af9f/nh3-0.2.21-cp38-abi3-win32.whl", hash = "sha256:6c9c30b8b0d291a7c5ab0967ab200598ba33208f754f2f4920e9343bdd88f79a", size = 537623, upload-time = "2025-02-25T13:38:41.893Z" }, { url = "https://files.pythonhosted.org/packages/23/fc/8ce756c032c70ae3dd1d48a3552577a325475af2a2f629604b44f571165c/nh3-0.2.21-cp38-abi3-win_amd64.whl", hash = "sha256:bb0014948f04d7976aabae43fcd4cb7f551f9f8ce785a4c9ef66e6c2590f8629", size = 535283, upload-time = "2025-02-25T13:38:43.355Z" }, ] [[package]] name = "nodeenv" version = "1.9.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, ] [[package]] name = "oauthlib" version = "3.2.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/6d/fa/fbf4001037904031639e6bfbfc02badfc7e12f137a8afa254df6c4c8a670/oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918", size = 177352, upload-time = "2022-10-17T20:04:27.471Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7e/80/cab10959dc1faead58dc8384a781dfbf93cb4d33d50988f7a69f1b7c9bbe/oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca", size = 151688, upload-time = "2022-10-17T20:04:24.037Z" }, ] [[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 = "pathspec" version = "0.12.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, ] [[package]] name = "platformdirs" version = "4.3.8" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362, upload-time = "2025-05-07T22:47:42.121Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567, upload-time = "2025-05-07T22:47:40.376Z" }, ] [[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 = "pre-commit" version = "4.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cfgv" }, { name = "identify" }, { name = "nodeenv" }, { name = "pyyaml" }, { name = "virtualenv" }, ] sdist = { url = "https://files.pythonhosted.org/packages/08/39/679ca9b26c7bb2999ff122d50faa301e49af82ca9c066ec061cfbc0c6784/pre_commit-4.2.0.tar.gz", hash = "sha256:601283b9757afd87d40c4c4a9b2b5de9637a8ea02eaff7adc2d0fb4e04841146", size = 193424, upload-time = "2025-03-18T21:35:20.987Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/88/74/a88bf1b1efeae488a0c0b7bdf71429c313722d1fc0f377537fbe554e6180/pre_commit-4.2.0-py2.py3-none-any.whl", hash = "sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd", size = 220707, upload-time = "2025-03-18T21:35:19.343Z" }, ] [[package]] name = "propcache" version = "0.3.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/07/c8/fdc6686a986feae3541ea23dcaa661bd93972d3940460646c6bb96e21c40/propcache-0.3.1.tar.gz", hash = "sha256:40d980c33765359098837527e18eddefc9a24cea5b45e078a7f3bb5b032c6ecf", size = 43651, upload-time = "2025-03-26T03:06:12.05Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/90/0f/5a5319ee83bd651f75311fcb0c492c21322a7fc8f788e4eef23f44243427/propcache-0.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7f30241577d2fef2602113b70ef7231bf4c69a97e04693bde08ddab913ba0ce5", size = 80243, upload-time = "2025-03-26T03:04:01.912Z" }, { url = "https://files.pythonhosted.org/packages/ce/84/3db5537e0879942783e2256616ff15d870a11d7ac26541336fe1b673c818/propcache-0.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:43593c6772aa12abc3af7784bff4a41ffa921608dd38b77cf1dfd7f5c4e71371", size = 46503, upload-time = "2025-03-26T03:04:03.704Z" }, { url = "https://files.pythonhosted.org/packages/e2/c8/b649ed972433c3f0d827d7f0cf9ea47162f4ef8f4fe98c5f3641a0bc63ff/propcache-0.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a75801768bbe65499495660b777e018cbe90c7980f07f8aa57d6be79ea6f71da", size = 45934, upload-time = "2025-03-26T03:04:05.257Z" }, { url = "https://files.pythonhosted.org/packages/59/f9/4c0a5cf6974c2c43b1a6810c40d889769cc8f84cea676cbe1e62766a45f8/propcache-0.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6f1324db48f001c2ca26a25fa25af60711e09b9aaf4b28488602776f4f9a744", size = 233633, upload-time = "2025-03-26T03:04:07.044Z" }, { url = "https://files.pythonhosted.org/packages/e7/64/66f2f4d1b4f0007c6e9078bd95b609b633d3957fe6dd23eac33ebde4b584/propcache-0.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cdb0f3e1eb6dfc9965d19734d8f9c481b294b5274337a8cb5cb01b462dcb7e0", size = 241124, upload-time = "2025-03-26T03:04:08.676Z" }, { url = "https://files.pythonhosted.org/packages/aa/bf/7b8c9fd097d511638fa9b6af3d986adbdf567598a567b46338c925144c1b/propcache-0.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1eb34d90aac9bfbced9a58b266f8946cb5935869ff01b164573a7634d39fbcb5", size = 240283, upload-time = "2025-03-26T03:04:10.172Z" }, { url = "https://files.pythonhosted.org/packages/fa/c9/e85aeeeaae83358e2a1ef32d6ff50a483a5d5248bc38510d030a6f4e2816/propcache-0.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f35c7070eeec2cdaac6fd3fe245226ed2a6292d3ee8c938e5bb645b434c5f256", size = 232498, upload-time = "2025-03-26T03:04:11.616Z" }, { url = "https://files.pythonhosted.org/packages/8e/66/acb88e1f30ef5536d785c283af2e62931cb934a56a3ecf39105887aa8905/propcache-0.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b23c11c2c9e6d4e7300c92e022046ad09b91fd00e36e83c44483df4afa990073", size = 221486, upload-time = "2025-03-26T03:04:13.102Z" }, { url = "https://files.pythonhosted.org/packages/f5/f9/233ddb05ffdcaee4448508ee1d70aa7deff21bb41469ccdfcc339f871427/propcache-0.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3e19ea4ea0bf46179f8a3652ac1426e6dcbaf577ce4b4f65be581e237340420d", size = 222675, upload-time = "2025-03-26T03:04:14.658Z" }, { url = "https://files.pythonhosted.org/packages/98/b8/eb977e28138f9e22a5a789daf608d36e05ed93093ef12a12441030da800a/propcache-0.3.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:bd39c92e4c8f6cbf5f08257d6360123af72af9f4da75a690bef50da77362d25f", size = 215727, upload-time = "2025-03-26T03:04:16.207Z" }, { url = "https://files.pythonhosted.org/packages/89/2d/5f52d9c579f67b8ee1edd9ec073c91b23cc5b7ff7951a1e449e04ed8fdf3/propcache-0.3.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b0313e8b923b3814d1c4a524c93dfecea5f39fa95601f6a9b1ac96cd66f89ea0", size = 217878, upload-time = "2025-03-26T03:04:18.11Z" }, { url = "https://files.pythonhosted.org/packages/7a/fd/5283e5ed8a82b00c7a989b99bb6ea173db1ad750bf0bf8dff08d3f4a4e28/propcache-0.3.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e861ad82892408487be144906a368ddbe2dc6297074ade2d892341b35c59844a", size = 230558, upload-time = "2025-03-26T03:04:19.562Z" }, { url = "https://files.pythonhosted.org/packages/90/38/ab17d75938ef7ac87332c588857422ae126b1c76253f0f5b1242032923ca/propcache-0.3.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:61014615c1274df8da5991a1e5da85a3ccb00c2d4701ac6f3383afd3ca47ab0a", size = 233754, upload-time = "2025-03-26T03:04:21.065Z" }, { url = "https://files.pythonhosted.org/packages/06/5d/3b921b9c60659ae464137508d3b4c2b3f52f592ceb1964aa2533b32fcf0b/propcache-0.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:71ebe3fe42656a2328ab08933d420df5f3ab121772eef78f2dc63624157f0ed9", size = 226088, upload-time = "2025-03-26T03:04:22.718Z" }, { url = "https://files.pythonhosted.org/packages/54/6e/30a11f4417d9266b5a464ac5a8c5164ddc9dd153dfa77bf57918165eb4ae/propcache-0.3.1-cp311-cp311-win32.whl", hash = "sha256:58aa11f4ca8b60113d4b8e32d37e7e78bd8af4d1a5b5cb4979ed856a45e62005", size = 40859, upload-time = "2025-03-26T03:04:24.039Z" }, { url = "https://files.pythonhosted.org/packages/1d/3a/8a68dd867da9ca2ee9dfd361093e9cb08cb0f37e5ddb2276f1b5177d7731/propcache-0.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:9532ea0b26a401264b1365146c440a6d78269ed41f83f23818d4b79497aeabe7", size = 45153, upload-time = "2025-03-26T03:04:25.211Z" }, { url = "https://files.pythonhosted.org/packages/41/aa/ca78d9be314d1e15ff517b992bebbed3bdfef5b8919e85bf4940e57b6137/propcache-0.3.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f78eb8422acc93d7b69964012ad7048764bb45a54ba7a39bb9e146c72ea29723", size = 80430, upload-time = "2025-03-26T03:04:26.436Z" }, { url = "https://files.pythonhosted.org/packages/1a/d8/f0c17c44d1cda0ad1979af2e593ea290defdde9eaeb89b08abbe02a5e8e1/propcache-0.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:89498dd49c2f9a026ee057965cdf8192e5ae070ce7d7a7bd4b66a8e257d0c976", size = 46637, upload-time = "2025-03-26T03:04:27.932Z" }, { url = "https://files.pythonhosted.org/packages/ae/bd/c1e37265910752e6e5e8a4c1605d0129e5b7933c3dc3cf1b9b48ed83b364/propcache-0.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:09400e98545c998d57d10035ff623266927cb784d13dd2b31fd33b8a5316b85b", size = 46123, upload-time = "2025-03-26T03:04:30.659Z" }, { url = "https://files.pythonhosted.org/packages/d4/b0/911eda0865f90c0c7e9f0415d40a5bf681204da5fd7ca089361a64c16b28/propcache-0.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa8efd8c5adc5a2c9d3b952815ff8f7710cefdcaf5f2c36d26aff51aeca2f12f", size = 243031, upload-time = "2025-03-26T03:04:31.977Z" }, { url = "https://files.pythonhosted.org/packages/0a/06/0da53397c76a74271621807265b6eb61fb011451b1ddebf43213df763669/propcache-0.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2fe5c910f6007e716a06d269608d307b4f36e7babee5f36533722660e8c4a70", size = 249100, upload-time = "2025-03-26T03:04:33.45Z" }, { url = "https://files.pythonhosted.org/packages/f1/eb/13090e05bf6b963fc1653cdc922133ced467cb4b8dab53158db5a37aa21e/propcache-0.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a0ab8cf8cdd2194f8ff979a43ab43049b1df0b37aa64ab7eca04ac14429baeb7", size = 250170, upload-time = "2025-03-26T03:04:35.542Z" }, { url = "https://files.pythonhosted.org/packages/3b/4c/f72c9e1022b3b043ec7dc475a0f405d4c3e10b9b1d378a7330fecf0652da/propcache-0.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:563f9d8c03ad645597b8d010ef4e9eab359faeb11a0a2ac9f7b4bc8c28ebef25", size = 245000, upload-time = "2025-03-26T03:04:37.501Z" }, { url = "https://files.pythonhosted.org/packages/e8/fd/970ca0e22acc829f1adf5de3724085e778c1ad8a75bec010049502cb3a86/propcache-0.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb6e0faf8cb6b4beea5d6ed7b5a578254c6d7df54c36ccd3d8b3eb00d6770277", size = 230262, upload-time = "2025-03-26T03:04:39.532Z" }, { url = "https://files.pythonhosted.org/packages/c4/42/817289120c6b9194a44f6c3e6b2c3277c5b70bbad39e7df648f177cc3634/propcache-0.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1c5c7ab7f2bb3f573d1cb921993006ba2d39e8621019dffb1c5bc94cdbae81e8", size = 236772, upload-time = "2025-03-26T03:04:41.109Z" }, { url = "https://files.pythonhosted.org/packages/7c/9c/3b3942b302badd589ad6b672da3ca7b660a6c2f505cafd058133ddc73918/propcache-0.3.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:050b571b2e96ec942898f8eb46ea4bfbb19bd5502424747e83badc2d4a99a44e", size = 231133, upload-time = "2025-03-26T03:04:42.544Z" }, { url = "https://files.pythonhosted.org/packages/98/a1/75f6355f9ad039108ff000dfc2e19962c8dea0430da9a1428e7975cf24b2/propcache-0.3.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e1c4d24b804b3a87e9350f79e2371a705a188d292fd310e663483af6ee6718ee", size = 230741, upload-time = "2025-03-26T03:04:44.06Z" }, { url = "https://files.pythonhosted.org/packages/67/0c/3e82563af77d1f8731132166da69fdfd95e71210e31f18edce08a1eb11ea/propcache-0.3.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e4fe2a6d5ce975c117a6bb1e8ccda772d1e7029c1cca1acd209f91d30fa72815", size = 244047, upload-time = "2025-03-26T03:04:45.983Z" }, { url = "https://files.pythonhosted.org/packages/f7/50/9fb7cca01532a08c4d5186d7bb2da6c4c587825c0ae134b89b47c7d62628/propcache-0.3.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:feccd282de1f6322f56f6845bf1207a537227812f0a9bf5571df52bb418d79d5", size = 246467, upload-time = "2025-03-26T03:04:47.699Z" }, { url = "https://files.pythonhosted.org/packages/a9/02/ccbcf3e1c604c16cc525309161d57412c23cf2351523aedbb280eb7c9094/propcache-0.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ec314cde7314d2dd0510c6787326bbffcbdc317ecee6b7401ce218b3099075a7", size = 241022, upload-time = "2025-03-26T03:04:49.195Z" }, { url = "https://files.pythonhosted.org/packages/db/19/e777227545e09ca1e77a6e21274ae9ec45de0f589f0ce3eca2a41f366220/propcache-0.3.1-cp312-cp312-win32.whl", hash = "sha256:7d2d5a0028d920738372630870e7d9644ce437142197f8c827194fca404bf03b", size = 40647, upload-time = "2025-03-26T03:04:50.595Z" }, { url = "https://files.pythonhosted.org/packages/24/bb/3b1b01da5dd04c77a204c84e538ff11f624e31431cfde7201d9110b092b1/propcache-0.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:88c423efef9d7a59dae0614eaed718449c09a5ac79a5f224a8b9664d603f04a3", size = 44784, upload-time = "2025-03-26T03:04:51.791Z" }, { url = "https://files.pythonhosted.org/packages/58/60/f645cc8b570f99be3cf46714170c2de4b4c9d6b827b912811eff1eb8a412/propcache-0.3.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f1528ec4374617a7a753f90f20e2f551121bb558fcb35926f99e3c42367164b8", size = 77865, upload-time = "2025-03-26T03:04:53.406Z" }, { url = "https://files.pythonhosted.org/packages/6f/d4/c1adbf3901537582e65cf90fd9c26fde1298fde5a2c593f987112c0d0798/propcache-0.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dc1915ec523b3b494933b5424980831b636fe483d7d543f7afb7b3bf00f0c10f", size = 45452, upload-time = "2025-03-26T03:04:54.624Z" }, { url = "https://files.pythonhosted.org/packages/d1/b5/fe752b2e63f49f727c6c1c224175d21b7d1727ce1d4873ef1c24c9216830/propcache-0.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a110205022d077da24e60b3df8bcee73971be9575dec5573dd17ae5d81751111", size = 44800, upload-time = "2025-03-26T03:04:55.844Z" }, { url = "https://files.pythonhosted.org/packages/62/37/fc357e345bc1971e21f76597028b059c3d795c5ca7690d7a8d9a03c9708a/propcache-0.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d249609e547c04d190e820d0d4c8ca03ed4582bcf8e4e160a6969ddfb57b62e5", size = 225804, upload-time = "2025-03-26T03:04:57.158Z" }, { url = "https://files.pythonhosted.org/packages/0d/f1/16e12c33e3dbe7f8b737809bad05719cff1dccb8df4dafbcff5575002c0e/propcache-0.3.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ced33d827625d0a589e831126ccb4f5c29dfdf6766cac441d23995a65825dcb", size = 230650, upload-time = "2025-03-26T03:04:58.61Z" }, { url = "https://files.pythonhosted.org/packages/3e/a2/018b9f2ed876bf5091e60153f727e8f9073d97573f790ff7cdf6bc1d1fb8/propcache-0.3.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4114c4ada8f3181af20808bedb250da6bae56660e4b8dfd9cd95d4549c0962f7", size = 234235, upload-time = "2025-03-26T03:05:00.599Z" }, { url = "https://files.pythonhosted.org/packages/45/5f/3faee66fc930dfb5da509e34c6ac7128870631c0e3582987fad161fcb4b1/propcache-0.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:975af16f406ce48f1333ec5e912fe11064605d5c5b3f6746969077cc3adeb120", size = 228249, upload-time = "2025-03-26T03:05:02.11Z" }, { url = "https://files.pythonhosted.org/packages/62/1e/a0d5ebda5da7ff34d2f5259a3e171a94be83c41eb1e7cd21a2105a84a02e/propcache-0.3.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a34aa3a1abc50740be6ac0ab9d594e274f59960d3ad253cd318af76b996dd654", size = 214964, upload-time = "2025-03-26T03:05:03.599Z" }, { url = "https://files.pythonhosted.org/packages/db/a0/d72da3f61ceab126e9be1f3bc7844b4e98c6e61c985097474668e7e52152/propcache-0.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9cec3239c85ed15bfaded997773fdad9fb5662b0a7cbc854a43f291eb183179e", size = 222501, upload-time = "2025-03-26T03:05:05.107Z" }, { url = "https://files.pythonhosted.org/packages/18/6d/a008e07ad7b905011253adbbd97e5b5375c33f0b961355ca0a30377504ac/propcache-0.3.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:05543250deac8e61084234d5fc54f8ebd254e8f2b39a16b1dce48904f45b744b", size = 217917, upload-time = "2025-03-26T03:05:06.59Z" }, { url = "https://files.pythonhosted.org/packages/98/37/02c9343ffe59e590e0e56dc5c97d0da2b8b19fa747ebacf158310f97a79a/propcache-0.3.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5cb5918253912e088edbf023788de539219718d3b10aef334476b62d2b53de53", size = 217089, upload-time = "2025-03-26T03:05:08.1Z" }, { url = "https://files.pythonhosted.org/packages/53/1b/d3406629a2c8a5666d4674c50f757a77be119b113eedd47b0375afdf1b42/propcache-0.3.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f3bbecd2f34d0e6d3c543fdb3b15d6b60dd69970c2b4c822379e5ec8f6f621d5", size = 228102, upload-time = "2025-03-26T03:05:09.982Z" }, { url = "https://files.pythonhosted.org/packages/cd/a7/3664756cf50ce739e5f3abd48febc0be1a713b1f389a502ca819791a6b69/propcache-0.3.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aca63103895c7d960a5b9b044a83f544b233c95e0dcff114389d64d762017af7", size = 230122, upload-time = "2025-03-26T03:05:11.408Z" }, { url = "https://files.pythonhosted.org/packages/35/36/0bbabaacdcc26dac4f8139625e930f4311864251276033a52fd52ff2a274/propcache-0.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5a0a9898fdb99bf11786265468571e628ba60af80dc3f6eb89a3545540c6b0ef", size = 226818, upload-time = "2025-03-26T03:05:12.909Z" }, { url = "https://files.pythonhosted.org/packages/cc/27/4e0ef21084b53bd35d4dae1634b6d0bad35e9c58ed4f032511acca9d4d26/propcache-0.3.1-cp313-cp313-win32.whl", hash = "sha256:3a02a28095b5e63128bcae98eb59025924f121f048a62393db682f049bf4ac24", size = 40112, upload-time = "2025-03-26T03:05:14.289Z" }, { url = "https://files.pythonhosted.org/packages/a6/2c/a54614d61895ba6dd7ac8f107e2b2a0347259ab29cbf2ecc7b94fa38c4dc/propcache-0.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:813fbb8b6aea2fc9659815e585e548fe706d6f663fa73dff59a1677d4595a037", size = 44034, upload-time = "2025-03-26T03:05:15.616Z" }, { url = "https://files.pythonhosted.org/packages/5a/a8/0a4fd2f664fc6acc66438370905124ce62e84e2e860f2557015ee4a61c7e/propcache-0.3.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:a444192f20f5ce8a5e52761a031b90f5ea6288b1eef42ad4c7e64fef33540b8f", size = 82613, upload-time = "2025-03-26T03:05:16.913Z" }, { url = "https://files.pythonhosted.org/packages/4d/e5/5ef30eb2cd81576256d7b6caaa0ce33cd1d2c2c92c8903cccb1af1a4ff2f/propcache-0.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0fbe94666e62ebe36cd652f5fc012abfbc2342de99b523f8267a678e4dfdee3c", size = 47763, upload-time = "2025-03-26T03:05:18.607Z" }, { url = "https://files.pythonhosted.org/packages/87/9a/87091ceb048efeba4d28e903c0b15bcc84b7c0bf27dc0261e62335d9b7b8/propcache-0.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f011f104db880f4e2166bcdcf7f58250f7a465bc6b068dc84c824a3d4a5c94dc", size = 47175, upload-time = "2025-03-26T03:05:19.85Z" }, { url = "https://files.pythonhosted.org/packages/3e/2f/854e653c96ad1161f96194c6678a41bbb38c7947d17768e8811a77635a08/propcache-0.3.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e584b6d388aeb0001d6d5c2bd86b26304adde6d9bb9bfa9c4889805021b96de", size = 292265, upload-time = "2025-03-26T03:05:21.654Z" }, { url = "https://files.pythonhosted.org/packages/40/8d/090955e13ed06bc3496ba4a9fb26c62e209ac41973cb0d6222de20c6868f/propcache-0.3.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8a17583515a04358b034e241f952f1715243482fc2c2945fd99a1b03a0bd77d6", size = 294412, upload-time = "2025-03-26T03:05:23.147Z" }, { url = "https://files.pythonhosted.org/packages/39/e6/d51601342e53cc7582449e6a3c14a0479fab2f0750c1f4d22302e34219c6/propcache-0.3.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5aed8d8308215089c0734a2af4f2e95eeb360660184ad3912686c181e500b2e7", size = 294290, upload-time = "2025-03-26T03:05:24.577Z" }, { url = "https://files.pythonhosted.org/packages/3b/4d/be5f1a90abc1881884aa5878989a1acdafd379a91d9c7e5e12cef37ec0d7/propcache-0.3.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d8e309ff9a0503ef70dc9a0ebd3e69cf7b3894c9ae2ae81fc10943c37762458", size = 282926, upload-time = "2025-03-26T03:05:26.459Z" }, { url = "https://files.pythonhosted.org/packages/57/2b/8f61b998c7ea93a2b7eca79e53f3e903db1787fca9373af9e2cf8dc22f9d/propcache-0.3.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b655032b202028a582d27aeedc2e813299f82cb232f969f87a4fde491a233f11", size = 267808, upload-time = "2025-03-26T03:05:28.188Z" }, { url = "https://files.pythonhosted.org/packages/11/1c/311326c3dfce59c58a6098388ba984b0e5fb0381ef2279ec458ef99bd547/propcache-0.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9f64d91b751df77931336b5ff7bafbe8845c5770b06630e27acd5dbb71e1931c", size = 290916, upload-time = "2025-03-26T03:05:29.757Z" }, { url = "https://files.pythonhosted.org/packages/4b/74/91939924b0385e54dc48eb2e4edd1e4903ffd053cf1916ebc5347ac227f7/propcache-0.3.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:19a06db789a4bd896ee91ebc50d059e23b3639c25d58eb35be3ca1cbe967c3bf", size = 262661, upload-time = "2025-03-26T03:05:31.472Z" }, { url = "https://files.pythonhosted.org/packages/c2/d7/e6079af45136ad325c5337f5dd9ef97ab5dc349e0ff362fe5c5db95e2454/propcache-0.3.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:bef100c88d8692864651b5f98e871fb090bd65c8a41a1cb0ff2322db39c96c27", size = 264384, upload-time = "2025-03-26T03:05:32.984Z" }, { url = "https://files.pythonhosted.org/packages/b7/d5/ba91702207ac61ae6f1c2da81c5d0d6bf6ce89e08a2b4d44e411c0bbe867/propcache-0.3.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:87380fb1f3089d2a0b8b00f006ed12bd41bd858fabfa7330c954c70f50ed8757", size = 291420, upload-time = "2025-03-26T03:05:34.496Z" }, { url = "https://files.pythonhosted.org/packages/58/70/2117780ed7edcd7ba6b8134cb7802aada90b894a9810ec56b7bb6018bee7/propcache-0.3.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e474fc718e73ba5ec5180358aa07f6aded0ff5f2abe700e3115c37d75c947e18", size = 290880, upload-time = "2025-03-26T03:05:36.256Z" }, { url = "https://files.pythonhosted.org/packages/4a/1f/ecd9ce27710021ae623631c0146719280a929d895a095f6d85efb6a0be2e/propcache-0.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:17d1c688a443355234f3c031349da69444be052613483f3e4158eef751abcd8a", size = 287407, upload-time = "2025-03-26T03:05:37.799Z" }, { url = "https://files.pythonhosted.org/packages/3e/66/2e90547d6b60180fb29e23dc87bd8c116517d4255240ec6d3f7dc23d1926/propcache-0.3.1-cp313-cp313t-win32.whl", hash = "sha256:359e81a949a7619802eb601d66d37072b79b79c2505e6d3fd8b945538411400d", size = 42573, upload-time = "2025-03-26T03:05:39.193Z" }, { url = "https://files.pythonhosted.org/packages/cb/8f/50ad8599399d1861b4d2b6b45271f0ef6af1b09b0a2386a46dbaf19c9535/propcache-0.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:e7fb9a84c9abbf2b2683fa3e7b0d7da4d8ecf139a1c635732a8bda29c5214b0e", size = 46757, upload-time = "2025-03-26T03:05:40.811Z" }, { url = "https://files.pythonhosted.org/packages/b8/d3/c3cb8f1d6ae3b37f83e1de806713a9b3642c5895f0215a62e1a4bd6e5e34/propcache-0.3.1-py3-none-any.whl", hash = "sha256:9a8ecf38de50a7f518c21568c80f985e776397b902f1ce0b01f799aba1608b40", size = 12376, upload-time = "2025-03-26T03:06:10.5Z" }, ] [[package]] name = "pyatmo" source = { editable = "." } dependencies = [ { name = "aiohttp" }, { name = "oauthlib" }, { name = "requests" }, { name = "requests-oauthlib" }, ] [package.dev-dependencies] dev = [ { name = "anyio" }, { name = "black" }, { name = "codespell" }, { name = "docutils" }, { name = "mypy" }, { name = "pre-commit" }, { name = "pytest" }, { name = "pytest-asyncio" }, { name = "pytest-cov" }, { name = "pytest-mock" }, { name = "requests-mock" }, { name = "ruff" }, { name = "time-machine" }, { name = "tox-uv" }, { name = "twine" }, ] [package.metadata] requires-dist = [ { name = "aiohttp", specifier = ">=3.7.4,<4.0.0" }, { name = "oauthlib", specifier = "~=3.1" }, { name = "requests", specifier = "~=2.24" }, { name = "requests-oauthlib", specifier = ">=1.3,<3.0" }, ] [package.metadata.requires-dev] dev = [ { name = "anyio", specifier = ">=4.3.0" }, { name = "black", specifier = ">=24.8.0" }, { name = "codespell", specifier = ">=2.3.0" }, { name = "docutils", specifier = ">=0.21.2" }, { name = "mypy", specifier = ">=1.11.2" }, { name = "pre-commit", specifier = ">=3.8.0" }, { name = "pytest", specifier = ">=8.3.3" }, { name = "pytest-asyncio", specifier = ">=0.24.0" }, { name = "pytest-cov", specifier = ">=5.0.0" }, { name = "pytest-mock", specifier = ">=3.14.0" }, { name = "requests-mock", specifier = ">=1.12.1" }, { name = "ruff", specifier = ">=0.6.4" }, { name = "time-machine", specifier = ">=2.15.0" }, { name = "tox-uv", specifier = ">=1.25.0" }, { name = "twine", specifier = ">=6.1.0" }, ] [[package]] name = "pycparser" version = "2.22" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload-time = "2024-03-30T13:22:22.564Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" }, ] [[package]] name = "pygments" version = "2.19.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" }, ] [[package]] name = "pyproject-api" version = "1.9.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "packaging" }, ] sdist = { url = "https://files.pythonhosted.org/packages/19/fd/437901c891f58a7b9096511750247535e891d2d5a5a6eefbc9386a2b41d5/pyproject_api-1.9.1.tar.gz", hash = "sha256:43c9918f49daab37e302038fc1aed54a8c7a91a9fa935d00b9a485f37e0f5335", size = 22710, upload-time = "2025-05-12T14:41:58.025Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ef/e6/c293c06695d4a3ab0260ef124a74ebadba5f4c511ce3a4259e976902c00b/pyproject_api-1.9.1-py3-none-any.whl", hash = "sha256:7d6238d92f8962773dd75b5f0c4a6a27cce092a14b623b811dba656f3b628948", size = 13158, upload-time = "2025-05-12T14:41:56.217Z" }, ] [[package]] name = "pytest" version = "8.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, { name = "iniconfig" }, { name = "packaging" }, { name = "pluggy" }, { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fb/aa/405082ce2749be5398045152251ac69c0f3578c7077efc53431303af97ce/pytest-8.4.0.tar.gz", hash = "sha256:14d920b48472ea0dbf68e45b96cd1ffda4705f33307dcc86c676c1b5104838a6", size = 1515232, upload-time = "2025-06-02T17:36:30.03Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/2f/de/afa024cbe022b1b318a3d224125aa24939e99b4ff6f22e0ba639a2eaee47/pytest-8.4.0-py3-none-any.whl", hash = "sha256:f40f825768ad76c0977cbacdf1fd37c6f7a468e460ea6a0636078f8972d4517e", size = 363797, upload-time = "2025-06-02T17:36:27.859Z" }, ] [[package]] name = "pytest-asyncio" version = "1.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] sdist = { url = "https://files.pythonhosted.org/packages/d0/d4/14f53324cb1a6381bef29d698987625d80052bb33932d8e7cbf9b337b17c/pytest_asyncio-1.0.0.tar.gz", hash = "sha256:d15463d13f4456e1ead2594520216b225a16f781e144f8fdf6c5bb4667c48b3f", size = 46960, upload-time = "2025-05-26T04:54:40.484Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/30/05/ce271016e351fddc8399e546f6e23761967ee09c8c568bbfbecb0c150171/pytest_asyncio-1.0.0-py3-none-any.whl", hash = "sha256:4f024da9f1ef945e680dc68610b52550e36590a67fd31bb3b4943979a1f90ef3", size = 15976, upload-time = "2025-05-26T04:54:39.035Z" }, ] [[package]] name = "pytest-cov" version = "6.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "coverage", extra = ["toml"] }, { name = "pytest" }, ] sdist = { url = "https://files.pythonhosted.org/packages/25/69/5f1e57f6c5a39f81411b550027bf72842c4567ff5fd572bed1edc9e4b5d9/pytest_cov-6.1.1.tar.gz", hash = "sha256:46935f7aaefba760e716c2ebfbe1c216240b9592966e7da99ea8292d4d3e2a0a", size = 66857, upload-time = "2025-04-05T14:07:51.592Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/28/d0/def53b4a790cfb21483016430ed828f64830dd981ebe1089971cd10cab25/pytest_cov-6.1.1-py3-none-any.whl", hash = "sha256:bddf29ed2d0ab6f4df17b4c55b0a657287db8684af9c42ea546b21b1041b3dde", size = 23841, upload-time = "2025-04-05T14:07:49.641Z" }, ] [[package]] name = "pytest-mock" version = "3.14.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] sdist = { url = "https://files.pythonhosted.org/packages/71/28/67172c96ba684058a4d24ffe144d64783d2a270d0af0d9e792737bddc75c/pytest_mock-3.14.1.tar.gz", hash = "sha256:159e9edac4c451ce77a5cdb9fc5d1100708d2dd4ba3c3df572f14097351af80e", size = 33241, upload-time = "2025-05-26T13:58:45.167Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b2/05/77b60e520511c53d1c1ca75f1930c7dd8e971d0c4379b7f4b3f9644685ba/pytest_mock-3.14.1-py3-none-any.whl", hash = "sha256:178aefcd11307d874b4cd3100344e7e2d888d9791a6a1d9bfe90fbc1b74fd1d0", size = 9923, upload-time = "2025-05-26T13:58:43.487Z" }, ] [[package]] name = "python-dateutil" version = "2.9.0.post0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "six" }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] [[package]] name = "pywin32-ctypes" version = "0.2.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/85/9f/01a1a99704853cb63f253eea009390c88e7131c67e66a0a02099a8c917cb/pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755", size = 29471, upload-time = "2024-08-14T10:15:34.626Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/de/3d/8161f7711c017e01ac9f008dfddd9410dff3674334c233bde66e7ba65bbf/pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8", size = 30756, upload-time = "2024-08-14T10:15:33.187Z" }, ] [[package]] name = "pyyaml" version = "6.0.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612, upload-time = "2024-08-06T20:32:03.408Z" }, { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040, upload-time = "2024-08-06T20:32:04.926Z" }, { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829, upload-time = "2024-08-06T20:32:06.459Z" }, { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167, upload-time = "2024-08-06T20:32:08.338Z" }, { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952, upload-time = "2024-08-06T20:32:14.124Z" }, { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301, upload-time = "2024-08-06T20:32:16.17Z" }, { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638, upload-time = "2024-08-06T20:32:18.555Z" }, { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850, upload-time = "2024-08-06T20:32:19.889Z" }, { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980, upload-time = "2024-08-06T20:32:21.273Z" }, { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" }, { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" }, { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" }, { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" }, { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" }, { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" }, { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" }, { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" }, { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" }, { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, ] [[package]] name = "readme-renderer" version = "44.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "docutils" }, { name = "nh3" }, { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/5a/a9/104ec9234c8448c4379768221ea6df01260cd6c2ce13182d4eac531c8342/readme_renderer-44.0.tar.gz", hash = "sha256:8712034eabbfa6805cacf1402b4eeb2a73028f72d1166d6f5cb7f9c047c5d1e1", size = 32056, upload-time = "2024-07-08T15:00:57.805Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-py3-none-any.whl", hash = "sha256:2fbca89b81a08526aadf1357a8c2ae889ec05fb03f5da67f9769c9a592166151", size = 13310, upload-time = "2024-07-08T15:00:56.577Z" }, ] [[package]] name = "requests" version = "2.32.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "charset-normalizer" }, { name = "idna" }, { name = "urllib3" }, ] sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218, upload-time = "2024-05-29T15:37:49.536Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928, upload-time = "2024-05-29T15:37:47.027Z" }, ] [[package]] name = "requests-mock" version = "1.12.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "requests" }, ] sdist = { url = "https://files.pythonhosted.org/packages/92/32/587625f91f9a0a3d84688bf9cfc4b2480a7e8ec327cefd0ff2ac891fd2cf/requests-mock-1.12.1.tar.gz", hash = "sha256:e9e12e333b525156e82a3c852f22016b9158220d2f47454de9cae8a77d371401", size = 60901, upload-time = "2024-03-29T03:54:29.446Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/97/ec/889fbc557727da0c34a33850950310240f2040f3b1955175fdb2b36a8910/requests_mock-1.12.1-py2.py3-none-any.whl", hash = "sha256:b1e37054004cdd5e56c84454cc7df12b25f90f382159087f4b6915aaeef39563", size = 27695, upload-time = "2024-03-29T03:54:27.64Z" }, ] [[package]] name = "requests-oauthlib" version = "2.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "oauthlib" }, { name = "requests" }, ] sdist = { url = "https://files.pythonhosted.org/packages/42/f2/05f29bc3913aea15eb670be136045bf5c5bbf4b99ecb839da9b422bb2c85/requests-oauthlib-2.0.0.tar.gz", hash = "sha256:b3dffaebd884d8cd778494369603a9e7b58d29111bf6b41bdc2dcd87203af4e9", size = 55650, upload-time = "2024-03-22T20:32:29.939Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3b/5d/63d4ae3b9daea098d5d6f5da83984853c1bbacd5dc826764b249fe119d24/requests_oauthlib-2.0.0-py2.py3-none-any.whl", hash = "sha256:7dd8a5c40426b779b0868c404bdef9768deccf22749cde15852df527e6269b36", size = 24179, upload-time = "2024-03-22T20:32:28.055Z" }, ] [[package]] name = "requests-toolbelt" version = "1.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "requests" }, ] sdist = { url = "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", size = 206888, upload-time = "2023-05-01T04:11:33.229Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481, upload-time = "2023-05-01T04:11:28.427Z" }, ] [[package]] name = "rfc3986" version = "2.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/85/40/1520d68bfa07ab5a6f065a186815fb6610c86fe957bc065754e47f7b0840/rfc3986-2.0.0.tar.gz", hash = "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c", size = 49026, upload-time = "2022-01-10T00:52:30.832Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ff/9a/9afaade874b2fa6c752c36f1548f718b5b83af81ed9b76628329dab81c1b/rfc3986-2.0.0-py2.py3-none-any.whl", hash = "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd", size = 31326, upload-time = "2022-01-10T00:52:29.594Z" }, ] [[package]] name = "rich" version = "14.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown-it-py" }, { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/a1/53/830aa4c3066a8ab0ae9a9955976fb770fe9c6102117c8ec4ab3ea62d89e8/rich-14.0.0.tar.gz", hash = "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725", size = 224078, upload-time = "2025-03-30T14:15:14.23Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/0d/9b/63f4c7ebc259242c89b3acafdb37b41d1185c07ff0011164674e9076b491/rich-14.0.0-py3-none-any.whl", hash = "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0", size = 243229, upload-time = "2025-03-30T14:15:12.283Z" }, ] [[package]] name = "ruff" version = "0.11.12" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/15/0a/92416b159ec00cdf11e5882a9d80d29bf84bba3dbebc51c4898bfbca1da6/ruff-0.11.12.tar.gz", hash = "sha256:43cf7f69c7d7c7d7513b9d59c5d8cafd704e05944f978614aa9faff6ac202603", size = 4202289, upload-time = "2025-05-29T13:31:40.037Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/60/cc/53eb79f012d15e136d40a8e8fc519ba8f55a057f60b29c2df34efd47c6e3/ruff-0.11.12-py3-none-linux_armv6l.whl", hash = "sha256:c7680aa2f0d4c4f43353d1e72123955c7a2159b8646cd43402de6d4a3a25d7cc", size = 10285597, upload-time = "2025-05-29T13:30:57.539Z" }, { url = "https://files.pythonhosted.org/packages/e7/d7/73386e9fb0232b015a23f62fea7503f96e29c29e6c45461d4a73bac74df9/ruff-0.11.12-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:2cad64843da9f134565c20bcc430642de897b8ea02e2e79e6e02a76b8dcad7c3", size = 11053154, upload-time = "2025-05-29T13:31:00.865Z" }, { url = "https://files.pythonhosted.org/packages/4e/eb/3eae144c5114e92deb65a0cb2c72326c8469e14991e9bc3ec0349da1331c/ruff-0.11.12-py3-none-macosx_11_0_arm64.whl", hash = "sha256:9b6886b524a1c659cee1758140138455d3c029783d1b9e643f3624a5ee0cb0aa", size = 10403048, upload-time = "2025-05-29T13:31:03.413Z" }, { url = "https://files.pythonhosted.org/packages/29/64/20c54b20e58b1058db6689e94731f2a22e9f7abab74e1a758dfba058b6ca/ruff-0.11.12-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cc3a3690aad6e86c1958d3ec3c38c4594b6ecec75c1f531e84160bd827b2012", size = 10597062, upload-time = "2025-05-29T13:31:05.539Z" }, { url = "https://files.pythonhosted.org/packages/29/3a/79fa6a9a39422a400564ca7233a689a151f1039110f0bbbabcb38106883a/ruff-0.11.12-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f97fdbc2549f456c65b3b0048560d44ddd540db1f27c778a938371424b49fe4a", size = 10155152, upload-time = "2025-05-29T13:31:07.986Z" }, { url = "https://files.pythonhosted.org/packages/e5/a4/22c2c97b2340aa968af3a39bc38045e78d36abd4ed3fa2bde91c31e712e3/ruff-0.11.12-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74adf84960236961090e2d1348c1a67d940fd12e811a33fb3d107df61eef8fc7", size = 11723067, upload-time = "2025-05-29T13:31:10.57Z" }, { url = "https://files.pythonhosted.org/packages/bc/cf/3e452fbd9597bcd8058856ecd42b22751749d07935793a1856d988154151/ruff-0.11.12-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b56697e5b8bcf1d61293ccfe63873aba08fdbcbbba839fc046ec5926bdb25a3a", size = 12460807, upload-time = "2025-05-29T13:31:12.88Z" }, { url = "https://files.pythonhosted.org/packages/2f/ec/8f170381a15e1eb7d93cb4feef8d17334d5a1eb33fee273aee5d1f8241a3/ruff-0.11.12-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d47afa45e7b0eaf5e5969c6b39cbd108be83910b5c74626247e366fd7a36a13", size = 12063261, upload-time = "2025-05-29T13:31:15.236Z" }, { url = "https://files.pythonhosted.org/packages/0d/bf/57208f8c0a8153a14652a85f4116c0002148e83770d7a41f2e90b52d2b4e/ruff-0.11.12-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:692bf9603fe1bf949de8b09a2da896f05c01ed7a187f4a386cdba6760e7f61be", size = 11329601, upload-time = "2025-05-29T13:31:18.68Z" }, { url = "https://files.pythonhosted.org/packages/c3/56/edf942f7fdac5888094d9ffa303f12096f1a93eb46570bcf5f14c0c70880/ruff-0.11.12-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08033320e979df3b20dba567c62f69c45e01df708b0f9c83912d7abd3e0801cd", size = 11522186, upload-time = "2025-05-29T13:31:21.216Z" }, { url = "https://files.pythonhosted.org/packages/ed/63/79ffef65246911ed7e2290aeece48739d9603b3a35f9529fec0fc6c26400/ruff-0.11.12-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:929b7706584f5bfd61d67d5070f399057d07c70585fa8c4491d78ada452d3bef", size = 10449032, upload-time = "2025-05-29T13:31:23.417Z" }, { url = "https://files.pythonhosted.org/packages/88/19/8c9d4d8a1c2a3f5a1ea45a64b42593d50e28b8e038f1aafd65d6b43647f3/ruff-0.11.12-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7de4a73205dc5756b8e09ee3ed67c38312dce1aa28972b93150f5751199981b5", size = 10129370, upload-time = "2025-05-29T13:31:25.777Z" }, { url = "https://files.pythonhosted.org/packages/bc/0f/2d15533eaa18f460530a857e1778900cd867ded67f16c85723569d54e410/ruff-0.11.12-py3-none-musllinux_1_2_i686.whl", hash = "sha256:2635c2a90ac1b8ca9e93b70af59dfd1dd2026a40e2d6eebaa3efb0465dd9cf02", size = 11123529, upload-time = "2025-05-29T13:31:28.396Z" }, { url = "https://files.pythonhosted.org/packages/4f/e2/4c2ac669534bdded835356813f48ea33cfb3a947dc47f270038364587088/ruff-0.11.12-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d05d6a78a89166f03f03a198ecc9d18779076ad0eec476819467acb401028c0c", size = 11577642, upload-time = "2025-05-29T13:31:30.647Z" }, { url = "https://files.pythonhosted.org/packages/a7/9b/c9ddf7f924d5617a1c94a93ba595f4b24cb5bc50e98b94433ab3f7ad27e5/ruff-0.11.12-py3-none-win32.whl", hash = "sha256:f5a07f49767c4be4772d161bfc049c1f242db0cfe1bd976e0f0886732a4765d6", size = 10475511, upload-time = "2025-05-29T13:31:32.917Z" }, { url = "https://files.pythonhosted.org/packages/fd/d6/74fb6d3470c1aada019ffff33c0f9210af746cca0a4de19a1f10ce54968a/ruff-0.11.12-py3-none-win_amd64.whl", hash = "sha256:5a4d9f8030d8c3a45df201d7fb3ed38d0219bccd7955268e863ee4a115fa0832", size = 11523573, upload-time = "2025-05-29T13:31:35.782Z" }, { url = "https://files.pythonhosted.org/packages/44/42/d58086ec20f52d2b0140752ae54b355ea2be2ed46f914231136dd1effcc7/ruff-0.11.12-py3-none-win_arm64.whl", hash = "sha256:65194e37853158d368e333ba282217941029a28ea90913c67e558c611d04daa5", size = 10697770, upload-time = "2025-05-29T13:31:38.009Z" }, ] [[package]] name = "secretstorage" version = "3.3.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cryptography" }, { name = "jeepney" }, ] sdist = { url = "https://files.pythonhosted.org/packages/53/a4/f48c9d79cb507ed1373477dbceaba7401fd8a23af63b837fa61f1dcd3691/SecretStorage-3.3.3.tar.gz", hash = "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77", size = 19739, upload-time = "2022-08-13T16:22:46.976Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/54/24/b4293291fa1dd830f353d2cb163295742fa87f179fcc8a20a306a81978b7/SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99", size = 15221, upload-time = "2022-08-13T16:22:44.457Z" }, ] [[package]] name = "six" version = "1.17.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] [[package]] name = "sniffio" version = "1.3.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, ] [[package]] name = "time-machine" version = "2.16.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "python-dateutil" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fb/dd/5022939b9cadefe3af04f4012186c29b8afbe858b1ec2cfa38baeec94dab/time_machine-2.16.0.tar.gz", hash = "sha256:4a99acc273d2f98add23a89b94d4dd9e14969c01214c8514bfa78e4e9364c7e2", size = 24626, upload-time = "2024-10-08T14:21:59.734Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/38/7b/34aad93f75f86503dd1fa53bc120d8129fe4de83aef58ffa78c62b044ef9/time_machine-2.16.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8f936566ef9f09136a3d5db305961ef6d897b76b240c9ff4199144aed6dd4fe5", size = 20169, upload-time = "2024-10-08T14:21:06.288Z" }, { url = "https://files.pythonhosted.org/packages/68/cb/7d020d5c05d0460a4a96232b0777882ef989c1e6144d11ba984c4b0b4d1a/time_machine-2.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5886e23ede3478ca2a3e0a641f5d09dd784dfa9e48c96e8e5e31fc4fe77b6dc0", size = 16614, upload-time = "2024-10-08T14:21:07.253Z" }, { url = "https://files.pythonhosted.org/packages/0d/24/ce1ff76c9a4f3be88c2b947f2411a5a8019390734597d3106a151f8a9416/time_machine-2.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c76caf539fa4941e1817b7c482c87c65c52a1903fea761e84525955c6106fafb", size = 32507, upload-time = "2024-10-08T14:21:08.289Z" }, { url = "https://files.pythonhosted.org/packages/08/d7/ba1135587bd2ed105e59ed7e05969c913277d110fecc0ed871006ea3f763/time_machine-2.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:298aa423e07c8b21b991782f01d7749c871c792319c2af3e9755f9ab49033212", size = 30627, upload-time = "2024-10-08T14:21:09.246Z" }, { url = "https://files.pythonhosted.org/packages/da/c6/f490aaddc80c54238f4b8fe97870bbfe0d2c70fe4a57269badc94f5f38a6/time_machine-2.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391ae9c484736850bb44ef125cbad52fe2d1b69e42c95dc88c43af8ead2cc7", size = 32362, upload-time = "2024-10-08T14:21:10.178Z" }, { url = "https://files.pythonhosted.org/packages/b1/f7/2522ae1c1995a39d6d8b7ee7efed47ec8bd7ff3240fdb2662a8b7e11b84a/time_machine-2.16.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:503e7ff507c2089699d91885fc5b9c8ff16774a7b6aff48b4dcee0c0a0685b61", size = 32188, upload-time = "2024-10-08T14:21:11.743Z" }, { url = "https://files.pythonhosted.org/packages/e9/53/b1ccb55f39e7e62660f852d7aedef438d2872ea9c73f64be46d0d3b3f3d7/time_machine-2.16.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:eee7b0fc4fbab2c6585ea17606c6548be83919c70deea0865409fe9fc2d8cdce", size = 30600, upload-time = "2024-10-08T14:21:12.728Z" }, { url = "https://files.pythonhosted.org/packages/19/1f/37a5a9333a2da35b0fc43e8ac693b82dd5492892131bc3cc0c8f5835af94/time_machine-2.16.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9db5e5b3ccdadaafa5730c2f9db44c38b013234c9ad01f87738907e19bdba268", size = 31896, upload-time = "2024-10-08T14:21:14.451Z" }, { url = "https://files.pythonhosted.org/packages/fc/97/e1a8bd64e5432adf47859cb63847b4472efc644b508602141c60ccf52112/time_machine-2.16.0-cp311-cp311-win32.whl", hash = "sha256:2552f0767bc10c9d668f108fef9b487809cdeb772439ce932e74136365c69baf", size = 19030, upload-time = "2024-10-08T14:21:15.662Z" }, { url = "https://files.pythonhosted.org/packages/34/c9/f4764e447aa9da4031c89da60fa69f4f73fd45571415788c298cbd4620e9/time_machine-2.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:12474fcdbc475aa6fe5275fe7224e685c5b9777f5939647f35980e9614ae7558", size = 19924, upload-time = "2024-10-08T14:21:17.324Z" }, { url = "https://files.pythonhosted.org/packages/8a/c0/788500d33656a044e3289b814106c2277209ac73316c00b9668012ce6027/time_machine-2.16.0-cp311-cp311-win_arm64.whl", hash = "sha256:ac2df0fa564356384515ed62cb6679f33f1f529435b16b0ec0f88414635dbe39", size = 17993, upload-time = "2024-10-08T14:21:18.346Z" }, { url = "https://files.pythonhosted.org/packages/4a/f4/603a84e7ae6427a53953db9f61b689dc6adf233e03c5f5ca907a901452fd/time_machine-2.16.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:84788f4d62a8b1bf5e499bb9b0e23ceceea21c415ad6030be6267ce3d639842f", size = 20155, upload-time = "2024-10-08T14:21:20.055Z" }, { url = "https://files.pythonhosted.org/packages/d8/94/dbe69aecb4b84be52d34814e63176c5ca61f38ee9e6ecda11104653405b5/time_machine-2.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:15ec236b6571730236a193d9d6c11d472432fc6ab54e85eac1c16d98ddcd71bf", size = 16640, upload-time = "2024-10-08T14:21:22.005Z" }, { url = "https://files.pythonhosted.org/packages/da/13/27f11be25d7bd298e033b9da93217e5b68309bf724b6e494cdadb471d00d/time_machine-2.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cedc989717c8b44a3881ac3d68ab5a95820448796c550de6a2149ed1525157f0", size = 33721, upload-time = "2024-10-08T14:21:23.059Z" }, { url = "https://files.pythonhosted.org/packages/e6/9d/70e4640fed1fd8122204ae825c688d0ef8c04f515ec6bf3c5f3086d6510e/time_machine-2.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d26d79de1c63a8c6586c75967e09b0ff306aa7e944a1eaddb74595c9b1839ca", size = 31646, upload-time = "2024-10-08T14:21:24.037Z" }, { url = "https://files.pythonhosted.org/packages/a1/cb/93bc0e51bea4e171a85151dbba3c3b3f612b50b953cd3076f5b4f0db9e14/time_machine-2.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:317b68b56a9c3731e0cf8886e0f94230727159e375988b36c60edce0ddbcb44a", size = 33403, upload-time = "2024-10-08T14:21:24.975Z" }, { url = "https://files.pythonhosted.org/packages/89/71/2c6a63ad4fbce3d62d46bbd9ac4433f30bade7f25978ce00815b905bcfcf/time_machine-2.16.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:43e1e18279759897be3293a255d53e6b1cb0364b69d9591d0b80c51e461c94b0", size = 33327, upload-time = "2024-10-08T14:21:25.958Z" }, { url = "https://files.pythonhosted.org/packages/68/4e/205c2b26763b8817cd6b8868242843800a1fbf275f2af35f5ba35ff2b01a/time_machine-2.16.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e43adb22def972a29d2b147999b56897116085777a0fea182fd93ee45730611e", size = 31454, upload-time = "2024-10-08T14:21:27.367Z" }, { url = "https://files.pythonhosted.org/packages/d7/95/44c1aa3994919f93534244c40cfd2fb9416d7686dc0c8b9b262c751b5118/time_machine-2.16.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0c766bea27a0600e36806d628ebc4b47178b12fcdfb6c24dc0a566a9c06bfe7f", size = 32972, upload-time = "2024-10-08T14:21:28.351Z" }, { url = "https://files.pythonhosted.org/packages/d4/ee/75243df9c7cf30f108758e887141a58e6544baaa46e2e647b9ccc56db819/time_machine-2.16.0-cp312-cp312-win32.whl", hash = "sha256:6dae82ab647d107817e013db82223e20a9853fa88543fec853ae326382d03c2e", size = 19078, upload-time = "2024-10-08T14:21:29.425Z" }, { url = "https://files.pythonhosted.org/packages/d4/7c/d4e67cc031f9653c92167ccf87d241e3208653d191c96ac79281c273ab92/time_machine-2.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:265462c77dc9576267c3c7f20707780a171a9fdbac93ac22e608c309efd68c33", size = 19923, upload-time = "2024-10-08T14:21:30.759Z" }, { url = "https://files.pythonhosted.org/packages/aa/b6/7047226fcb9afefe47fc80f605530535bf71ad99b6797f057abbfa4cd9a5/time_machine-2.16.0-cp312-cp312-win_arm64.whl", hash = "sha256:ef768e14768eebe3bb1196c0dece8e14c1c6991605721214a0c3c68cf77eb216", size = 18003, upload-time = "2024-10-08T14:21:32.662Z" }, { url = "https://files.pythonhosted.org/packages/a6/18/3087d0eb185cedbc82385f46bf16032ec7102a0e070205a2c88c4ecf9952/time_machine-2.16.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7751bf745d54e9e8b358c0afa332815da9b8a6194b26d0fd62876ab6c4d5c9c0", size = 20209, upload-time = "2024-10-08T14:21:34.222Z" }, { url = "https://files.pythonhosted.org/packages/03/a3/fcc3eaf69390402ecf491d718e533b6d0e06d944d77fc8d87be3a2839102/time_machine-2.16.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1784edf173ca840ba154de6eed000b5727f65ab92972c2f88cec5c4d6349c5f2", size = 16681, upload-time = "2024-10-08T14:21:35.14Z" }, { url = "https://files.pythonhosted.org/packages/a2/96/8b76d264014bf9dc21873218de50d67223c71736f87fe6c65e582f7c29ac/time_machine-2.16.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f5876a5682ce1f517e55d7ace2383432627889f6f7e338b961f99d684fd9e8d", size = 33768, upload-time = "2024-10-08T14:21:36.942Z" }, { url = "https://files.pythonhosted.org/packages/5c/13/59ae8259be02b6c657ef6e3b6952bf274b43849f6f35cc61a576c68ce301/time_machine-2.16.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:806672529a2e255cd901f244c9033767dc1fa53466d0d3e3e49565a1572a64fe", size = 31685, upload-time = "2024-10-08T14:21:37.881Z" }, { url = "https://files.pythonhosted.org/packages/3e/c1/9f142beb4d373a2a01ebb58d5117289315baa5131d880ec804db49e94bf7/time_machine-2.16.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:667b150fedb54acdca2a4bea5bf6da837b43e6dd12857301b48191f8803ba93f", size = 33447, upload-time = "2024-10-08T14:21:38.809Z" }, { url = "https://files.pythonhosted.org/packages/95/f7/ed9ecd93c2d38dca77d0a28e070020f3ce0fb23e0d4a6edb14bcfffa5526/time_machine-2.16.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:da3ae1028af240c0c46c79adf9c1acffecc6ed1701f2863b8132f5ceae6ae4b5", size = 33408, upload-time = "2024-10-08T14:21:39.785Z" }, { url = "https://files.pythonhosted.org/packages/91/40/d0d274d70fa2c4cad531745deb8c81346365beb0a2736be05a3acde8b94a/time_machine-2.16.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:520a814ea1b2706c89ab260a54023033d3015abef25c77873b83e3d7c1fafbb2", size = 31526, upload-time = "2024-10-08T14:21:40.769Z" }, { url = "https://files.pythonhosted.org/packages/1d/ba/a27cdbb324d9a6d779cde0d514d47b696b5a6a653705d4b511fd65ef1514/time_machine-2.16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8243664438bb468408b29c6865958662d75e51f79c91842d2794fa22629eb697", size = 33042, upload-time = "2024-10-08T14:21:41.722Z" }, { url = "https://files.pythonhosted.org/packages/72/63/64e9156c9e38c18720d0cc41378168635241de44013ffe3dd5b099447eb0/time_machine-2.16.0-cp313-cp313-win32.whl", hash = "sha256:32d445ce20d25c60ab92153c073942b0bac9815bfbfd152ce3dcc225d15ce988", size = 19108, upload-time = "2024-10-08T14:21:43.596Z" }, { url = "https://files.pythonhosted.org/packages/3d/40/27f5738fbd50b78dcc0682c14417eac5a49ccf430525dd0c5a058be125a2/time_machine-2.16.0-cp313-cp313-win_amd64.whl", hash = "sha256:f6927dda86425f97ffda36131f297b1a601c64a6ee6838bfa0e6d3149c2f0d9f", size = 19935, upload-time = "2024-10-08T14:21:45.277Z" }, { url = "https://files.pythonhosted.org/packages/35/75/c4d8b2f0fe7dac22854d88a9c509d428e78ac4bf284bc54cfe83f75cc13b/time_machine-2.16.0-cp313-cp313-win_arm64.whl", hash = "sha256:4d3843143c46dddca6491a954bbd0abfd435681512ac343169560e9bab504129", size = 18047, upload-time = "2024-10-08T14:21:46.261Z" }, ] [[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 = "tox" version = "4.26.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cachetools" }, { name = "chardet" }, { name = "colorama" }, { name = "filelock" }, { name = "packaging" }, { name = "platformdirs" }, { name = "pluggy" }, { name = "pyproject-api" }, { name = "virtualenv" }, ] sdist = { url = "https://files.pythonhosted.org/packages/fd/3c/dcec0c00321a107f7f697fd00754c5112572ea6dcacb40b16d8c3eea7c37/tox-4.26.0.tar.gz", hash = "sha256:a83b3b67b0159fa58e44e646505079e35a43317a62d2ae94725e0586266faeca", size = 197260, upload-time = "2025-05-13T15:04:28.481Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/de/14/f58b4087cf248b18c795b5c838c7a8d1428dfb07cb468dad3ec7f54041ab/tox-4.26.0-py3-none-any.whl", hash = "sha256:75f17aaf09face9b97bd41645028d9f722301e912be8b4c65a3f938024560224", size = 172761, upload-time = "2025-05-13T15:04:26.207Z" }, ] [[package]] name = "tox-uv" version = "1.26.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "packaging" }, { name = "tox" }, { name = "uv" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7e/da/37790b4a176f05b0ec7a699f54979078fc726f743640aa5c10c551c27edb/tox_uv-1.26.0.tar.gz", hash = "sha256:5045880c467eed58a98f7eaa7fe286b7ef688e2c56f2123d53e275011495c381", size = 21523, upload-time = "2025-05-27T14:51:42.702Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/46/b8/04c5cb83da072a3f96d357d68a551f5e97e162573c2011a09437df995811/tox_uv-1.26.0-py3-none-any.whl", hash = "sha256:894b2e7274fd6131c3bd1012813edc858753cad67727050c21cd973a08e691c8", size = 16562, upload-time = "2025-05-27T14:51:40.803Z" }, ] [[package]] name = "twine" version = "6.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "id" }, { name = "keyring", marker = "platform_machine != 'ppc64le' and platform_machine != 's390x'" }, { name = "packaging" }, { name = "readme-renderer" }, { name = "requests" }, { name = "requests-toolbelt" }, { name = "rfc3986" }, { name = "rich" }, { name = "urllib3" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c8/a2/6df94fc5c8e2170d21d7134a565c3a8fb84f9797c1dd65a5976aaf714418/twine-6.1.0.tar.gz", hash = "sha256:be324f6272eff91d07ee93f251edf232fc647935dd585ac003539b42404a8dbd", size = 168404, upload-time = "2025-01-21T18:45:26.758Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/7c/b6/74e927715a285743351233f33ea3c684528a0d374d2e43ff9ce9585b73fe/twine-6.1.0-py3-none-any.whl", hash = "sha256:a47f973caf122930bf0fbbf17f80b83bc1602c9ce393c7845f289a3001dc5384", size = 40791, upload-time = "2025-01-21T18:45:24.584Z" }, ] [[package]] name = "typing-extensions" version = "4.14.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d1/bc/51647cd02527e87d05cb083ccc402f93e441606ff1f01739a62c8ad09ba5/typing_extensions-4.14.0.tar.gz", hash = "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4", size = 107423, upload-time = "2025-06-02T14:52:11.399Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/69/e0/552843e0d356fbb5256d21449fa957fa4eff3bbc135a74a691ee70c7c5da/typing_extensions-4.14.0-py3-none-any.whl", hash = "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af", size = 43839, upload-time = "2025-06-02T14:52:10.026Z" }, ] [[package]] name = "urllib3" version = "2.4.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/8a/78/16493d9c386d8e60e442a35feac5e00f0913c0f4b7c217c11e8ec2ff53e0/urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466", size = 390672, upload-time = "2025-04-10T15:23:39.232Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/6b/11/cc635220681e93a0183390e26485430ca2c7b5f9d33b15c74c2861cb8091/urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813", size = 128680, upload-time = "2025-04-10T15:23:37.377Z" }, ] [[package]] name = "uv" version = "0.7.9" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/9a/7c/8621d5928111f985196dc75c50a64147b3bad39f36164686f24d45581367/uv-0.7.9.tar.gz", hash = "sha256:baac54e49f3b0d05ee83f534fdcb27b91d2923c585bf349a1532ca25d62c216f", size = 3272882, upload-time = "2025-05-30T19:54:33.003Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/c5/7a/e4d12029e16f30279ef48f387545f8f3974dc3c4c9d8ef59c381ae7e6a7d/uv-0.7.9-py3-none-linux_armv6l.whl", hash = "sha256:0f8c53d411f95cec2fa19471c23b41ec456fc0d5f2efca96480d94e0c34026c2", size = 16746809, upload-time = "2025-05-30T19:53:35.447Z" }, { url = "https://files.pythonhosted.org/packages/fc/85/8df3ca683e1a260117efa31373e91e1c03a4862b7add865662f60a967fdf/uv-0.7.9-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:85c1a63669e49b825923fc876b7467cc3c20d4aa010f522c0ac8b0f30ce2b18e", size = 16821006, upload-time = "2025-05-30T19:53:40.102Z" }, { url = "https://files.pythonhosted.org/packages/77/d4/c40502ec8f5575798b7ec13ac38c0d5ded84cc32129c1d74a47f8cb7bc0a/uv-0.7.9-py3-none-macosx_11_0_arm64.whl", hash = "sha256:aa10c61668f94515acf93f31dbb8de41b1f2e7a9c41db828f2448cef786498ff", size = 15600148, upload-time = "2025-05-30T19:53:43.513Z" }, { url = "https://files.pythonhosted.org/packages/4f/dd/4deec6d5b556f4033d6bcc35d6aad70c08acea3f5da749cb34112dced5da/uv-0.7.9-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:9de67ca9ea97db71e5697c1320508e25679fb68d4ee2cea27bbeac499a6bad56", size = 16038119, upload-time = "2025-05-30T19:53:46.504Z" }, { url = "https://files.pythonhosted.org/packages/cb/c5/2c23763e18566a9a7767738714791203cc97a7530979f61e0fd32d8473a2/uv-0.7.9-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:13ce63524f88228152edf8a9c1c07cecc07d69a2853b32ecc02ac73538aaa5c1", size = 16467257, upload-time = "2025-05-30T19:53:49.592Z" }, { url = "https://files.pythonhosted.org/packages/da/94/f452d0093f466f9f81a2ede3ea2d48632237b79eb1dc595c7c91be309de5/uv-0.7.9-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3453b7bb65eaea87c9129e27bff701007a8bd1a563249982a1ede7ec4357ced6", size = 17170719, upload-time = "2025-05-30T19:53:52.828Z" }, { url = "https://files.pythonhosted.org/packages/69/bf/e15ef77520e9bbf00d29a3b639dfaf4fe63996863d6db00c53eba19535c7/uv-0.7.9-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d7b1e36a8b39600d0f0333bf50c966e83beeaaee1a38380ccb0f16ab45f351c3", size = 18052903, upload-time = "2025-05-30T19:53:56.237Z" }, { url = "https://files.pythonhosted.org/packages/32/9f/ebf3f9910121ef037c0fe9e7e7fb5f1c25b77d41a65a029d5cbcd85cc886/uv-0.7.9-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ab412ed3d415f07192805788669c8a89755086cdd6fe9f021e1ba21781728031", size = 17771828, upload-time = "2025-05-30T19:53:59.561Z" }, { url = "https://files.pythonhosted.org/packages/fe/6c/82b4cd471432e721c239ddde2ebee2e674238f3bd88e279e6c71f3cbc775/uv-0.7.9-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cbeb229ee86f69913f5f9236ff1b8ccbae212f559d7f029f8432fa8d9abcc7e0", size = 17886161, upload-time = "2025-05-30T19:54:02.865Z" }, { url = "https://files.pythonhosted.org/packages/63/e2/922d2eed25647b50a7257a7bfea10c36d9ff910d1451f9a1ba5e31766f41/uv-0.7.9-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1d654a14d632ecb078969ae7252d89dd98c89205df567a1eff18b5f078a6d00", size = 17442630, upload-time = "2025-05-30T19:54:06.519Z" }, { url = "https://files.pythonhosted.org/packages/96/b8/45a5598cc8d466bb1669ccf0fc4f556719babfdb7a1983edc24967cb3845/uv-0.7.9-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:f5f47e93a5f948f431ca55d765af6e818c925500807539b976bfda7f94369aa9", size = 16299207, upload-time = "2025-05-30T19:54:09.713Z" }, { url = "https://files.pythonhosted.org/packages/14/35/7e70639cd175f340138c88290c819214a496dfc52461f30f71e51e776293/uv-0.7.9-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:267fe25ad3adf024e13617be9fc99bedebf96bf726c6140e48d856e844f21af4", size = 16427594, upload-time = "2025-05-30T19:54:13.318Z" }, { url = "https://files.pythonhosted.org/packages/5e/f6/90fe538370bc60509cca942b703bca06c06c160ec09816ea6946882278d1/uv-0.7.9-py3-none-musllinux_1_1_i686.whl", hash = "sha256:473d3c6ee07588cff8319079d9225fb393ed177d8d57186fce0d7c1aebff79c0", size = 16751451, upload-time = "2025-05-30T19:54:16.833Z" }, { url = "https://files.pythonhosted.org/packages/09/cb/c099aba21fb22e50713b42e874075a5b60c6b4d141cc3868ae22f505baa7/uv-0.7.9-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:19792c88058894c10f0370a5e5492bb4a7e6302c439fed9882e73ba2e4b231ef", size = 17594496, upload-time = "2025-05-30T19:54:20.383Z" }, { url = "https://files.pythonhosted.org/packages/c0/2e/e35b2c5669533075987e1d74da45af891890ae5faee031f90997ed81cada/uv-0.7.9-py3-none-win32.whl", hash = "sha256:298e9b3c65742edcb3097c2cf3f62ec847df174a7c62c85fe139dddaa1b9ab65", size = 17121149, upload-time = "2025-05-30T19:54:23.608Z" }, { url = "https://files.pythonhosted.org/packages/33/8e/d10425711156d0d5d9a28299950acb3ab4a3987b3150a3c871ac95ce2fdd/uv-0.7.9-py3-none-win_amd64.whl", hash = "sha256:82d76ea988ff1347158c6de46a571b1db7d344219e452bd7b3339c21ec37cfd8", size = 18622895, upload-time = "2025-05-30T19:54:27.427Z" }, { url = "https://files.pythonhosted.org/packages/72/77/cac29a8fb608b5613b7a0863ec6bd7c2517f3a80b94c419e9d890c12257e/uv-0.7.9-py3-none-win_arm64.whl", hash = "sha256:4d419bcc3138fd787ce77305f1a09e2a984766e0804c6e5a2b54adfa55d2439a", size = 17316542, upload-time = "2025-05-30T19:54:30.697Z" }, ] [[package]] name = "virtualenv" version = "20.31.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "distlib" }, { name = "filelock" }, { name = "platformdirs" }, ] sdist = { url = "https://files.pythonhosted.org/packages/56/2c/444f465fb2c65f40c3a104fd0c495184c4f2336d65baf398e3c75d72ea94/virtualenv-20.31.2.tar.gz", hash = "sha256:e10c0a9d02835e592521be48b332b6caee6887f332c111aa79a09b9e79efc2af", size = 6076316, upload-time = "2025-05-08T17:58:23.811Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/f3/40/b1c265d4b2b62b58576588510fc4d1fe60a86319c8de99fd8e9fec617d2c/virtualenv-20.31.2-py3-none-any.whl", hash = "sha256:36efd0d9650ee985f0cad72065001e66d49a6f24eb44d98980f630686243cf11", size = 6057982, upload-time = "2025-05-08T17:58:21.15Z" }, ] [[package]] name = "yarl" version = "1.20.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] sdist = { url = "https://files.pythonhosted.org/packages/62/51/c0edba5219027f6eab262e139f73e2417b0f4efffa23bf562f6e18f76ca5/yarl-1.20.0.tar.gz", hash = "sha256:686d51e51ee5dfe62dec86e4866ee0e9ed66df700d55c828a615640adc885307", size = 185258, upload-time = "2025-04-17T00:45:14.661Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/60/82/a59d8e21b20ffc836775fa7daedac51d16bb8f3010c4fcb495c4496aa922/yarl-1.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fdb5204d17cb32b2de2d1e21c7461cabfacf17f3645e4b9039f210c5d3378bf3", size = 145178, upload-time = "2025-04-17T00:42:04.511Z" }, { url = "https://files.pythonhosted.org/packages/ba/81/315a3f6f95947cfbf37c92d6fbce42a1a6207b6c38e8c2b452499ec7d449/yarl-1.20.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:eaddd7804d8e77d67c28d154ae5fab203163bd0998769569861258e525039d2a", size = 96859, upload-time = "2025-04-17T00:42:06.43Z" }, { url = "https://files.pythonhosted.org/packages/ad/17/9b64e575583158551b72272a1023cdbd65af54fe13421d856b2850a6ddb7/yarl-1.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:634b7ba6b4a85cf67e9df7c13a7fb2e44fa37b5d34501038d174a63eaac25ee2", size = 94647, upload-time = "2025-04-17T00:42:07.976Z" }, { url = "https://files.pythonhosted.org/packages/2c/29/8f291e7922a58a21349683f6120a85701aeefaa02e9f7c8a2dc24fe3f431/yarl-1.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d409e321e4addf7d97ee84162538c7258e53792eb7c6defd0c33647d754172e", size = 355788, upload-time = "2025-04-17T00:42:09.902Z" }, { url = "https://files.pythonhosted.org/packages/26/6d/b4892c80b805c42c228c6d11e03cafabf81662d371b0853e7f0f513837d5/yarl-1.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ea52f7328a36960ba3231c6677380fa67811b414798a6e071c7085c57b6d20a9", size = 344613, upload-time = "2025-04-17T00:42:11.768Z" }, { url = "https://files.pythonhosted.org/packages/d7/0e/517aa28d3f848589bae9593717b063a544b86ba0a807d943c70f48fcf3bb/yarl-1.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8703517b924463994c344dcdf99a2d5ce9eca2b6882bb640aa555fb5efc706a", size = 370953, upload-time = "2025-04-17T00:42:13.983Z" }, { url = "https://files.pythonhosted.org/packages/5f/9b/5bd09d2f1ad6e6f7c2beae9e50db78edd2cca4d194d227b958955573e240/yarl-1.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:077989b09ffd2f48fb2d8f6a86c5fef02f63ffe6b1dd4824c76de7bb01e4f2e2", size = 369204, upload-time = "2025-04-17T00:42:16.386Z" }, { url = "https://files.pythonhosted.org/packages/9c/85/d793a703cf4bd0d4cd04e4b13cc3d44149470f790230430331a0c1f52df5/yarl-1.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0acfaf1da020253f3533526e8b7dd212838fdc4109959a2c53cafc6db611bff2", size = 358108, upload-time = "2025-04-17T00:42:18.622Z" }, { url = "https://files.pythonhosted.org/packages/6f/54/b6c71e13549c1f6048fbc14ce8d930ac5fb8bafe4f1a252e621a24f3f1f9/yarl-1.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4230ac0b97ec5eeb91d96b324d66060a43fd0d2a9b603e3327ed65f084e41f8", size = 346610, upload-time = "2025-04-17T00:42:20.9Z" }, { url = "https://files.pythonhosted.org/packages/a0/1a/d6087d58bdd0d8a2a37bbcdffac9d9721af6ebe50d85304d9f9b57dfd862/yarl-1.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a6a1e6ae21cdd84011c24c78d7a126425148b24d437b5702328e4ba640a8902", size = 365378, upload-time = "2025-04-17T00:42:22.926Z" }, { url = "https://files.pythonhosted.org/packages/02/84/e25ddff4cbc001dbc4af76f8d41a3e23818212dd1f0a52044cbc60568872/yarl-1.20.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:86de313371ec04dd2531f30bc41a5a1a96f25a02823558ee0f2af0beaa7ca791", size = 356919, upload-time = "2025-04-17T00:42:25.145Z" }, { url = "https://files.pythonhosted.org/packages/04/76/898ae362353bf8f64636495d222c8014c8e5267df39b1a9fe1e1572fb7d0/yarl-1.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dd59c9dd58ae16eaa0f48c3d0cbe6be8ab4dc7247c3ff7db678edecbaf59327f", size = 364248, upload-time = "2025-04-17T00:42:27.475Z" }, { url = "https://files.pythonhosted.org/packages/1b/b0/9d9198d83a622f1c40fdbf7bd13b224a6979f2e1fc2cf50bfb1d8773c495/yarl-1.20.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a0bc5e05f457b7c1994cc29e83b58f540b76234ba6b9648a4971ddc7f6aa52da", size = 378418, upload-time = "2025-04-17T00:42:29.333Z" }, { url = "https://files.pythonhosted.org/packages/c7/ce/1f50c1cc594cf5d3f5bf4a9b616fca68680deaec8ad349d928445ac52eb8/yarl-1.20.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c9471ca18e6aeb0e03276b5e9b27b14a54c052d370a9c0c04a68cefbd1455eb4", size = 383850, upload-time = "2025-04-17T00:42:31.668Z" }, { url = "https://files.pythonhosted.org/packages/89/1e/a59253a87b35bfec1a25bb5801fb69943330b67cfd266278eb07e0609012/yarl-1.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:40ed574b4df723583a26c04b298b283ff171bcc387bc34c2683235e2487a65a5", size = 381218, upload-time = "2025-04-17T00:42:33.523Z" }, { url = "https://files.pythonhosted.org/packages/85/b0/26f87df2b3044b0ef1a7cf66d321102bdca091db64c5ae853fcb2171c031/yarl-1.20.0-cp311-cp311-win32.whl", hash = "sha256:db243357c6c2bf3cd7e17080034ade668d54ce304d820c2a58514a4e51d0cfd6", size = 86606, upload-time = "2025-04-17T00:42:35.873Z" }, { url = "https://files.pythonhosted.org/packages/33/46/ca335c2e1f90446a77640a45eeb1cd8f6934f2c6e4df7db0f0f36ef9f025/yarl-1.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:8c12cd754d9dbd14204c328915e23b0c361b88f3cffd124129955e60a4fbfcfb", size = 93374, upload-time = "2025-04-17T00:42:37.586Z" }, { url = "https://files.pythonhosted.org/packages/c3/e8/3efdcb83073df978bb5b1a9cc0360ce596680e6c3fac01f2a994ccbb8939/yarl-1.20.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e06b9f6cdd772f9b665e5ba8161968e11e403774114420737f7884b5bd7bdf6f", size = 147089, upload-time = "2025-04-17T00:42:39.602Z" }, { url = "https://files.pythonhosted.org/packages/60/c3/9e776e98ea350f76f94dd80b408eaa54e5092643dbf65fd9babcffb60509/yarl-1.20.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b9ae2fbe54d859b3ade40290f60fe40e7f969d83d482e84d2c31b9bff03e359e", size = 97706, upload-time = "2025-04-17T00:42:41.469Z" }, { url = "https://files.pythonhosted.org/packages/0c/5b/45cdfb64a3b855ce074ae607b9fc40bc82e7613b94e7612b030255c93a09/yarl-1.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d12b8945250d80c67688602c891237994d203d42427cb14e36d1a732eda480e", size = 95719, upload-time = "2025-04-17T00:42:43.666Z" }, { url = "https://files.pythonhosted.org/packages/2d/4e/929633b249611eeed04e2f861a14ed001acca3ef9ec2a984a757b1515889/yarl-1.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:087e9731884621b162a3e06dc0d2d626e1542a617f65ba7cc7aeab279d55ad33", size = 343972, upload-time = "2025-04-17T00:42:45.391Z" }, { url = "https://files.pythonhosted.org/packages/49/fd/047535d326c913f1a90407a3baf7ff535b10098611eaef2c527e32e81ca1/yarl-1.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:69df35468b66c1a6e6556248e6443ef0ec5f11a7a4428cf1f6281f1879220f58", size = 339639, upload-time = "2025-04-17T00:42:47.552Z" }, { url = "https://files.pythonhosted.org/packages/48/2f/11566f1176a78f4bafb0937c0072410b1b0d3640b297944a6a7a556e1d0b/yarl-1.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b2992fe29002fd0d4cbaea9428b09af9b8686a9024c840b8a2b8f4ea4abc16f", size = 353745, upload-time = "2025-04-17T00:42:49.406Z" }, { url = "https://files.pythonhosted.org/packages/26/17/07dfcf034d6ae8837b33988be66045dd52f878dfb1c4e8f80a7343f677be/yarl-1.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4c903e0b42aab48abfbac668b5a9d7b6938e721a6341751331bcd7553de2dcae", size = 354178, upload-time = "2025-04-17T00:42:51.588Z" }, { url = "https://files.pythonhosted.org/packages/15/45/212604d3142d84b4065d5f8cab6582ed3d78e4cc250568ef2a36fe1cf0a5/yarl-1.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf099e2432131093cc611623e0b0bcc399b8cddd9a91eded8bfb50402ec35018", size = 349219, upload-time = "2025-04-17T00:42:53.674Z" }, { url = "https://files.pythonhosted.org/packages/e6/e0/a10b30f294111c5f1c682461e9459935c17d467a760c21e1f7db400ff499/yarl-1.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a7f62f5dc70a6c763bec9ebf922be52aa22863d9496a9a30124d65b489ea672", size = 337266, upload-time = "2025-04-17T00:42:55.49Z" }, { url = "https://files.pythonhosted.org/packages/33/a6/6efa1d85a675d25a46a167f9f3e80104cde317dfdf7f53f112ae6b16a60a/yarl-1.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:54ac15a8b60382b2bcefd9a289ee26dc0920cf59b05368c9b2b72450751c6eb8", size = 360873, upload-time = "2025-04-17T00:42:57.895Z" }, { url = "https://files.pythonhosted.org/packages/77/67/c8ab718cb98dfa2ae9ba0f97bf3cbb7d45d37f13fe1fbad25ac92940954e/yarl-1.20.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:25b3bc0763a7aca16a0f1b5e8ef0f23829df11fb539a1b70476dcab28bd83da7", size = 360524, upload-time = "2025-04-17T00:43:00.094Z" }, { url = "https://files.pythonhosted.org/packages/bd/e8/c3f18660cea1bc73d9f8a2b3ef423def8dadbbae6c4afabdb920b73e0ead/yarl-1.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b2586e36dc070fc8fad6270f93242124df68b379c3a251af534030a4a33ef594", size = 365370, upload-time = "2025-04-17T00:43:02.242Z" }, { url = "https://files.pythonhosted.org/packages/c9/99/33f3b97b065e62ff2d52817155a89cfa030a1a9b43fee7843ef560ad9603/yarl-1.20.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:866349da9d8c5290cfefb7fcc47721e94de3f315433613e01b435473be63daa6", size = 373297, upload-time = "2025-04-17T00:43:04.189Z" }, { url = "https://files.pythonhosted.org/packages/3d/89/7519e79e264a5f08653d2446b26d4724b01198a93a74d2e259291d538ab1/yarl-1.20.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:33bb660b390a0554d41f8ebec5cd4475502d84104b27e9b42f5321c5192bfcd1", size = 378771, upload-time = "2025-04-17T00:43:06.609Z" }, { url = "https://files.pythonhosted.org/packages/3a/58/6c460bbb884abd2917c3eef6f663a4a873f8dc6f498561fc0ad92231c113/yarl-1.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:737e9f171e5a07031cbee5e9180f6ce21a6c599b9d4b2c24d35df20a52fabf4b", size = 375000, upload-time = "2025-04-17T00:43:09.01Z" }, { url = "https://files.pythonhosted.org/packages/3b/2a/dd7ed1aa23fea996834278d7ff178f215b24324ee527df53d45e34d21d28/yarl-1.20.0-cp312-cp312-win32.whl", hash = "sha256:839de4c574169b6598d47ad61534e6981979ca2c820ccb77bf70f4311dd2cc64", size = 86355, upload-time = "2025-04-17T00:43:11.311Z" }, { url = "https://files.pythonhosted.org/packages/ca/c6/333fe0338305c0ac1c16d5aa7cc4841208d3252bbe62172e0051006b5445/yarl-1.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:3d7dbbe44b443b0c4aa0971cb07dcb2c2060e4a9bf8d1301140a33a93c98e18c", size = 92904, upload-time = "2025-04-17T00:43:13.087Z" }, { url = "https://files.pythonhosted.org/packages/0f/6f/514c9bff2900c22a4f10e06297714dbaf98707143b37ff0bcba65a956221/yarl-1.20.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2137810a20b933b1b1b7e5cf06a64c3ed3b4747b0e5d79c9447c00db0e2f752f", size = 145030, upload-time = "2025-04-17T00:43:15.083Z" }, { url = "https://files.pythonhosted.org/packages/4e/9d/f88da3fa319b8c9c813389bfb3463e8d777c62654c7168e580a13fadff05/yarl-1.20.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:447c5eadd750db8389804030d15f43d30435ed47af1313303ed82a62388176d3", size = 96894, upload-time = "2025-04-17T00:43:17.372Z" }, { url = "https://files.pythonhosted.org/packages/cd/57/92e83538580a6968b2451d6c89c5579938a7309d4785748e8ad42ddafdce/yarl-1.20.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:42fbe577272c203528d402eec8bf4b2d14fd49ecfec92272334270b850e9cd7d", size = 94457, upload-time = "2025-04-17T00:43:19.431Z" }, { url = "https://files.pythonhosted.org/packages/e9/ee/7ee43bd4cf82dddd5da97fcaddb6fa541ab81f3ed564c42f146c83ae17ce/yarl-1.20.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18e321617de4ab170226cd15006a565d0fa0d908f11f724a2c9142d6b2812ab0", size = 343070, upload-time = "2025-04-17T00:43:21.426Z" }, { url = "https://files.pythonhosted.org/packages/4a/12/b5eccd1109e2097bcc494ba7dc5de156e41cf8309fab437ebb7c2b296ce3/yarl-1.20.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4345f58719825bba29895011e8e3b545e6e00257abb984f9f27fe923afca2501", size = 337739, upload-time = "2025-04-17T00:43:23.634Z" }, { url = "https://files.pythonhosted.org/packages/7d/6b/0eade8e49af9fc2585552f63c76fa59ef469c724cc05b29519b19aa3a6d5/yarl-1.20.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d9b980d7234614bc4674468ab173ed77d678349c860c3af83b1fffb6a837ddc", size = 351338, upload-time = "2025-04-17T00:43:25.695Z" }, { url = "https://files.pythonhosted.org/packages/45/cb/aaaa75d30087b5183c7b8a07b4fb16ae0682dd149a1719b3a28f54061754/yarl-1.20.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af4baa8a445977831cbaa91a9a84cc09debb10bc8391f128da2f7bd070fc351d", size = 353636, upload-time = "2025-04-17T00:43:27.876Z" }, { url = "https://files.pythonhosted.org/packages/98/9d/d9cb39ec68a91ba6e66fa86d97003f58570327d6713833edf7ad6ce9dde5/yarl-1.20.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:123393db7420e71d6ce40d24885a9e65eb1edefc7a5228db2d62bcab3386a5c0", size = 348061, upload-time = "2025-04-17T00:43:29.788Z" }, { url = "https://files.pythonhosted.org/packages/72/6b/103940aae893d0cc770b4c36ce80e2ed86fcb863d48ea80a752b8bda9303/yarl-1.20.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ab47acc9332f3de1b39e9b702d9c916af7f02656b2a86a474d9db4e53ef8fd7a", size = 334150, upload-time = "2025-04-17T00:43:31.742Z" }, { url = "https://files.pythonhosted.org/packages/ef/b2/986bd82aa222c3e6b211a69c9081ba46484cffa9fab2a5235e8d18ca7a27/yarl-1.20.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4a34c52ed158f89876cba9c600b2c964dfc1ca52ba7b3ab6deb722d1d8be6df2", size = 362207, upload-time = "2025-04-17T00:43:34.099Z" }, { url = "https://files.pythonhosted.org/packages/14/7c/63f5922437b873795d9422cbe7eb2509d4b540c37ae5548a4bb68fd2c546/yarl-1.20.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:04d8cfb12714158abf2618f792c77bc5c3d8c5f37353e79509608be4f18705c9", size = 361277, upload-time = "2025-04-17T00:43:36.202Z" }, { url = "https://files.pythonhosted.org/packages/81/83/450938cccf732466953406570bdb42c62b5ffb0ac7ac75a1f267773ab5c8/yarl-1.20.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7dc63ad0d541c38b6ae2255aaa794434293964677d5c1ec5d0116b0e308031f5", size = 364990, upload-time = "2025-04-17T00:43:38.551Z" }, { url = "https://files.pythonhosted.org/packages/b4/de/af47d3a47e4a833693b9ec8e87debb20f09d9fdc9139b207b09a3e6cbd5a/yarl-1.20.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d02b591a64e4e6ca18c5e3d925f11b559c763b950184a64cf47d74d7e41877", size = 374684, upload-time = "2025-04-17T00:43:40.481Z" }, { url = "https://files.pythonhosted.org/packages/62/0b/078bcc2d539f1faffdc7d32cb29a2d7caa65f1a6f7e40795d8485db21851/yarl-1.20.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:95fc9876f917cac7f757df80a5dda9de59d423568460fe75d128c813b9af558e", size = 382599, upload-time = "2025-04-17T00:43:42.463Z" }, { url = "https://files.pythonhosted.org/packages/74/a9/4fdb1a7899f1fb47fd1371e7ba9e94bff73439ce87099d5dd26d285fffe0/yarl-1.20.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bb769ae5760cd1c6a712135ee7915f9d43f11d9ef769cb3f75a23e398a92d384", size = 378573, upload-time = "2025-04-17T00:43:44.797Z" }, { url = "https://files.pythonhosted.org/packages/fd/be/29f5156b7a319e4d2e5b51ce622b4dfb3aa8d8204cd2a8a339340fbfad40/yarl-1.20.0-cp313-cp313-win32.whl", hash = "sha256:70e0c580a0292c7414a1cead1e076c9786f685c1fc4757573d2967689b370e62", size = 86051, upload-time = "2025-04-17T00:43:47.076Z" }, { url = "https://files.pythonhosted.org/packages/52/56/05fa52c32c301da77ec0b5f63d2d9605946fe29defacb2a7ebd473c23b81/yarl-1.20.0-cp313-cp313-win_amd64.whl", hash = "sha256:4c43030e4b0af775a85be1fa0433119b1565673266a70bf87ef68a9d5ba3174c", size = 92742, upload-time = "2025-04-17T00:43:49.193Z" }, { url = "https://files.pythonhosted.org/packages/d4/2f/422546794196519152fc2e2f475f0e1d4d094a11995c81a465faf5673ffd/yarl-1.20.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b6c4c3d0d6a0ae9b281e492b1465c72de433b782e6b5001c8e7249e085b69051", size = 163575, upload-time = "2025-04-17T00:43:51.533Z" }, { url = "https://files.pythonhosted.org/packages/90/fc/67c64ddab6c0b4a169d03c637fb2d2a212b536e1989dec8e7e2c92211b7f/yarl-1.20.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8681700f4e4df891eafa4f69a439a6e7d480d64e52bf460918f58e443bd3da7d", size = 106121, upload-time = "2025-04-17T00:43:53.506Z" }, { url = "https://files.pythonhosted.org/packages/6d/00/29366b9eba7b6f6baed7d749f12add209b987c4cfbfa418404dbadc0f97c/yarl-1.20.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:84aeb556cb06c00652dbf87c17838eb6d92cfd317799a8092cee0e570ee11229", size = 103815, upload-time = "2025-04-17T00:43:55.41Z" }, { url = "https://files.pythonhosted.org/packages/28/f4/a2a4c967c8323c03689383dff73396281ced3b35d0ed140580825c826af7/yarl-1.20.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f166eafa78810ddb383e930d62e623d288fb04ec566d1b4790099ae0f31485f1", size = 408231, upload-time = "2025-04-17T00:43:57.825Z" }, { url = "https://files.pythonhosted.org/packages/0f/a1/66f7ffc0915877d726b70cc7a896ac30b6ac5d1d2760613603b022173635/yarl-1.20.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5d3d6d14754aefc7a458261027a562f024d4f6b8a798adb472277f675857b1eb", size = 390221, upload-time = "2025-04-17T00:44:00.526Z" }, { url = "https://files.pythonhosted.org/packages/41/15/cc248f0504610283271615e85bf38bc014224122498c2016d13a3a1b8426/yarl-1.20.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a8f64df8ed5d04c51260dbae3cc82e5649834eebea9eadfd829837b8093eb00", size = 411400, upload-time = "2025-04-17T00:44:02.853Z" }, { url = "https://files.pythonhosted.org/packages/5c/af/f0823d7e092bfb97d24fce6c7269d67fcd1aefade97d0a8189c4452e4d5e/yarl-1.20.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4d9949eaf05b4d30e93e4034a7790634bbb41b8be2d07edd26754f2e38e491de", size = 411714, upload-time = "2025-04-17T00:44:04.904Z" }, { url = "https://files.pythonhosted.org/packages/83/70/be418329eae64b9f1b20ecdaac75d53aef098797d4c2299d82ae6f8e4663/yarl-1.20.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c366b254082d21cc4f08f522ac201d0d83a8b8447ab562732931d31d80eb2a5", size = 404279, upload-time = "2025-04-17T00:44:07.721Z" }, { url = "https://files.pythonhosted.org/packages/19/f5/52e02f0075f65b4914eb890eea1ba97e6fd91dd821cc33a623aa707b2f67/yarl-1.20.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91bc450c80a2e9685b10e34e41aef3d44ddf99b3a498717938926d05ca493f6a", size = 384044, upload-time = "2025-04-17T00:44:09.708Z" }, { url = "https://files.pythonhosted.org/packages/6a/36/b0fa25226b03d3f769c68d46170b3e92b00ab3853d73127273ba22474697/yarl-1.20.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9c2aa4387de4bc3a5fe158080757748d16567119bef215bec643716b4fbf53f9", size = 416236, upload-time = "2025-04-17T00:44:11.734Z" }, { url = "https://files.pythonhosted.org/packages/cb/3a/54c828dd35f6831dfdd5a79e6c6b4302ae2c5feca24232a83cb75132b205/yarl-1.20.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:d2cbca6760a541189cf87ee54ff891e1d9ea6406079c66341008f7ef6ab61145", size = 402034, upload-time = "2025-04-17T00:44:13.975Z" }, { url = "https://files.pythonhosted.org/packages/10/97/c7bf5fba488f7e049f9ad69c1b8fdfe3daa2e8916b3d321aa049e361a55a/yarl-1.20.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:798a5074e656f06b9fad1a162be5a32da45237ce19d07884d0b67a0aa9d5fdda", size = 407943, upload-time = "2025-04-17T00:44:16.052Z" }, { url = "https://files.pythonhosted.org/packages/fd/a4/022d2555c1e8fcff08ad7f0f43e4df3aba34f135bff04dd35d5526ce54ab/yarl-1.20.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:f106e75c454288472dbe615accef8248c686958c2e7dd3b8d8ee2669770d020f", size = 423058, upload-time = "2025-04-17T00:44:18.547Z" }, { url = "https://files.pythonhosted.org/packages/4c/f6/0873a05563e5df29ccf35345a6ae0ac9e66588b41fdb7043a65848f03139/yarl-1.20.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:3b60a86551669c23dc5445010534d2c5d8a4e012163218fc9114e857c0586fdd", size = 423792, upload-time = "2025-04-17T00:44:20.639Z" }, { url = "https://files.pythonhosted.org/packages/9e/35/43fbbd082708fa42e923f314c24f8277a28483d219e049552e5007a9aaca/yarl-1.20.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3e429857e341d5e8e15806118e0294f8073ba9c4580637e59ab7b238afca836f", size = 422242, upload-time = "2025-04-17T00:44:22.851Z" }, { url = "https://files.pythonhosted.org/packages/ed/f7/f0f2500cf0c469beb2050b522c7815c575811627e6d3eb9ec7550ddd0bfe/yarl-1.20.0-cp313-cp313t-win32.whl", hash = "sha256:65a4053580fe88a63e8e4056b427224cd01edfb5f951498bfefca4052f0ce0ac", size = 93816, upload-time = "2025-04-17T00:44:25.491Z" }, { url = "https://files.pythonhosted.org/packages/3f/93/f73b61353b2a699d489e782c3f5998b59f974ec3156a2050a52dfd7e8946/yarl-1.20.0-cp313-cp313t-win_amd64.whl", hash = "sha256:53b2da3a6ca0a541c1ae799c349788d480e5144cac47dba0266c7cb6c76151fe", size = 101093, upload-time = "2025-04-17T00:44:27.418Z" }, { url = "https://files.pythonhosted.org/packages/ea/1f/70c57b3d7278e94ed22d85e09685d3f0a38ebdd8c5c73b65ba4c0d0fe002/yarl-1.20.0-py3-none-any.whl", hash = "sha256:5d0fe6af927a47a230f31e6004621fd0959eaa915fc62acfafa67ff7229a3124", size = 46124, upload-time = "2025-04-17T00:45:12.199Z" }, ] [[package]] name = "zipp" version = "3.22.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/12/b6/7b3d16792fdf94f146bed92be90b4eb4563569eca91513c8609aebf0c167/zipp-3.22.0.tar.gz", hash = "sha256:dd2f28c3ce4bc67507bfd3781d21b7bb2be31103b51a4553ad7d90b84e57ace5", size = 25257, upload-time = "2025-05-26T14:46:32.217Z" } wheels = [ { url = "https://files.pythonhosted.org/packages/ad/da/f64669af4cae46f17b90798a827519ce3737d31dbafad65d391e49643dc4/zipp-3.22.0-py3-none-any.whl", hash = "sha256:fe208f65f2aca48b81f9e6fd8cf7b8b32c26375266b009b413d45306b6148343", size = 9796, upload-time = "2025-05-26T14:46:30.775Z" }, ]