Repository: hacs/integration Branch: main Commit: cb488796faf1 Files: 701 Total size: 2.3 MB Directory structure: gitextract_ec9nfn8q/ ├── .codeclimate.yml ├── .codecov.yml ├── .coveragerc ├── .devcontainer.json ├── .dockerignore ├── .gitattributes ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── a_integration.yml │ │ ├── b_frontend.yml │ │ ├── c_bot.yml │ │ ├── config.yml │ │ ├── d_documentation.yml │ │ ├── e_action.yml │ │ ├── f_addon.yml │ │ └── removal.yml │ ├── dependabot.yml │ ├── pre-commit-config.yaml │ ├── release.yml │ └── workflows/ │ ├── action-container.yml │ ├── generate-hacs-data.yml │ ├── lint.yaml │ ├── lock.yml │ ├── publish.yml │ ├── pull_requests_labels.yml │ ├── pytest.yml │ ├── stale.yml │ └── validate.yml ├── .gitignore ├── .pylintrc ├── LICENSE ├── README.md ├── action/ │ ├── Dockerfile │ └── action.py ├── constraints.txt ├── custom_components/ │ └── hacs/ │ ├── __init__.py │ ├── base.py │ ├── config_flow.py │ ├── const.py │ ├── coordinator.py │ ├── data_client.py │ ├── diagnostics.py │ ├── entity.py │ ├── enums.py │ ├── exceptions.py │ ├── frontend.py │ ├── icons.json │ ├── iconset.js │ ├── manifest.json │ ├── repairs.py │ ├── repositories/ │ │ ├── __init__.py │ │ ├── appdaemon.py │ │ ├── base.py │ │ ├── integration.py │ │ ├── plugin.py │ │ ├── python_script.py │ │ ├── template.py │ │ └── theme.py │ ├── switch.py │ ├── system_health.py │ ├── types.py │ ├── update.py │ ├── utils/ │ │ ├── __init__.py │ │ ├── backup.py │ │ ├── configuration_schema.py │ │ ├── data.py │ │ ├── decode.py │ │ ├── decorator.py │ │ ├── file_system.py │ │ ├── filters.py │ │ ├── github_graphql_query.py │ │ ├── json.py │ │ ├── logger.py │ │ ├── path.py │ │ ├── queue_manager.py │ │ ├── regex.py │ │ ├── store.py │ │ ├── url.py │ │ ├── validate.py │ │ ├── version.py │ │ └── workarounds.py │ ├── validate/ │ │ ├── README.md │ │ ├── __init__.py │ │ ├── archived.py │ │ ├── base.py │ │ ├── brands.py │ │ ├── description.py │ │ ├── hacsjson.py │ │ ├── images.py │ │ ├── information.py │ │ ├── integration_manifest.py │ │ ├── issues.py │ │ ├── manager.py │ │ └── topics.py │ └── websocket/ │ ├── __init__.py │ ├── critical.py │ ├── repositories.py │ └── repository.py ├── hacs.json ├── info.md ├── pyproject.toml ├── requirements_action.txt ├── requirements_base.txt ├── requirements_core_min.txt ├── requirements_generate_data.txt ├── requirements_lint.txt ├── requirements_test.txt ├── scripts/ │ ├── __init__.py │ ├── clear_storage │ ├── coverage │ ├── data/ │ │ ├── __init__.py │ │ ├── common.py │ │ ├── generate_category_data.py │ │ └── validate_category_data.py │ ├── develop │ ├── install/ │ │ ├── core │ │ ├── core_dev │ │ ├── frontend │ │ ├── pip_packages │ │ └── uv_packages │ ├── lgtm.js │ ├── lint │ ├── setup │ ├── snapshot-update │ ├── test │ └── update/ │ ├── __init__.py │ ├── default_repositories.py │ └── manifest.py └── tests/ ├── __init__.py ├── action/ │ └── test_hacs_action_integration.py ├── common.py ├── conftest.py ├── fixtures/ │ ├── proxy/ │ │ ├── api.github.com/ │ │ │ ├── rate_limit.json │ │ │ └── repos/ │ │ │ ├── hacs/ │ │ │ │ ├── default/ │ │ │ │ │ └── contents/ │ │ │ │ │ ├── appdaemon.json │ │ │ │ │ ├── integration.json │ │ │ │ │ ├── plugin.json │ │ │ │ │ ├── python_script.json │ │ │ │ │ ├── template.json │ │ │ │ │ └── theme.json │ │ │ │ ├── integration/ │ │ │ │ │ ├── contents/ │ │ │ │ │ │ ├── custom_components/ │ │ │ │ │ │ │ └── hacs/ │ │ │ │ │ │ │ └── manifest.json │ │ │ │ │ │ └── hacs.json │ │ │ │ │ └── git/ │ │ │ │ │ └── trees/ │ │ │ │ │ └── main.json │ │ │ │ └── integration.json │ │ │ └── hacs-test-org/ │ │ │ ├── addon-basic/ │ │ │ │ ├── git/ │ │ │ │ │ └── trees/ │ │ │ │ │ └── main.json │ │ │ │ └── releases.json │ │ │ ├── addon-basic.json │ │ │ ├── appdaemon-basic/ │ │ │ │ ├── branches/ │ │ │ │ │ └── main.json │ │ │ │ ├── contents/ │ │ │ │ │ ├── apps/ │ │ │ │ │ │ └── example.json │ │ │ │ │ ├── apps.json │ │ │ │ │ └── hacs.json │ │ │ │ ├── git/ │ │ │ │ │ └── trees/ │ │ │ │ │ ├── 1.0.0.json │ │ │ │ │ ├── 2.0.0.json │ │ │ │ │ └── main.json │ │ │ │ └── releases.json │ │ │ ├── appdaemon-basic.json │ │ │ ├── integration-basic/ │ │ │ │ ├── branches/ │ │ │ │ │ └── main.json │ │ │ │ ├── contents/ │ │ │ │ │ ├── custom_components/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── manifest.json │ │ │ │ │ └── hacs.json │ │ │ │ ├── git/ │ │ │ │ │ └── trees/ │ │ │ │ │ ├── 1.0.0.json │ │ │ │ │ ├── 2.0.0.json │ │ │ │ │ └── main.json │ │ │ │ ├── releases/ │ │ │ │ │ └── latest.json │ │ │ │ └── releases.json │ │ │ ├── integration-basic-custom/ │ │ │ │ ├── branches/ │ │ │ │ │ └── main.json │ │ │ │ ├── contents/ │ │ │ │ │ ├── custom_components/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── manifest.json │ │ │ │ │ └── hacs.json │ │ │ │ ├── git/ │ │ │ │ │ └── trees/ │ │ │ │ │ ├── 1.0.0.json │ │ │ │ │ ├── 2.0.0.json │ │ │ │ │ └── main.json │ │ │ │ └── releases.json │ │ │ ├── integration-basic-custom.json │ │ │ ├── integration-basic.json │ │ │ ├── integration-invalid/ │ │ │ │ ├── git/ │ │ │ │ │ └── trees/ │ │ │ │ │ └── main.json │ │ │ │ └── releases.json │ │ │ ├── integration-invalid.json │ │ │ ├── plugin-basic/ │ │ │ │ ├── branches/ │ │ │ │ │ └── main.json │ │ │ │ ├── contents/ │ │ │ │ │ └── hacs.json │ │ │ │ ├── git/ │ │ │ │ │ └── trees/ │ │ │ │ │ ├── 1.0.0.json │ │ │ │ │ ├── 2.0.0.json │ │ │ │ │ └── main.json │ │ │ │ └── releases.json │ │ │ ├── plugin-basic.json │ │ │ ├── plugin-custom-dist/ │ │ │ │ ├── branches/ │ │ │ │ │ └── main.json │ │ │ │ ├── contents/ │ │ │ │ │ └── hacs.json │ │ │ │ ├── git/ │ │ │ │ │ └── trees/ │ │ │ │ │ ├── 1.0.0.json │ │ │ │ │ ├── 2.0.0.json │ │ │ │ │ └── main.json │ │ │ │ └── releases.json │ │ │ ├── plugin-custom-dist.json │ │ │ ├── python_script-basic/ │ │ │ │ ├── branches/ │ │ │ │ │ └── main.json │ │ │ │ ├── contents/ │ │ │ │ │ └── hacs.json │ │ │ │ ├── git/ │ │ │ │ │ └── trees/ │ │ │ │ │ ├── 1.0.0.json │ │ │ │ │ ├── 2.0.0.json │ │ │ │ │ └── main.json │ │ │ │ └── releases.json │ │ │ ├── python_script-basic.json │ │ │ ├── template-basic/ │ │ │ │ ├── branches/ │ │ │ │ │ └── main.json │ │ │ │ ├── contents/ │ │ │ │ │ └── hacs.json │ │ │ │ ├── git/ │ │ │ │ │ └── trees/ │ │ │ │ │ ├── 1.0.0.json │ │ │ │ │ ├── 2.0.0.json │ │ │ │ │ └── main.json │ │ │ │ └── releases.json │ │ │ ├── template-basic.json │ │ │ ├── theme-basic/ │ │ │ │ ├── branches/ │ │ │ │ │ └── main.json │ │ │ │ ├── contents/ │ │ │ │ │ └── hacs.json │ │ │ │ ├── git/ │ │ │ │ │ └── trees/ │ │ │ │ │ ├── 1.0.0.json │ │ │ │ │ ├── 2.0.0.json │ │ │ │ │ └── main.json │ │ │ │ └── releases.json │ │ │ └── theme-basic.json │ │ ├── brands.home-assistant.io/ │ │ │ └── domains.json │ │ ├── data-v2.hacs.xyz/ │ │ │ ├── appdaemon/ │ │ │ │ ├── data.json │ │ │ │ └── repositories.json │ │ │ ├── critical/ │ │ │ │ └── data.json │ │ │ ├── integration/ │ │ │ │ ├── data.json │ │ │ │ └── repositories.json │ │ │ ├── netdaemon/ │ │ │ │ ├── data.json │ │ │ │ └── repositories.json │ │ │ ├── plugin/ │ │ │ │ ├── data.json │ │ │ │ └── repositories.json │ │ │ ├── python_script/ │ │ │ │ ├── data.json │ │ │ │ └── repositories.json │ │ │ ├── removed/ │ │ │ │ ├── data.json │ │ │ │ └── repositories.json │ │ │ ├── template/ │ │ │ │ ├── data.json │ │ │ │ └── repositories.json │ │ │ └── theme/ │ │ │ ├── data.json │ │ │ └── repositories.json │ │ ├── github.com/ │ │ │ └── hacs-test-org/ │ │ │ ├── appdaemon-basic/ │ │ │ │ └── _base/ │ │ │ │ ├── README.md │ │ │ │ └── apps/ │ │ │ │ └── example/ │ │ │ │ └── __init__.py │ │ │ └── integration-basic/ │ │ │ └── _base/ │ │ │ ├── README.md │ │ │ └── custom_components/ │ │ │ └── example/ │ │ │ └── manifest.json │ │ └── raw.githubusercontent.com/ │ │ └── hacs-test-org/ │ │ ├── appdaemon-basic/ │ │ │ ├── 1.0.0/ │ │ │ │ ├── README.md │ │ │ │ └── hacs.json │ │ │ └── 2.0.0/ │ │ │ ├── README.md │ │ │ └── hacs.json │ │ ├── integration-basic/ │ │ │ ├── 1.0.0/ │ │ │ │ ├── README.md │ │ │ │ └── hacs.json │ │ │ ├── 2.0.0/ │ │ │ │ ├── README.md │ │ │ │ └── hacs.json │ │ │ └── main/ │ │ │ └── hacs.json │ │ ├── plugin-basic/ │ │ │ ├── 1.0.0/ │ │ │ │ ├── hacs.json │ │ │ │ └── plugin-basic.js │ │ │ └── 2.0.0/ │ │ │ ├── hacs.json │ │ │ └── plugin-basic.js │ │ ├── python_script-basic/ │ │ │ ├── 1.0.0/ │ │ │ │ ├── README.md │ │ │ │ ├── hacs.json │ │ │ │ └── python_scripts/ │ │ │ │ └── example.py │ │ │ └── 2.0.0/ │ │ │ ├── README.md │ │ │ ├── hacs.json │ │ │ └── python_scripts/ │ │ │ └── example.py │ │ ├── template-basic/ │ │ │ ├── 1.0.0/ │ │ │ │ ├── example.jinja │ │ │ │ └── hacs.json │ │ │ └── 2.0.0/ │ │ │ ├── example.jinja │ │ │ └── hacs.json │ │ └── theme-basic/ │ │ ├── 1.0.0/ │ │ │ ├── hacs.json │ │ │ └── themes/ │ │ │ └── example.yaml │ │ └── 2.0.0/ │ │ ├── hacs.json │ │ └── themes/ │ │ └── example.yaml │ ├── repository_data.json │ ├── stored_repositories.json │ ├── v2-appdaemon-data.json │ ├── v2-critical-data.json │ ├── v2-integration-data.json │ ├── v2-plugin-data.json │ ├── v2-python_script-data.json │ ├── v2-removed-data.json │ ├── v2-template-data.json │ └── v2-theme-data.json ├── hacsbase/ │ ├── test_backup.py │ ├── test_configuration.py │ ├── test_hacs.py │ └── test_hacsbase_data.py ├── helpers/ │ ├── classes/ │ │ ├── test_repository_data.py │ │ └── test_validate_class.py │ ├── download/ │ │ ├── test_gather_files_to_download.py │ │ └── test_should_try_releases.py │ ├── filters/ │ │ ├── test_filter_content_return_one_of_type.py │ │ └── test_get_first_directory_in_directory.py │ └── functions/ │ └── test_extract_repository_from_url.py ├── homeassistantfixtures/ │ ├── __init__.py │ ├── common.py │ ├── dev.py │ └── min.py ├── integration/ │ └── test_integration_setup.py ├── patch_time.py ├── repositories/ │ ├── helpers/ │ │ ├── __init__.py │ │ └── test_properties.py │ ├── test_can_install.py │ ├── test_display_status.py │ ├── test_download_repository.py │ ├── test_get_documentation.py │ ├── test_get_hacs_json.py │ ├── test_get_hacs_json_raw.py │ ├── test_get_reposiotry_releases.py │ ├── test_hacs_manifest.py │ ├── test_plugin_repository.py │ ├── test_register_repository.py │ ├── test_remove_repository.py │ ├── test_removed_repository.py │ └── test_update_repository.py ├── ruff.toml ├── scripts/ │ └── data/ │ └── test_generate_category_data.py ├── snapshots/ │ ├── action/ │ │ └── test_hacs_action_integration/ │ │ ├── bad_documentation.log │ │ ├── bad_issue_tracker.log │ │ ├── no_releases.log │ │ ├── releases_without_assets.log │ │ └── valid_manifest.log │ ├── api-usage/ │ │ └── tests/ │ │ ├── action/ │ │ │ ├── test_hacs_action_integrationtest-hacs-action-integration-bad-documentation.json │ │ │ ├── test_hacs_action_integrationtest-hacs-action-integration-bad-issue-tracker.json │ │ │ ├── test_hacs_action_integrationtest-hacs-action-integration-no-releases.json │ │ │ ├── test_hacs_action_integrationtest-hacs-action-integration-releases-without-assets.json │ │ │ └── test_hacs_action_integrationtest-hacs-action-integration-valid-manifest.json │ │ ├── hacsbase/ │ │ │ ├── test_backuptest-directory.json │ │ │ ├── test_backuptest-file.json │ │ │ ├── test_backuptest-muilti.json │ │ │ ├── test_hacsbase_datatest-hacs-data-async-write1.json │ │ │ ├── test_hacsbase_datatest-hacs-data-async-write2.json │ │ │ ├── test_hacsbase_datatest-hacs-data-restore-write-not-new.json │ │ │ ├── test_hacstest-add-remove-repository.json │ │ │ └── test_hacstest-hacs.json │ │ ├── helpers/ │ │ │ └── download/ │ │ │ ├── test_gather_files_to_downloadtest-gather-appdaemon-files-base.json │ │ │ ├── test_gather_files_to_downloadtest-gather-appdaemon-files-with-subdir.json │ │ │ ├── test_gather_files_to_downloadtest-gather-content-in-root-theme.json │ │ │ ├── test_gather_files_to_downloadtest-gather-files-to-download.json │ │ │ ├── test_gather_files_to_downloadtest-gather-plugin-different-card-name.json │ │ │ ├── test_gather_files_to_downloadtest-gather-plugin-files-from-dist.json │ │ │ ├── test_gather_files_to_downloadtest-gather-plugin-files-from-release-multiple.json │ │ │ ├── test_gather_files_to_downloadtest-gather-plugin-files-from-release.json │ │ │ ├── test_gather_files_to_downloadtest-gather-plugin-files-from-root.json │ │ │ ├── test_gather_files_to_downloadtest-gather-plugin-multiple-files-in-root.json │ │ │ ├── test_gather_files_to_downloadtest-gather-plugin-multiple-plugin-files-from-dist.json │ │ │ ├── test_gather_files_to_downloadtest-gather-zip-release.json │ │ │ ├── test_gather_files_to_downloadtest-single-file-repo.json │ │ │ ├── test_should_try_releasestest-base.json │ │ │ ├── test_should_try_releasestest-category-is-wrong.json │ │ │ ├── test_should_try_releasestest-no-releases.json │ │ │ ├── test_should_try_releasestest-ref-is-default.json │ │ │ └── test_should_try_releasestest-zip-release.json │ │ ├── integration/ │ │ │ └── test_integration_setuptest-integration-setup.json │ │ ├── repositories/ │ │ │ ├── helpers/ │ │ │ │ ├── test_propertiestest-repository-helpers-properties-can-be-installed.json │ │ │ │ └── test_propertiestest-repository-helpers-properties-pending-update.json │ │ │ ├── test_can_installtest-hacs-can-install.json │ │ │ ├── test_display_statustest-display-status.json │ │ │ ├── test_download_repositorytest-download-repository-hacs-test-org-appdaemon-basic.json │ │ │ ├── test_download_repositorytest-download-repository-hacs-test-org-integration-basic.json │ │ │ ├── test_download_repositorytest-download-repository-hacs-test-org-plugin-basic.json │ │ │ ├── test_download_repositorytest-download-repository-hacs-test-org-python-script-basic.json │ │ │ ├── test_download_repositorytest-download-repository-hacs-test-org-template-basic.json │ │ │ ├── test_download_repositorytest-download-repository-hacs-test-org-theme-basic.json │ │ │ ├── test_get_documentationtest-repository-get-documentation-data0.json │ │ │ ├── test_get_documentationtest-repository-get-documentation-data1.json │ │ │ ├── test_get_documentationtest-repository-get-documentation-data2.json │ │ │ ├── test_get_documentationtest-repository-get-documentation-data3.json │ │ │ ├── test_get_hacs_json_rawtest-get-hacs-json-raw-1-0-0-expected0.json │ │ │ ├── test_get_hacs_json_rawtest-get-hacs-json-raw-99-99-99-none.json │ │ │ ├── test_get_hacs_json_rawtest-get-hacs-json-raw-with-exception.json │ │ │ ├── test_get_hacs_jsontest-get-hacs-json-with-exception.json │ │ │ ├── test_get_hacs_jsontest-validate-repository-1-0-0-integration-basic-1-0-0.json │ │ │ ├── test_get_hacs_jsontest-validate-repository-99-99-99-none.json │ │ │ ├── test_get_reposiotry_releasestest-get-reposiotry-releases-hacs-test-org-appdaemon-basic.json │ │ │ ├── test_get_reposiotry_releasestest-get-reposiotry-releases-hacs-test-org-integration-basic.json │ │ │ ├── test_get_reposiotry_releasestest-get-reposiotry-releases-hacs-test-org-plugin-basic.json │ │ │ ├── test_get_reposiotry_releasestest-get-reposiotry-releases-hacs-test-org-python-script-basic.json │ │ │ ├── test_get_reposiotry_releasestest-get-reposiotry-releases-hacs-test-org-template-basic.json │ │ │ ├── test_get_reposiotry_releasestest-get-reposiotry-releases-hacs-test-org-theme-basic.json │ │ │ ├── test_plugin_repositorytest-add-dashboard-resource-with-invalid-file-name.json │ │ │ ├── test_plugin_repositorytest-add-dashboard-resource.json │ │ │ ├── test_plugin_repositorytest-dashboard-hacstag-1-0-0-none-none-100.json │ │ │ ├── test_plugin_repositorytest-dashboard-hacstag-1-7-dev09-r2-none-none-17092.json │ │ │ ├── test_plugin_repositorytest-dashboard-hacstag-none-2-0-1-none-201.json │ │ │ ├── test_plugin_repositorytest-dashboard-hacstag-none-none-3-4-2-342.json │ │ │ ├── test_plugin_repositorytest-dashboard-hacstag-none-none-none.json │ │ │ ├── test_plugin_repositorytest-dashboard-namespace-hacs-test-org-awesome-plugin-hacsfiles-awesome-plugin.json │ │ │ ├── test_plugin_repositorytest-dashboard-namespace-hacs-test-org-plugin-advanced-hacsfiles-plugin-advanced.json │ │ │ ├── test_plugin_repositorytest-dashboard-namespace-hacs-test-org-plugin-basic-hacsfiles-plugin-basic.json │ │ │ ├── test_plugin_repositorytest-dashboard-url.json │ │ │ ├── test_plugin_repositorytest-get-resource-handler-no-hass-data.json │ │ │ ├── test_plugin_repositorytest-get-resource-handler-no-lovelace-data.json │ │ │ ├── test_plugin_repositorytest-get-resource-handler-no-lovelace-resources.json │ │ │ ├── test_plugin_repositorytest-get-resource-handler-no-store.json │ │ │ ├── test_plugin_repositorytest-get-resource-handler-none-store.json │ │ │ ├── test_plugin_repositorytest-get-resource-handler-wrong-key.json │ │ │ ├── test_plugin_repositorytest-get-resource-handler-wrong-version.json │ │ │ ├── test_plugin_repositorytest-get-resource-handler.json │ │ │ ├── test_plugin_repositorytest-remove-dashboard-resource.json │ │ │ ├── test_plugin_repositorytest-update-dashboard-resource.json │ │ │ ├── test_register_repositorytest-register-repository-failures-hacs-test-org-addon-basic-the-repository-does-not-seem-to-be-a-integration-but-an-add-on-repository-hacs-does-not-manage-add-ons.json │ │ │ ├── test_register_repositorytest-register-repository-failures-hacs-test-org-integration-invalid-integration-hacs-test-org-integration-invalid-repository-structure-for-main-is-not-compliant.json │ │ │ ├── test_register_repositorytest-register-repository-failures-hassio-addons-example-the-repository-does-not-seem-to-be-a-integration-but-an-add-on-repository-hacs-does-not-manage-add-ons.json │ │ │ ├── test_register_repositorytest-register-repository-failures-home-assistant-addons-the-repository-does-not-seem-to-be-a-integration-but-an-add-on-repository-hacs-does-not-manage-add-ons.json │ │ │ ├── test_register_repositorytest-register-repository-failures-home-assistant-core-you-can-not-add-homeassistant-core-to-use-core-integrations-check-the-home-assistant-documentation-for-how-to-add-them.json │ │ │ ├── test_register_repositorytest-register-repository-hacs-test-org-integration-basic-custom-integration.json │ │ │ ├── test_register_repositorytest-register-repository-hacs-test-org-plugin-custom-dist-plugin.json │ │ │ ├── test_remove_repositorytest-remove-repository-hacs-test-org-appdaemon-basic.json │ │ │ ├── test_remove_repositorytest-remove-repository-hacs-test-org-integration-basic.json │ │ │ ├── test_remove_repositorytest-remove-repository-hacs-test-org-plugin-basic.json │ │ │ ├── test_remove_repositorytest-remove-repository-hacs-test-org-python-script-basic.json │ │ │ ├── test_remove_repositorytest-remove-repository-hacs-test-org-template-basic.json │ │ │ ├── test_remove_repositorytest-remove-repository-hacs-test-org-theme-basic.json │ │ │ ├── test_update_repositorytest-update-repository-entity-download-failure.json │ │ │ ├── test_update_repositorytest-update-repository-entity-hacs-test-org-appdaemon-basic.json │ │ │ ├── test_update_repositorytest-update-repository-entity-hacs-test-org-integration-basic.json │ │ │ ├── test_update_repositorytest-update-repository-entity-hacs-test-org-plugin-basic.json │ │ │ ├── test_update_repositorytest-update-repository-entity-hacs-test-org-python-script-basic.json │ │ │ ├── test_update_repositorytest-update-repository-entity-hacs-test-org-template-basic.json │ │ │ ├── test_update_repositorytest-update-repository-entity-hacs-test-org-theme-basic.json │ │ │ ├── test_update_repositorytest-update-repository-entity-no-manifest.json │ │ │ ├── test_update_repositorytest-update-repository-entity-no-update.json │ │ │ ├── test_update_repositorytest-update-repository-entity-old-core-version.json │ │ │ ├── test_update_repositorytest-update-repository-entity-old-hacs-version.json │ │ │ ├── test_update_repositorytest-update-repository-entity-same-provided-version.json │ │ │ ├── test_update_repositorytest-update-repository-websocket-hacs-test-org-appdaemon-basic.json │ │ │ ├── test_update_repositorytest-update-repository-websocket-hacs-test-org-integration-basic.json │ │ │ ├── test_update_repositorytest-update-repository-websocket-hacs-test-org-plugin-basic.json │ │ │ ├── test_update_repositorytest-update-repository-websocket-hacs-test-org-python-script-basic.json │ │ │ ├── test_update_repositorytest-update-repository-websocket-hacs-test-org-template-basic.json │ │ │ └── test_update_repositorytest-update-repository-websocket-hacs-test-org-theme-basic.json │ │ ├── scripts/ │ │ │ └── data/ │ │ │ ├── test_generate_category_datatest-generate-category-data-error-status-release-304-hacs-test-org-integration-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-error-status-release-404-hacs-test-org-integration-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-errors-release-cancellederror-hacs-test-org-integration-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-errors-release-error2-hacs-test-org-integration-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-errors-release-timeouterror-hacs-test-org-integration-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-hacs-test-org-appdaemon-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-hacs-test-org-integration-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-hacs-test-org-plugin-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-hacs-test-org-python-script-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-hacs-test-org-template-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-hacs-test-org-theme-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-single-repository-hacs-test-org-appdaemon-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-single-repository-hacs-test-org-integration-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-single-repository-hacs-test-org-plugin-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-single-repository-hacs-test-org-python-script-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-single-repository-hacs-test-org-template-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-single-repository-hacs-test-org-theme-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-with-30plus-prereleases-hacs-test-org-integration-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-with-prior-content-hacs-test-org-appdaemon-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-with-prior-content-hacs-test-org-integration-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-with-prior-content-hacs-test-org-plugin-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-with-prior-content-hacs-test-org-python-script-basic.json │ │ │ ├── test_generate_category_datatest-generate-category-data-with-prior-content-hacs-test-org-template-basic.json │ │ │ └── test_generate_category_datatest-generate-category-data-with-prior-content-hacs-test-org-theme-basic.json │ │ ├── test_config_flowtest-flow-with-activation-failure.json │ │ ├── test_config_flowtest-flow-with-registration-failure.json │ │ ├── test_config_flowtest-flow-with-remove-while-activating.json │ │ ├── test_config_flowtest-full-user-flow-implementation.json │ │ ├── test_config_flowtest-options-flow.json │ │ ├── test_data_clienttest-basic-functionality-data-hacs-test-org-appdaemon-basic.json │ │ ├── test_data_clienttest-basic-functionality-data-hacs-test-org-integration-basic.json │ │ ├── test_data_clienttest-basic-functionality-data-hacs-test-org-plugin-basic.json │ │ ├── test_data_clienttest-basic-functionality-data-hacs-test-org-python-script-basic.json │ │ ├── test_data_clienttest-basic-functionality-data-hacs-test-org-template-basic.json │ │ ├── test_data_clienttest-basic-functionality-data-hacs-test-org-theme-basic.json │ │ ├── test_data_clienttest-basic-functionality-data-validate-appdaemon-data0.json │ │ ├── test_data_clienttest-basic-functionality-data-validate-critical-data6.json │ │ ├── test_data_clienttest-basic-functionality-data-validate-integration-data1.json │ │ ├── test_data_clienttest-basic-functionality-data-validate-plugin-data2.json │ │ ├── test_data_clienttest-basic-functionality-data-validate-python-script-data3.json │ │ ├── test_data_clienttest-basic-functionality-data-validate-removed-data7.json │ │ ├── test_data_clienttest-basic-functionality-data-validate-template-data4.json │ │ ├── test_data_clienttest-basic-functionality-data-validate-theme-data5.json │ │ ├── test_data_clienttest-basic-functionality-repositories-hacs-test-org-appdaemon-basic.json │ │ ├── test_data_clienttest-basic-functionality-repositories-hacs-test-org-integration-basic.json │ │ ├── test_data_clienttest-basic-functionality-repositories-hacs-test-org-plugin-basic.json │ │ ├── test_data_clienttest-basic-functionality-repositories-hacs-test-org-python-script-basic.json │ │ ├── test_data_clienttest-basic-functionality-repositories-hacs-test-org-template-basic.json │ │ ├── test_data_clienttest-basic-functionality-repositories-hacs-test-org-theme-basic.json │ │ ├── test_data_clienttest-discard-invalid-repo-data-appdaemon-data0.json │ │ ├── test_data_clienttest-discard-invalid-repo-data-integration-data1.json │ │ ├── test_data_clienttest-discard-invalid-repo-data-plugin-data2.json │ │ ├── test_data_clienttest-discard-invalid-repo-data-python-script-data3.json │ │ ├── test_data_clienttest-discard-invalid-repo-data-template-data4.json │ │ ├── test_data_clienttest-discard-invalid-repo-data-theme-data5.json │ │ ├── test_data_clienttest-exception-handling-exception-error-fetching-data-from-hacs-test.json │ │ ├── test_data_clienttest-exception-handling-timeouterror-timeout-of-60s-reached.json │ │ ├── test_data_clienttest-status-handling-1009-hacsexception.json │ │ ├── test_data_clienttest-status-handling-200-does-not-raise.json │ │ ├── test_data_clienttest-status-handling-201-does-not-raise.json │ │ ├── test_data_clienttest-status-handling-301-hacsexception.json │ │ ├── test_data_clienttest-status-handling-302-hacsexception.json │ │ ├── test_data_clienttest-status-handling-304-hacsnotmodifiedexception.json │ │ ├── test_data_clienttest-status-handling-400-hacsexception.json │ │ ├── test_data_clienttest-status-handling-401-hacsexception.json │ │ ├── test_data_clienttest-status-handling-403-hacsexception.json │ │ ├── test_data_clienttest-status-handling-418-hacsexception.json │ │ ├── test_data_clienttest-status-handling-429-hacsexception.json │ │ ├── test_data_clienttest-status-handling-500-hacsexception.json │ │ ├── test_data_clienttest-status-handling-529-hacsexception.json │ │ ├── test_diagnosticstest-diagnostics-with-exception.json │ │ ├── test_diagnosticstest-diagnostics.json │ │ ├── test_sensor_cleanuptest-sensor-cleanup.json │ │ ├── test_switchtest-switch-entity-state-hacs-test-org-appdaemon-basic.json │ │ ├── test_switchtest-switch-entity-state-hacs-test-org-integration-basic.json │ │ ├── test_switchtest-switch-entity-state-hacs-test-org-plugin-basic.json │ │ ├── test_switchtest-switch-entity-state-hacs-test-org-python-script-basic.json │ │ ├── test_switchtest-switch-entity-state-hacs-test-org-template-basic.json │ │ ├── test_switchtest-switch-entity-state-hacs-test-org-theme-basic.json │ │ ├── test_system_healthtest-system-health-after-unload.json │ │ ├── test_system_healthtest-system-health.json │ │ ├── test_updatetest-update-entity-state-hacs-test-org-appdaemon-basic.json │ │ ├── test_updatetest-update-entity-state-hacs-test-org-integration-basic.json │ │ ├── test_updatetest-update-entity-state-hacs-test-org-plugin-basic.json │ │ ├── test_updatetest-update-entity-state-hacs-test-org-python-script-basic.json │ │ ├── test_updatetest-update-entity-state-hacs-test-org-template-basic.json │ │ ├── test_updatetest-update-entity-state-hacs-test-org-theme-basic.json │ │ ├── utils/ │ │ │ ├── test_pathtest-is-safe.json │ │ │ ├── test_queue_managertest-queue-manager.json │ │ │ └── test_versiontest-version-to-download.json │ │ └── validate/ │ │ ├── test_async_run_repository_checkstest-async-run-repository-checks.json │ │ ├── test_brands_checktest-added-to-brands.json │ │ ├── test_brands_checktest-local-brands-asset-content-in-root.json │ │ ├── test_brands_checktest-local-brands-asset-missing-falls-back-to-remote.json │ │ ├── test_brands_checktest-local-brands-asset-not-in-root.json │ │ ├── test_brands_checktest-not-added-to-brands.json │ │ ├── test_hacsjson_checktest-hacs-manifest-integration-zip-release-with-filename.json │ │ ├── test_hacsjson_checktest-hacs-manifest-no-manifest.json │ │ ├── test_hacsjson_checktest-hacs-manifest-with-invalid-manifest.json │ │ ├── test_hacsjson_checktest-hacs-manifest-with-missing-filename.json │ │ ├── test_hacsjson_checktest-hacs-manifest-with-valid-manifest.json │ │ ├── test_images_checktest-repository-has-images.json │ │ ├── test_images_checktest-repository-has-not-images.json │ │ ├── test_integration_manifest_checktest-hacs-manifest-with-invalid-manifest.json │ │ ├── test_integration_manifest_checktest-integration-manifest-with-valid-manifest.json │ │ ├── test_integration_manifest_checktest-integration-no-manifest.json │ │ ├── test_repository_archived_checktest-repository-archived.json │ │ ├── test_repository_archived_checktest-repository-not-archived.json │ │ ├── test_repository_description_checktest-repository-hacs-description.json │ │ ├── test_repository_description_checktest-repository-no-description.json │ │ ├── test_repository_information_file_checktest-has-info-file.json │ │ ├── test_repository_information_file_checktest-has-info-md-file.json │ │ ├── test_repository_information_file_checktest-has-readme-file.json │ │ ├── test_repository_information_file_checktest-has-readme-md-file.json │ │ ├── test_repository_information_file_checktest-no-info-file.json │ │ ├── test_repository_information_file_checktest-no-readme-file.json │ │ ├── test_repository_issues_checktest-repository-issues-enabled.json │ │ ├── test_repository_issues_checktest-repository-issues-not-enabled.json │ │ ├── test_repository_topics_checktest-repository-hacs-topics.json │ │ └── test_repository_topics_checktest-repository-no-topics.json │ ├── config_flow/ │ │ ├── test_already_configured.json │ │ ├── test_flow_with_activation_failure.json │ │ ├── test_flow_with_registration_failure.json │ │ └── test_full_user_flow_implementation.json │ ├── data_client/ │ │ └── base/ │ │ ├── data/ │ │ │ ├── appdaemon.json │ │ │ ├── integration.json │ │ │ ├── plugin.json │ │ │ ├── python_script.json │ │ │ ├── template.json │ │ │ └── theme.json │ │ ├── data_validate/ │ │ │ ├── appdaemon.json │ │ │ ├── critical.json │ │ │ ├── integration.json │ │ │ ├── plugin.json │ │ │ ├── python_script.json │ │ │ ├── removed.json │ │ │ ├── template.json │ │ │ └── theme.json │ │ └── repositories/ │ │ ├── appdaemon.json │ │ ├── integration.json │ │ ├── plugin.json │ │ ├── python_script.json │ │ ├── template.json │ │ └── theme.json │ ├── diagnostics/ │ │ ├── base.json │ │ └── exception.json │ ├── hacs-test-org/ │ │ ├── appdaemon-basic/ │ │ │ ├── test_discard_invalid_repo_data.json │ │ │ ├── test_download_repository.json │ │ │ ├── test_get_reposiotry_releases.json │ │ │ ├── test_remove_repository_post.json │ │ │ ├── test_remove_repository_pre.json │ │ │ ├── test_switch/ │ │ │ │ └── entity_states.json │ │ │ ├── test_update_entity_state.json │ │ │ ├── test_update_repository_entity.json │ │ │ └── test_update_repository_websocket.json │ │ ├── integration-basic/ │ │ │ ├── get_documentation/ │ │ │ │ ├── installed_false_last_version_2_0_0.md │ │ │ │ ├── installed_false_last_version_99_99_99.md │ │ │ │ ├── installed_true_installed_version_1_0_0.md │ │ │ │ └── installed_true_installed_version_1_0_0_last_version_2_0_0.md │ │ │ ├── test_discard_invalid_repo_data.json │ │ │ ├── test_download_repository.json │ │ │ ├── test_get_reposiotry_releases.json │ │ │ ├── test_remove_repository_post.json │ │ │ ├── test_remove_repository_pre.json │ │ │ ├── test_switch/ │ │ │ │ └── entity_states.json │ │ │ ├── test_update_entity_state.json │ │ │ ├── test_update_repository_entity.json │ │ │ └── test_update_repository_websocket.json │ │ ├── integration-basic-custom/ │ │ │ └── test_register_repository.json │ │ ├── plugin-basic/ │ │ │ ├── test_discard_invalid_repo_data.json │ │ │ ├── test_download_repository.json │ │ │ ├── test_get_reposiotry_releases.json │ │ │ ├── test_remove_repository_post.json │ │ │ ├── test_remove_repository_pre.json │ │ │ ├── test_switch/ │ │ │ │ └── entity_states.json │ │ │ ├── test_update_entity_state.json │ │ │ ├── test_update_repository_entity.json │ │ │ └── test_update_repository_websocket.json │ │ ├── plugin-custom-dist/ │ │ │ └── test_register_repository.json │ │ ├── python_script-basic/ │ │ │ ├── test_discard_invalid_repo_data.json │ │ │ ├── test_download_repository.json │ │ │ ├── test_get_reposiotry_releases.json │ │ │ ├── test_remove_repository_post.json │ │ │ ├── test_remove_repository_pre.json │ │ │ ├── test_switch/ │ │ │ │ └── entity_states.json │ │ │ ├── test_update_entity_state.json │ │ │ ├── test_update_repository_entity.json │ │ │ └── test_update_repository_websocket.json │ │ ├── template-basic/ │ │ │ ├── test_discard_invalid_repo_data.json │ │ │ ├── test_download_repository.json │ │ │ ├── test_get_reposiotry_releases.json │ │ │ ├── test_remove_repository_post.json │ │ │ ├── test_remove_repository_pre.json │ │ │ ├── test_switch/ │ │ │ │ └── entity_states.json │ │ │ ├── test_update_entity_state.json │ │ │ ├── test_update_repository_entity.json │ │ │ └── test_update_repository_websocket.json │ │ └── theme-basic/ │ │ ├── test_discard_invalid_repo_data.json │ │ ├── test_download_repository.json │ │ ├── test_get_reposiotry_releases.json │ │ ├── test_remove_repository_post.json │ │ ├── test_remove_repository_pre.json │ │ ├── test_switch/ │ │ │ └── entity_states.json │ │ ├── test_update_entity_state.json │ │ ├── test_update_repository_entity.json │ │ └── test_update_repository_websocket.json │ ├── scripts/ │ │ └── data/ │ │ ├── generate_category_data/ │ │ │ ├── appdaemon/ │ │ │ │ ├── data.json │ │ │ │ ├── repositories.json │ │ │ │ └── summary.json │ │ │ ├── integration/ │ │ │ │ ├── data.json │ │ │ │ ├── repositories.json │ │ │ │ └── summary.json │ │ │ ├── plugin/ │ │ │ │ ├── data.json │ │ │ │ ├── repositories.json │ │ │ │ └── summary.json │ │ │ ├── python_script/ │ │ │ │ ├── data.json │ │ │ │ ├── repositories.json │ │ │ │ └── summary.json │ │ │ ├── single/ │ │ │ │ ├── appdaemon/ │ │ │ │ │ └── hacs-test-org/ │ │ │ │ │ └── appdaemon-basic/ │ │ │ │ │ ├── data.json │ │ │ │ │ ├── repositories.json │ │ │ │ │ └── summary.json │ │ │ │ ├── integration/ │ │ │ │ │ └── hacs-test-org/ │ │ │ │ │ └── integration-basic/ │ │ │ │ │ ├── data.json │ │ │ │ │ ├── repositories.json │ │ │ │ │ └── summary.json │ │ │ │ ├── plugin/ │ │ │ │ │ └── hacs-test-org/ │ │ │ │ │ └── plugin-basic/ │ │ │ │ │ ├── data.json │ │ │ │ │ ├── repositories.json │ │ │ │ │ └── summary.json │ │ │ │ ├── python_script/ │ │ │ │ │ └── hacs-test-org/ │ │ │ │ │ └── python_script-basic/ │ │ │ │ │ ├── data.json │ │ │ │ │ ├── repositories.json │ │ │ │ │ └── summary.json │ │ │ │ ├── template/ │ │ │ │ │ └── hacs-test-org/ │ │ │ │ │ └── template-basic/ │ │ │ │ │ ├── data.json │ │ │ │ │ ├── repositories.json │ │ │ │ │ └── summary.json │ │ │ │ └── theme/ │ │ │ │ └── hacs-test-org/ │ │ │ │ └── theme-basic/ │ │ │ │ ├── data.json │ │ │ │ ├── repositories.json │ │ │ │ └── summary.json │ │ │ ├── template/ │ │ │ │ ├── data.json │ │ │ │ ├── repositories.json │ │ │ │ └── summary.json │ │ │ └── theme/ │ │ │ ├── data.json │ │ │ ├── repositories.json │ │ │ └── summary.json │ │ ├── test_generate_category_data_error_status_release/ │ │ │ └── integration/ │ │ │ ├── 304.json │ │ │ └── 404.json │ │ ├── test_generate_category_data_errors_release/ │ │ │ └── integration/ │ │ │ ├── CancelledError.json │ │ │ ├── TimeoutError.json │ │ │ └── error2.json │ │ ├── test_generate_category_data_with_30plus_prereleases/ │ │ │ └── integration.json │ │ └── test_generate_category_data_with_prior_content/ │ │ ├── appdaemon.json │ │ ├── integration.json │ │ ├── plugin.json │ │ ├── python_script.json │ │ ├── template.json │ │ └── theme.json │ ├── system_health/ │ │ ├── system_health.json │ │ └── system_health_after_unload.json │ ├── test_integration_setup.json │ └── test_integration_setup_with_custom_updater.json ├── test_config_flow.py ├── test_data_client.py ├── test_diagnostics.py ├── test_emuns.py ├── test_sensor_cleanup.py ├── test_switch.py ├── test_system_health.py ├── test_update.py ├── utils/ │ ├── test_decorator.py │ ├── test_fs_util.py │ ├── test_path.py │ ├── test_queue_manager.py │ ├── test_store.py │ ├── test_url.py │ ├── test_validate.py │ ├── test_version.py │ └── test_workarounds.py └── validate/ ├── test_async_run_repository_checks.py ├── test_brands_check.py ├── test_hacsjson_check.py ├── test_images_check.py ├── test_integration_manifest_check.py ├── test_repository_archived_check.py ├── test_repository_description_check.py ├── test_repository_information_file_check.py ├── test_repository_issues_check.py └── test_repository_topics_check.py ================================================ FILE CONTENTS ================================================ ================================================ FILE: .codeclimate.yml ================================================ --- engines: duplication: enabled: true config: languages: - python fixme: enabled: true radon: enabled: true ratings: paths: - "**.py" exclude_paths: - tests/ - action/ - scripts/ ================================================ FILE: .codecov.yml ================================================ comment: false codecov: branch: main coverage: precision: 2 round: down range: "60...100" status: patch: off project: default: target: 50% validate: target: 100% paths: - custom_components/hacs/validate/ repositories: target: 50% paths: - custom_components/hacs/repositories/ parsers: gcov: branch_detection: conditional: yes loop: yes method: no macro: no ignore: - "tests" ================================================ FILE: .coveragerc ================================================ [run] source = custom_components omit = # omit tests tests/* # omit scripts scripts/update/* [report] exclude_lines = if TYPE_CHECKING: ================================================ FILE: .devcontainer.json ================================================ { "name": "hacs/integration", "image": "mcr.microsoft.com/devcontainers/python:1-3.13", "postCreateCommand": "scripts/setup", "forwardPorts": [ 8123 ], "portsAttributes": { "8123": { "label": "Home Assistant" }, "0-8122": { "label": "Auto-Forwarded - Other", "onAutoForward": "ignore" }, "8124-999999": { "label": "Auto-Forwarded - Other", "onAutoForward": "ignore" } }, "customizations": { "extensions": [ "charliermarsh.ruff", "ms-python.python", "github.vscode-pull-request-github", "ryanluker.vscode-coverage-gutters", "ms-python.vscode-pylance", "GitHub.copilot" ], "vscode": { "settings": { "python.pythonPath": "/usr/local/bin/python", "python.formatting.provider": "ruff", "editor.formatOnPaste": false, "editor.formatOnSave": true, "editor.formatOnType": true, "editor.defaultFormatter": "charliermarsh.ruff", "editor.rulers": [ 100 ], "editor.codeActionsOnSave": { "source.fixAll": "always", "source.organizeImports": "always" }, "files.trimTrailingWhitespace": true }, "extensions": [ "GitHub.copilot", "github.vscode-pull-request-github", "ms-python.python", "ms-python.vscode-pylance", "ms-vscode.makefile-tools", "ryanluker.vscode-coverage-gutters" ] } }, "remoteUser": "vscode", "features": { "ghcr.io/anthropics/devcontainer-features/claude-code:1.0": {}, "ghcr.io/devcontainers/features/github-cli:1": {}, "ghcr.io/devcontainers/features/node:1": {}, "ghcr.io/devcontainers/features/rust:1": {} } } ================================================ FILE: .dockerignore ================================================ * !custom_components/hacs !scripts !action !constraints.txt !requirements_action.txt ================================================ FILE: .gitattributes ================================================ text eol=lf ================================================ FILE: .github/ISSUE_TEMPLATE/a_integration.yml ================================================ --- name: "Backend/Integration" description: You use this when something is not doing what it's supposed to do. labels: "issue:backend" body: - type: markdown attributes: value: | Learn how to submit an issue here https://hacs.xyz/docs/help/issues/ Before you open a new issue, search through the existing issues to see if others have had the same problem. The issue template is not a suggestion, fill out everything that is asked. - type: textarea attributes: label: "System Health details" description: "Paste the data from the System Health card in Home Assistant (https://www.home-assistant.io//more-info/system-health#github-issues)" validations: required: true - type: checkboxes attributes: label: Checklist options: - label: I'm running the newest version of HACS required: true - label: I have enabled debug logging for my installation. required: true - label: I have filled out the issue template to the best of my ability. required: true - label: I have read required: true - label: This issue is related to the backend (integration part) of HACS. required: true - label: This issue only contains 1 issue (if you have multiple issues, open one issue for each issue). required: true - label: This is a bug and not a feature request. required: true - label: This issue is not a duplicate issue of currently [open](https://github.com/hacs/integration/issues) or issues [pending release](https://github.com/hacs/integration/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc+milestone%3Anext). required: true - type: textarea attributes: label: "Describe the issue" description: "A clear and concise description of what the issue is." validations: required: true - type: textarea attributes: label: Reproduction steps description: "Without steps to reproduce, it will be hard to fix, it is very important that you fill out this part, issues without it will be closed" value: | 1. 2. 3. ... validations: required: true - type: textarea attributes: label: "Debug logs" description: "To enable debug logs check this https://hacs.xyz/docs/use/troubleshooting/logs/, this **needs** to include _everything_ from startup of Home Assistant to the point where you encounter the issue." render: text validations: required: true - type: textarea attributes: label: "Diagnostics dump" description: "Drag or paste the diagnostics dump file here. (see https://hacs.xyz/docs/use/troubleshooting/diagnostics/ for info)" validations: required: true ================================================ FILE: .github/ISSUE_TEMPLATE/b_frontend.yml ================================================ --- name: "Frontend" description: You use this when elements in the UI are not working correctly. labels: "issue:frontend" body: - type: markdown attributes: value: | Learn how to submit an issue here https://hacs.xyz/docs/help/issues/ Before you open a new issue, search through the existing issues to see if others have had the same problem. The issue template is not a suggestion, fill out everything that is asked. - type: markdown attributes: value: "## Installation details" - type: input attributes: label: Web browser description: The type of browser you are using validations: required: true - type: input attributes: label: Web browser version description: The version of the browser you are using validations: required: true - type: textarea attributes: label: "System Health details" description: "Paste the data from the System Health card in Home Assistant (https://www.home-assistant.io//more-info/system-health#github-issues)" validations: required: true - type: checkboxes attributes: label: Checklist options: - label: I'm running the newest version of HACS required: true - label: I have filled out the issue template to the best of my ability. required: true - label: I have read required: true - label: This issue is related to the frontend of HACS. required: true - label: This issue only contains 1 issue (if you have multiple issues, open one issue for each issue). required: true - label: This is a bug and not a feature request. required: true - label: This issue is not a duplicate issue of currently [open](https://github.com/hacs/integration/issues) or issues [pending release](https://github.com/hacs/integration/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc+milestone%3Anext). required: true - type: textarea attributes: label: Describe the issue placeholder: "A clear and concise description of what the issue is." validations: required: true - type: textarea attributes: label: Reproduction steps description: "Without steps to reproduce, it will be hard to fix, it is very important that you fill out this part, issues without it will be closed" value: | 1. 2. 3. ... validations: required: true - type: textarea attributes: label: Screenshots placeholder: "Here you paste screenshots to showcase the issue." validations: required: true - type: textarea attributes: label: "Javascript logs from your browser console" render: text validations: required: true - type: textarea attributes: label: "Debug logs" description: "To enable debug logs check this https://hacs.xyz/docs/use/troubleshooting/logs/, this **needs** to include _everything_ from startup of Home Assistant to the point where you encounter the issue." render: text validations: required: true - type: textarea attributes: label: "Diagnostics dump" description: "Drag or paste the diagnostics dump file here. (see https://hacs.xyz/docs/use/troubleshooting/diagnostics/ for info)" validations: required: true ================================================ FILE: .github/ISSUE_TEMPLATE/c_bot.yml ================================================ --- name: "hacs-bot" description: You use this when hacs-bot did something wrong. labels: "issue:bot" body: - type: markdown attributes: value: | Learn how to submit an issue here https://hacs.xyz/docs/help/issues/ Before you open a new issue, search through the existing issues to see if others have had the same problem. The issue template is not a suggestion, fill out everything that is asked. - type: textarea attributes: label: Describe the issue placeholder: "A clear and concise description of what the issue is." validations: required: true - type: checkboxes attributes: label: Checklist options: - label: I have filled out the issue template to the best of my ability. required: true - label: I have read required: true - label: This issue is related to the HACS bot. required: true - label: This issue only contains 1 issue (if you have multiple issues, open one issue for each issue). required: true - label: This is a bug and not a feature request. required: true - label: This issue is not a duplicate issue of currently [open](https://github.com/hacs/integration/issues) or issues [pending release](https://github.com/hacs/integration/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc+milestone%3Anext). required: true ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: false contact_links: - name: HACS Looks different url: https://experimental.hacs.xyz/docs/use/dashboard/ about: HACS does not look like others/HACS not showing menu/HACS does not look like guides/youtube Im following - name: Closed issues for next release url: https://github.com/hacs/integration/issues?q=is%3Aissue+is%3Aclosed+sort%3Aupdated-desc+milestone%3Anext about: Se closed issues that will be a part of the next release - name: How to file an issue url: https://hacs.xyz/docs/issues about: Describes what an issue should contain - name: HACS Documentation url: https://hacs.xyz/ about: The documentation for HACS - name: HACS Discord server url: https://discord.gg/apgchf8 about: For questions about HACS ================================================ FILE: .github/ISSUE_TEMPLATE/d_documentation.yml ================================================ --- name: "Documentation" description: You use this when something is wrong with the documentation. labels: "issue:documentation" body: - type: markdown attributes: value: | Learn how to submit an issue here https://hacs.xyz/docs/help/issues/ Before you open a new issue, search through the existing issues to see if others have had the same problem. The issue template is not a suggestion, fill out everything that is asked. - type: textarea attributes: label: Describe the issue placeholder: "A clear and concise description of what the issue is." validations: required: true - type: textarea attributes: label: Screenshots placeholder: "Here you paste screenshots to showcase the issue." ================================================ FILE: .github/ISSUE_TEMPLATE/e_action.yml ================================================ --- name: "HACS Action" description: You use this when there is an issue with the HACS action. labels: "issue:action" body: - type: markdown attributes: value: | Learn how to submit an issue here https://hacs.xyz/docs/help/issues/ Before you open a new issue, search through the existing issues to see if others have had the same problem. The issue template is not a suggestion, fill out everything that is asked. - type: textarea attributes: label: Describe the issue placeholder: "A clear and concise description of what the issue is." validations: required: true - type: input attributes: label: Link to action run validations: required: true - type: input attributes: label: Link to action configuration validations: required: true - type: checkboxes attributes: label: Checklist options: - label: I have filled out the issue template to the best of my ability. required: true - label: I have read required: true - label: This issue is related to the HACS action. required: true - label: This is a bug and not a feature request. required: true - label: This issue only contains 1 issue (if you have multiple issues, open one issue for each issue). required: true ================================================ FILE: .github/ISSUE_TEMPLATE/f_addon.yml ================================================ --- name: "HACS Add-ons" description: You use this when there is an issue with one of the HACS Add-ons labels: "issue:addon" body: - type: markdown attributes: value: | Learn how to submit an issue here https://hacs.xyz/docs/help/issues/ Before you open a new issue, search through the existing issues to see if others have had the same problem. The issue template is not a suggestion, fill out everything that is asked. - type: checkboxes attributes: label: Checklist options: - label: I have filled out the issue template to the best of my ability. required: true - label: I have read required: true - label: This issue is related to one the HACS add-ons. required: true - label: This is a bug and not a feature request. required: true - label: This issue only contains 1 issue (if you have multiple issues, open one issue for each issue). required: true - type: dropdown validations: required: true attributes: label: Which Add-on are you reporting an issue for? options: - get - type: textarea attributes: label: Describe the issue placeholder: "A clear and concise description of what the issue is." validations: required: true - type: textarea attributes: label: Add-on logs validations: required: true - type: textarea attributes: label: Supervisor logs validations: required: true - type: textarea attributes: label: "Diagnostics dump" description: "Drag or paste the diagnostics dump file here. (see https://hacs.xyz/docs/use/troubleshooting/diagnostics/ for info)" validations: required: true ================================================ FILE: .github/ISSUE_TEMPLATE/removal.yml ================================================ --- name: Request for repository removal description: Flagging of repository that should be removed from HACS labels: flag body: - type: markdown attributes: value: | Learn how to submit an issue here https://hacs.xyz/docs/help/issues/ Before you open a new issue, search through the existing issues to see if others have had the same problem. The issue template is not a suggestion, fill out everything that is asked. - type: input id: repo attributes: label: Repository description: The repository that is requested to be removed (owner/repository) validations: required: true - type: checkboxes attributes: label: Checklist options: - label: I understand that this form should only be used for repositories that needs to be removed from HACS required: true - label: I understand that a bug is not reason enough to have a repository removed required: true - label: The repository is currently shipped as a default repository in HACS required: true - label: I have tried to get the authors attention to the reason for removal required: true - type: textarea attributes: label: Why should this be removed? placeholder: "Describe why the repository should be removed from HACS. If you are flagging a repository for removal without a good reason/description, the request will be closed" validations: required: true - type: input attributes: label: Link to issue description: The URL to the issue that shows an attempt to contact the author has been made validations: required: true ================================================ FILE: .github/dependabot.yml ================================================ version: 2 updates: - package-ecosystem: "devcontainers" directory: "/" labels: - "pr: dependency-update" schedule: interval: weekly time: "06:00" open-pull-requests-limit: 10 - package-ecosystem: "github-actions" directory: "/" labels: - "pr: dependency-update" schedule: interval: weekly time: "06:00" open-pull-requests-limit: 10 - package-ecosystem: pip directory: "/" labels: - "pr: dependency-update" schedule: interval: weekly time: "06:00" open-pull-requests-limit: 10 ================================================ FILE: .github/pre-commit-config.yaml ================================================ repos: - repo: local hooks: - id: codespell name: Check code for common misspellings language: system types: [text] stages: [pre-commit, pre-push, manual] entry: codespell args: - --quiet-level=2 - --ignore-words-list=hass,ba,fo - --skip=tests/fixtures/* - id: isort name: Sort imports language: system types: [text] stages: [pre-commit, pre-push, manual] entry: isort - id: pyupgrade name: Run pyupgrade language: system types: [text] stages: [pre-commit, pre-push, manual] entry: pyupgrade files: ^.*.py$ args: - "--py39-plus" - id: ruff-check name: Run ruff check language: system types: [text] stages: [pre-commit, pre-push, manual] entry: ruff args: - check files: ^((action|custom_components|script|tests)/.+)?[^/]+\.py$ - id: ruff-format name: Run ruff format language: system types: [text] stages: [pre-commit, pre-push, manual] entry: ruff args: - format files: ^((action|custom_components|script)/.+)?[^/]+\.py$ - id: check-executables-have-shebangs name: Check that executables have shebangs language: system types: [text, executable] entry: check-executables-have-shebangs stages: [pre-commit, pre-push, manual] - id: check-json name: Check JSON files language: system types: [json] stages: [pre-commit, pre-push, manual] entry: check-json - id: requirements-txt-fixer name: Check requirements files language: system types: [text] stages: [pre-commit, pre-push, manual] entry: requirements-txt-fixer files: ^requirements_.*.txt$ - id: check-ast name: Check Python AST language: system types: [python] stages: [pre-commit, pre-push, manual] entry: check-ast - id: mixed-line-ending name: Check line nedings language: system types: [text] stages: [pre-commit, pre-push, manual] entry: mixed-line-ending args: - --fix=lf ================================================ FILE: .github/release.yml ================================================ changelog: categories: - title: '💥 Breaking changes' labels: - 'Breaking Change' - title: '🛎️ Experimental' labels: - 'Experimental' - title: '✨ New features' labels: - 'pr: new-feature' - title: '⚡ Enhancements' labels: - 'pr: enhancement' - title: '♻️ Refactor' labels: - 'pr: refactor' - title: '🐛 Bug fixes' labels: - 'pr: bugfix' - title: '🎨 Frontend updates' labels: - 'pr: frontend-update' ================================================ FILE: .github/workflows/action-container.yml ================================================ name: "Build the action container" on: release: types: - published push: branches: - main paths: - '.github/workflows/action-container.yml' - 'custom_components/**' - 'action/**' pull_request: branches: - main paths: - '.github/workflows/action-container.yml' - 'custom_components/**' - 'action/**' concurrency: group: container-build-${{ github.ref }} cancel-in-progress: true permissions: {} jobs: build: name: Build runs-on: ubuntu-latest permissions: packages: write steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Login to GitHub Container Registry uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0 if: ${{ github.event_name != 'pull_request' }} with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - name: Docker metadata id: meta uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0 with: images: | ghcr.io/${{ github.repository_owner }}/action tags: | type=ref,event=branch type=semver,pattern={{version}} type=sha - name: Build and push uses: docker/build-push-action@d08e5c354a6adb9ed34480a06d141179aa583294 # v7.0.0 with: context: . file: action/Dockerfile push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} ================================================ FILE: .github/workflows/generate-hacs-data.yml ================================================ name: Generate HACS Data on: workflow_dispatch: inputs: forceRepositoryUpdate: description: 'Force repository update' required: false default: 'False' type: choice options: - "False" - "True" category: description: 'Select a category' required: false type: choice options: - None - appdaemon - integration - plugin - python_script - template - theme schedule: - cron: "0 */2 * * *" concurrency: group: category-data permissions: {} jobs: generate-matrix: name: Generate matrix runs-on: ubuntu-latest if: github.repository == 'hacs/integration' outputs: categories: ${{ steps.set-matrix.outputs.categories }} steps: - id: set-matrix run: | if [[ "${{ github.event_name }}" == "workflow_dispatch" ]] && [[ "${{ inputs.category }}" != "None" ]] && [[ "${{ inputs.category }}" != "" ]]; then echo "categories=['${{ inputs.category }}']" >> $GITHUB_OUTPUT else echo "categories=['appdaemon','integration','plugin','python_script','template','theme']" >> $GITHUB_OUTPUT fi category-data: runs-on: ubuntu-latest needs: generate-matrix if: github.repository == 'hacs/integration' name: Generate ${{ matrix.category }} data strategy: fail-fast: false matrix: category: ${{ fromJSON( needs.generate-matrix.outputs.categories )}} steps: - name: Checkout the repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 id: python with: python-version: "3.13" cache: 'pip' cache-dependency-path: | requirements_base.txt requirements_generate_data.txt - name: Install dependencies run: | scripts/install/frontend scripts/install/pip_packages --requirement requirements_generate_data.txt - name: Generate ${{ matrix.category }} data run: python3 -m scripts.data.generate_category_data ${{ matrix.category }} env: DATA_GENERATOR_TOKEN: ${{ secrets.DATA_GENERATOR_TOKEN }} FORCE_REPOSITORY_UPDATE: ${{ inputs.forceRepositoryUpdate }} - name: Validate output with JQ run: | jq -c . outputdata/${{ matrix.category }}/data.json jq -c . outputdata/${{ matrix.category }}/repositories.json - name: Validate output with schema run: | python3 -m scripts.data.validate_category_data ${{ matrix.category }} outputdata/${{ matrix.category }}/data.json - name: Generate diff run: | diff -U 8 outputdata/diff/${{ matrix.category }}_before.json outputdata/diff/${{ matrix.category }}_after.json > outputdata/diff/${{ matrix.category }}.diff || true cat outputdata/diff/${{ matrix.category }}.diff - name: Upload diff uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 env: CATEGORY: ${{ matrix.category }} with: script: | const fs = require('fs'); const diffContents = fs.readFileSync(`outputdata/diff/${process.env.CATEGORY}.diff`); core.summary.addDetails(`${process.env.CATEGORY}.diff contents`, `\n\n\`\`\`diff\n${diffContents}\`\`\`\n\n`) core.summary.write() - name: Upload artifacts uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: ${{ matrix.category }} path: | outputdata/${{ matrix.category }} outputdata/summary.json outputdata/diff if-no-files-found: error retention-days: 7 summarize: name: Summarize runs-on: ubuntu-latest needs: category-data if: github.repository == 'hacs/integration' outputs: changedCategories: ${{ steps.combined.outputs.changedCategories }} environments: ${{ steps.combined.outputs.environments }} steps: - name: Download artifacts uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: path: outputdata - name: Generate combined summary uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 id: combined env: HACS_CHANGED_PCT_TARGET: ${{ vars.HACS_CHANGED_PCT_TARGET }} HACS_DIFF_TARGET: ${{ vars.HACS_DIFF_TARGET }} with: script: | const fs = require('fs'); const summaries = {}; const changedCategories = []; const environments = {}; const diffTarget = Number(process.env.HACS_DIFF_TARGET || 1) core.info(`[global] diffTarget: ${diffTarget}`); const subDirectories = fs.readdirSync("outputdata", { withFileTypes: true }) .filter(entry => entry.isDirectory()) .map(entry => entry.name) for (const directory of subDirectories) { let changedPctTarget = Number(process.env.HACS_CHANGED_PCT_TARGET) const parsed = JSON.parse(fs.readFileSync(`outputdata/${directory}/summary.json`)) if (!changedPctTarget) { if (!parsed.new_count || parsed.new_count <= 0) { changedPctTarget = 0; } else if (parsed.new_count > 750) { changedPctTarget = 7; } else if (parsed.new_count > 500) { changedPctTarget = 8; } else if (parsed.new_count > 250) { changedPctTarget = 9; } else if (parsed.new_count > 100) { changedPctTarget = 10; } else if (parsed.new_count > 75) { changedPctTarget = 15; } else if (parsed.new_count > 50) { changedPctTarget = 20; } else if (parsed.new_count > 25) { changedPctTarget = 25; } else if (parsed.new_count > 10) { changedPctTarget = 28; } else { changedPctTarget = 50; } } core.info(`[${directory}] changedPctTarget: ${changedPctTarget}`); if (parsed.changed >= 1 || parsed.diff >= 1) { changedCategories.push(directory) } if (parsed.changed_pct >= changedPctTarget) { core.warning(`${directory} changed ${parsed.changed_pct}%!`) environments[directory] = `publish-${directory}-verify`; } if (parsed.diff >= diffTarget) { core.warning(`${directory} changed ${parsed.diff}!`) environments[directory] = `publish-${directory}-verify`; } summaries[directory] = JSON.parse(fs.readFileSync(`outputdata/${directory}/summary.json`)); } core.summary.addCodeBlock(JSON.stringify({summaries, environments, changedCategories}, null, 4), "json") core.summary.write() core.setOutput("changedCategories", JSON.stringify(changedCategories)) core.setOutput("environments", environments) - name: Send notification if: ${{ steps.combined.outputs.environments != '{}' }} run: | curl \ -H "Content-Type: application/json" \ -d '{"username": "GitHub action", "content": "[Attention needed!](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}})"}' \ ${{ secrets.DISCORD_WEBHOOK_ACTION_FAILURE }} publish: runs-on: ubuntu-latest needs: summarize if: github.repository == 'hacs/integration' name: Publish ${{ matrix.category }} data environment: ${{ fromJSON(needs.summarize.outputs.environments)[matrix.category] }} strategy: fail-fast: false matrix: category: ${{ fromJSON(needs.summarize.outputs.changedCategories) }} steps: - name: Checkout the repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 id: python with: python-version: "3.13" cache: 'pip' cache-dependency-path: | requirements_base.txt requirements_generate_data.txt - name: Install dependencies run: | scripts/install/frontend scripts/install/pip_packages --requirement requirements_generate_data.txt - name: Download artifacts uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: ${{ matrix.category }} path: outputdata - name: Validate output with JQ run: | jq -c . outputdata/${{ matrix.category }}/data.json jq -c . outputdata/${{ matrix.category }}/repositories.json - name: Validate output with schema run: | python3 -m scripts.data.validate_category_data ${{ matrix.category }} outputdata/${{ matrix.category }}/data.json - name: Upload to R2 run: | aws s3 sync \ outputdata/${{ matrix.category }} \ s3://data-v2/${{ matrix.category }} \ --endpoint-url ${{ secrets.CF_R2_ENDPOINT_DATA }} env: AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_SECRET_ACCESS_KEY }} - name: Bust Cloudflare cache run: | curl --silent --show-error --fail -X POST \ "https://api.cloudflare.com/client/v4/zones/${{ secrets.CF_ZONE_ID }}/purge_cache" \ -H "Authorization: Bearer ${{ secrets.CF_BUST_CACHE_TOKEN }}" \ -H "Content-Type: application/json" \ --data '{"files": ["https:\/\/data-v2.hacs.xyz\/${{ matrix.category }}\/data.json", "https:\/\/data-v2.hacs.xyz\/${{ matrix.category }}\/repositories.json"]}' notify_on_failure: runs-on: ubuntu-latest name: Trigger Discord notification when jobs fail needs: ["generate-matrix", "category-data", "summarize", "publish"] steps: - name: Send notification if: ${{ always() && contains(join(needs.*.result, ','), 'failure') && github.event_name == 'schedule' }} run: | curl \ -H "Content-Type: application/json" \ -d '{"username": "GitHub action failure", "content": "[Scheduled action failed!](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}})"}' \ ${{ secrets.DISCORD_WEBHOOK_ACTION_FAILURE }} ================================================ FILE: .github/workflows/lint.yaml ================================================ name: Lint on: pull_request: branches: - main push: branches: - main concurrency: group: lint-${{ github.ref }} cancel-in-progress: true permissions: {} jobs: matrix: runs-on: ubuntu-latest name: Run ${{ matrix.check }} strategy: matrix: check: - check-ast - check-executables-have-shebangs - check-json - codespell - isort - mixed-line-ending - pyupgrade - requirements-txt-fixer - ruff-check - ruff-format steps: - name: Checkout the repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 id: python with: python-version: "3.13" cache: 'pip' cache-dependency-path: | requirements_base.txt requirements_lint.txt - name: Install dependencies run: | scripts/install/pip_packages --requirement requirements_lint.txt pre-commit install-hooks --config .github/pre-commit-config.yaml - name: Run the check (${{ matrix.check }}) run: pre-commit run --show-diff-on-failure --hook-stage manual ${{ matrix.check }} --all-files --config .github/pre-commit-config.yaml lint-json: runs-on: ubuntu-latest name: With JQ steps: - name: Checkout the repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Run validation run: jq -r -e -c . tests/fixtures/*.json ================================================ FILE: .github/workflows/lock.yml ================================================ name: "Lock closed issues and PR's" on: schedule: - cron: "0 * * * *" concurrency: group: lock-${{ github.ref }} cancel-in-progress: true permissions: {} jobs: lock: runs-on: ubuntu-latest if: github.repository == 'hacs/integration' permissions: issues: write pull-requests: write steps: - name: 🔒 Lock closed issues and PRs uses: dessant/lock-threads@7266a7ce5c1df01b1c6db85bf8cd86c737dadbe7 # v6.0.0 with: issue-inactive-days: "14" issue-lock-reason: "" pr-inactive-days: "1" pr-lock-reason: "" ================================================ FILE: .github/workflows/publish.yml ================================================ name: Publish on: release: types: - published push: branches: - main concurrency: group: publish-${{ github.ref }} cancel-in-progress: true permissions: {} jobs: release_zip_file: name: Publish HACS zip file asset runs-on: ubuntu-latest permissions: contents: write steps: - name: 📥 Checkout the repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: 🛠️ Set up Python uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.13" - name: 🔢 Get version if: ${{ github.event_name == 'release' }} id: version uses: home-assistant/actions/helpers/version@dce0e860c68256ef2902ece06afa5401eb4674e1 # master - name: 🔢 Set version number if: ${{ github.event_name == 'release' }} run: | sed -i "/MINIMUM_HA_VERSION = /c\MINIMUM_HA_VERSION = \"$(jq .homeassistant -r ${{ github.workspace }}/hacs.json)\"" ${{ github.workspace }}/custom_components/hacs/const.py python3 ${{ github.workspace }}/scripts/update/manifest.py --version ${{ steps.version.outputs.version }} - name: ⏬ Download HACS frontend run: ${{ github.workspace }}/scripts/install/frontend - name: 📤 Upload zip to action uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 if: ${{ github.event_name == 'push' }} with: name: hacs path: ${{ github.workspace }}/custom_components/hacs retention-days: 7 # Pack the HACS dir as a zip and upload to the release - name: 📦 ZIP HACS Dir if: ${{ github.event_name == 'release' }} run: | cd ${{ github.workspace }}/custom_components/hacs zip hacs.zip -r ./ - name: 📤 Upload zip to release uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2.6.1 if: ${{ github.event_name == 'release' }} with: files: ${{ github.workspace }}/custom_components/hacs/hacs.zip ================================================ FILE: .github/workflows/pull_requests_labels.yml ================================================ name: "Check Pull Request labels" on: pull_request: types: - labeled - opened - synchronize - unlabeled branches: - main permissions: {} jobs: check_labels: name: "Check Pull Request labels" runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Check the labels uses: ludeeus/action-require-labels@7ef0dba93830452589680da7cdea2e2c4c0f8dff # 1.1.0 with: labels: >- Breaking Change, Experimental, pr: new-feature, pr: enhancement, pr: refactor, pr: bugfix, pr: dependency-update, pr: action, pr: test, pr: repository ================================================ FILE: .github/workflows/pytest.yml ================================================ name: Test on: pull_request: branches: - main push: branches: - main concurrency: group: test-${{ github.ref }} cancel-in-progress: true permissions: {} jobs: legacy: name: With pytest with Home Assistant (min. supported version) runs-on: ubuntu-latest steps: - name: 📥 Checkout the repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: 🛠️ Set up Python 3.13 uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.13" cache: 'pip' cache-dependency-path: | requirements_core_min.txt requirements_base.txt requirements_test.txt - name: 📦 Install dependencies run: | scripts/install/pip_packages \ --requirement requirements_core_min.txt \ --requirement requirements_test.txt scripts/install/frontend - name: ⏲️ Set time zone uses: szenius/set-timezone@1f9716b0f7120e344f0c62bb7b1ee98819aefd42 # v2.0 with: timezoneLinux: 'Asia/Singapore' - name: 🏃 Run tests env: PYTEST: true run: scripts/test dev: name: With pytest with Home Assistant (${{ matrix.homeassistant-version }}) & Python (${{ matrix.python-version }}) runs-on: ubuntu-latest strategy: matrix: homeassistant-version: - "dev" python-version: - "3.14" steps: - name: 📥 Checkout the repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: 🛠️ Set up Python ${{ matrix.python-version }} uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: ${{ matrix.python-version }} cache: 'pip' cache-dependency-path: | requirements_core_min.txt requirements_base.txt requirements_test.txt - name: 📦 Install dependencies run: | scripts/install/pip_packages --requirement requirements_test.txt scripts/install/core_dev scripts/install/frontend - name: ⏲️ Set time zone uses: szenius/set-timezone@1f9716b0f7120e344f0c62bb7b1ee98819aefd42 # v2.0 with: timezoneLinux: 'Asia/Singapore' - name: 🏃 Run tests env: PYTEST: true run: scripts/test - name: 📤 Upload coverage to Codecov if: ${{ matrix.python-version == '3.14' }} run: | scripts/coverage curl -sfSL https://codecov.io/bash | bash - ================================================ FILE: .github/workflows/stale.yml ================================================ name: 'Close stale issues' on: workflow_dispatch: schedule: - cron: '30 10 * * *' permissions: {} jobs: issues_missing_required_information: runs-on: ubuntu-latest permissions: actions: write issues: write pull-requests: write steps: - uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.0 with: days-before-stale: -1 days-before-close: 7 only-labels: 'Missing required issue information' stale-issue-label: 'Missing required issue information' ================================================ FILE: .github/workflows/validate.yml ================================================ name: Validate on: pull_request: branches: - main push: branches: - main schedule: - cron: "0 12 * * *" concurrency: cancel-in-progress: true group: validate-${{ github.ref }} permissions: {} jobs: preflight: if: ${{ github.repository == 'hacs/integration' }} runs-on: ubuntu-latest name: Preflight steps: - name: Validation preflight env: ACTOR: ${{ github.actor }} EVENT_NAME: ${{ github.event_name }} REF_NAME: ${{ github.ref_name }} REF: ${{ github.ref }} SHA: ${{ github.sha }} run: | echo "**Start:** $(date)" >> $GITHUB_STEP_SUMMARY echo "**Actor:** $ACTOR" >> $GITHUB_STEP_SUMMARY echo "**Event:** $EVENT_NAME" >> $GITHUB_STEP_SUMMARY echo "**Ref name:** $REF_NAME" >> $GITHUB_STEP_SUMMARY echo "**Ref:** $REF" >> $GITHUB_STEP_SUMMARY echo "**SHA:** $SHA" >> $GITHUB_STEP_SUMMARY validate-hassfest: needs: - "preflight" runs-on: ubuntu-latest name: With hassfest steps: - name: Checkout the repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 # Test files conflict with running hassfest - name: Remove tests run: rm -rf tests - name: Hassfest validation uses: home-assistant/actions/hassfest@dce0e860c68256ef2902ece06afa5401eb4674e1 # master validate-hacs: needs: - "preflight" runs-on: ubuntu-latest name: With HACS Action steps: - name: HACS validation uses: hacs/action@dcb30e72781db3f207d5236b861172774ab0b485 # main with: category: integration validate-hacs-local: if: ${{ github.event_name != 'schedule' }} needs: - "preflight" runs-on: ubuntu-latest name: Check ${{matrix.entry.category}} ${{matrix.entry.repository}} with HACS Action (local) strategy: matrix: entry: - repository: "hacs/integration" category: "integration" - repository: "piitaya/lovelace-mushroom" category: "plugin" steps: - name: Checkout the repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Build Container run: | docker build . -t hacs/action:local -f action/Dockerfile - name: Run Action run: | docker run --name hacs_action_local \ --env INPUT_GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} \ --env INPUT_REPOSITORY=${{matrix.entry.repository}} \ --env INPUT_CATEGORY=${{matrix.entry.category}} \ hacs/action:local validata-hacs-data: if: ${{ github.event_name != 'schedule' }} needs: - "preflight" runs-on: ubuntu-latest name: Check ${{matrix.entry.category}} ${{matrix.entry.repository}} with HACS data generation strategy: matrix: entry: - repository: "hacs/integration" category: "integration" - repository: "piitaya/lovelace-mushroom" category: "plugin" steps: - name: Checkout the repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Python uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 with: python-version: "3.13" cache: 'pip' cache-dependency-path: | requirements_base.txt requirements_generate_data.txt - name: Install dependencies run: | scripts/install/frontend scripts/install/pip_packages --requirement requirements_generate_data.txt - name: Generate data run: | python3 -m scripts.data.generate_category_data \ ${{ matrix.entry.category }} \ ${{ matrix.entry.repository }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Generate diff run: | diff -U 8 outputdata/diff/${{ matrix.entry.category }}_before.json outputdata/diff/${{ matrix.entry.category }}_after.json > outputdata/diff/${{ matrix.entry.category }}.diff || true cat outputdata/diff/${{ matrix.entry.category }}.diff - name: Upload diff uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 env: CATEGORY: ${{ matrix.entry.category }} with: script: | const fs = require('fs'); const diffContents = fs.readFileSync(`outputdata/diff/${process.env.CATEGORY}.diff`); core.summary.addDetails(`${process.env.CATEGORY}.diff contents`, `\n\n\`\`\`diff\n${diffContents}\`\`\`\n\n`) core.summary.write() - name: Validate output with JQ run: | jq -c . outputdata/${{ matrix.entry.category }}/data.json jq -c . outputdata/${{ matrix.entry.category }}/repositories.json - name: Validate output with schema run: | python3 -m scripts.data.validate_category_data ${{ matrix.entry.category }} outputdata/${{ matrix.entry.category }}/data.json - name: Upload artifact uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 with: name: "${{ matrix.entry.category }}_${{ strategy.job-index }}" path: | outputdata/summary.json outputdata/${{ matrix.entry.category }} outputdata/diff if-no-files-found: error retention-days: 3 notify_on_failure: runs-on: ubuntu-latest name: Trigger Discord notification when jobs fail needs: ["preflight","validate-hassfest", "validate-hacs"] steps: - name: Send notification if: ${{ always() && contains(join(needs.*.result, ','), 'failure') && github.event_name == 'schedule' }} run: | curl \ -H "Content-Type: application/json" \ -d '{"username": "GitHub action failure", "content": "[Scheduled action failed!](https://github.com/${{github.repository}}/actions/runs/${{github.run_id}})"}' \ ${{ secrets.DISCORD_WEBHOOK_ACTION_FAILURE }} ================================================ FILE: .gitignore ================================================ # artifacts __pycache__ .pytest* *.egg-info */build/* */dist/* # misc .claude .coverage .python-version .venv .vscode coverage.xml htmlcov outputdata settings.json venv # Frontend are downloaded on release custom_components/hacs/hacs_frontend # Translation files custom_components/hacs/translations !custom_components/hacs/translations/en.json # Home Assistant configuration config ================================================ FILE: .pylintrc ================================================ [MESSAGES CONTROL] # pylint issue with Python 3.9 https://github.com/PyCQA/pylint/issues/3882 disable=unsubscriptable-object ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2019 - 2023 Joakim Sørensen (@ludeeus) 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. ================================================ FILE: README.md ================================================ # HACS (Home Assistant Community Store) _Manage (Install, track, upgrade) and discover custom elements for Home Assistant directly from the UI._ ## What? HACS is an integration that gives the user a powerful UI to handle downloads of custom needs. **Highlights of what HACS can do:** - Help you discover new custom elements. - Help you download new custom elements. - Help you keep track of your custom elements. - Manage(download/update/remove) - Shortcuts to repositories/issue tracker ## Useful links - [General documentation](https://hacs.xyz/) - [Configuration](https://hacs.xyz/docs/use/configuration/basic) - [FAQ](https://hacs.xyz/docs/faq) - [GitHub](https://github.com/hacs) - [Discord](https://discord.gg/apgchf8) - [Become a GitHub sponsor? ❤️](https://github.com/sponsors/ludeeus) - [BuyMe~~Coffee~~Beer? 🍺🙈](https://buymeacoffee.com/ludeeus) ## Issues ~~If~~ When you experience issues/bugs with this the best way to report them is to open an issue in **this** repo. [Issue link](https://hacs.xyz/docs/help/issues) ================================================ FILE: action/Dockerfile ================================================ FROM python:3.13-alpine WORKDIR /hacs COPY . /hacs ENV \ UV_SYSTEM_PYTHON=true \ UV_EXTRA_INDEX_URL="https://wheels.home-assistant.io/musllinux-index/" RUN \ apk add --no-cache --virtual .build-deps \ bash \ \ && bash /hacs/scripts/install/pip_packages \ uv==0.9.6 \ \ && bash /hacs/scripts/install/uv_packages \ -r requirements_action.txt \ \ && bash /hacs/scripts/install/frontend \ \ && apk del --no-cache .build-deps > /dev/null 2>&1 \ \ && rm -rf /var/cache/apk/* \ \ && find /usr/local \( -type d -a -name test -o -name tests -o -name '__pycache__' \) -o \( -type f -a -name '*.pyc' -o -name '*.pyo' \) -exec rm -rf '{}' \; \ \ && mv /hacs/action/action.py /hacs/action.py \ \ && rm -rf /hacs/scripts /hacs/action \ \ && rm /hacs/requirements_action.txt /hacs/constraints.txt ENTRYPOINT ["python3", "/hacs/action.py"] ================================================ FILE: action/action.py ================================================ """Validate a GitHub repository to be used with HACS.""" from __future__ import annotations import asyncio import json import logging import os from aiogithubapi import GitHub, GitHubAPI import aiohttp from homeassistant.core import HomeAssistant from custom_components.hacs.base import HacsBase from custom_components.hacs.const import HACS_ACTION_GITHUB_API_HEADERS from custom_components.hacs.enums import HacsGitHubRepo from custom_components.hacs.exceptions import HacsException from custom_components.hacs.utils.decode import decode_content from custom_components.hacs.utils.logger import LOGGER from custom_components.hacs.validate.manager import ValidationManager TOKEN = os.getenv("INPUT_GITHUB_TOKEN") GITHUB_WORKSPACE = os.getenv("GITHUB_WORKSPACE") GITHUB_ACTOR = os.getenv("GITHUB_ACTOR") GITHUB_EVENT_PATH = os.getenv("GITHUB_EVENT_PATH") GITHUB_REPOSITORY = os.getenv("GITHUB_REPOSITORY") CHANGED_FILES = os.getenv("CHANGED_FILES", "") REPOSITORY = os.getenv("REPOSITORY", os.getenv("INPUT_REPOSITORY")) CATEGORY = os.getenv("CATEGORY", os.getenv("INPUT_CATEGORY", "")) CATEGORIES = [ "appdaemon", "integration", "plugin", "python_script", "template", "theme", ] logging.basicConfig( format="::%(levelname)s:: %(message)s", level=logging.DEBUG, ) def error(error: str): LOGGER.error(error) exit(1) def output_in_group(group: str, content: str): print(f"::group::{group}") # noqa: T201 print(content) # noqa: T201 print("::endgroup::") # noqa: T201 def get_event_data(): if GITHUB_EVENT_PATH is None or not os.path.exists(GITHUB_EVENT_PATH): return {} with open(GITHUB_EVENT_PATH) as ev: return json.loads(ev.read()) async def choose_repository(githubapi: GitHubAPI, category: str): if category is None: return None response = await githubapi.repos.contents.get(HacsGitHubRepo.DEFAULT, category) current = json.loads(decode_content(response.data.content)) with open(f"{GITHUB_WORKSPACE}/{category}") as cat_file: # noqa: ASYNC230 new = json.loads(cat_file.read()) for repo in current: if repo in new: new.remove(repo) if len(new) != 1: error(f"{new} is not a single repository") return new[0] def choose_category(): for name in CHANGED_FILES.split(" "): if name in CATEGORIES: return name async def preflight(): """Preflight checks.""" event_data = get_event_data() ref: str | None = None hacs = HacsBase() hacs.hass = HomeAssistant("") hacs.system.action = True hacs.configuration.token = TOKEN hacs.core.config_path = None async with aiohttp.ClientSession() as session: hacs.session = session hacs.validation = ValidationManager(hacs=hacs, hass=hacs.hass) hacs.githubapi = GitHubAPI( token=hacs.configuration.token, session=session, client_name="HACS/Action", ) if REPOSITORY and CATEGORY: repository = REPOSITORY category = CATEGORY elif GITHUB_REPOSITORY == HacsGitHubRepo.DEFAULT: category = choose_category() repository = await choose_repository(hacs.githubapi, category) LOGGER.info(f"Actor: {GITHUB_ACTOR}") else: category = CATEGORY.lower() if event_data.get("pull_request") is not None: head = event_data["pull_request"]["head"] ref = head["ref"] repository = head["repo"]["full_name"] else: repository = GITHUB_REPOSITORY if event_data.get("ref") is not None: # For push events ref = event_data["ref"] # For tag events if ref.startswith("refs/tags/"): ref = ref.split("/")[-1] if TOKEN is None: error("No GitHub token found, use env GITHUB_TOKEN to set this.") if repository is None: error("No repository found, use env REPOSITORY to set this.") if category is None: error("No category found, use env CATEGORY to set this.") if category not in CATEGORIES: error(f"Category {category} is not valid.") if (repository_ref := os.getenv("REPOSITORY_REF")) is not None: ref = repository_ref if ref is None and GITHUB_REPOSITORY != HacsGitHubRepo.DEFAULT: repo = await hacs.githubapi.repos.get(repository) ref = repo.data.default_branch LOGGER.info(f"Category: {category}") LOGGER.info(f"Repository: {repository}{f'@{ref}' if ref else ''}") await validate_repository(hacs, repository, category, ref) async def validate_repository(hacs: HacsBase, repository: str, category: str, ref=None): """Validate.""" # Legacy GitHub client hacs.github = GitHub( hacs.configuration.token, hacs.session, headers=HACS_ACTION_GITHUB_API_HEADERS, ) try: await hacs.async_register_repository( repository_full_name=repository, category=category, ref=ref, ) except HacsException as exception: LOGGER.error(exception) if (repo := hacs.repositories.get_by_full_name(repository)) is None: error(f"Repository {repository} not loaded properly in HACS.") output_in_group( "data", json.dumps( { "data": repo.data.to_json(), "manifest": repo.repository_manifest.to_dict(), "release": ( { "tag": matching_release.tag_name, "assets": [asset.name for asset in matching_release.assets], } if repo.releases.objects and len(repo.releases.objects) > 0 and ( matching_release := next( ( release for release in repo.releases.objects if release.tag_name == repo.data.last_version ), repo.releases.objects[0], ) ) else None ), "category": category, "ref": ref, }, indent=4, ), ) if __name__ == "__main__": asyncio.run(preflight()) ================================================ FILE: constraints.txt ================================================ ================================================ FILE: custom_components/hacs/__init__.py ================================================ """HACS gives you a powerful UI to handle downloads of all your custom needs. For more details about this integration, please refer to the documentation at https://hacs.xyz/ """ from __future__ import annotations from aiogithubapi import AIOGitHubAPIException, GitHub, GitHubAPI from aiogithubapi.const import ACCEPT_HEADERS from awesomeversion import AwesomeVersion from homeassistant.components.frontend import async_remove_panel from homeassistant.components.lovelace.system_health import system_health_info from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry from homeassistant.const import Platform, __version__ as HAVERSION from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.entity_registry import async_get as async_get_entity_registry from homeassistant.helpers.event import async_call_later from homeassistant.helpers.start import async_at_start from homeassistant.loader import async_get_integration from .base import HacsBase from .const import DOMAIN, HACS_SYSTEM_ID, MINIMUM_HA_VERSION from .data_client import HacsDataClient from .enums import HacsDisabledReason, HacsStage, LovelaceMode from .frontend import async_register_frontend from .utils.data import HacsData from .utils.queue_manager import QueueManager from .utils.version import version_left_higher_or_equal_then_right from .websocket import async_register_websocket_commands PLATFORMS = [Platform.SWITCH, Platform.UPDATE] async def _async_initialize_integration( hass: HomeAssistant, config_entry: ConfigEntry, ) -> bool: """Initialize the integration""" hass.data[DOMAIN] = hacs = HacsBase() hacs.enable_hacs() if config_entry.source == SOURCE_IMPORT: # Import is not supported hass.async_create_task(hass.config_entries.async_remove(config_entry.entry_id)) return False hacs.configuration.update_from_dict( { "config_entry": config_entry, **config_entry.data, **config_entry.options, }, ) integration = await async_get_integration(hass, DOMAIN) hacs.set_stage(None) hacs.log.info("Starting HACS[%s]", integration.version) clientsession = async_get_clientsession(hass) hacs.integration = integration hacs.version = integration.version hacs.configuration.dev = integration.version == "0.0.0" hacs.hass = hass hacs.queue = QueueManager(hass=hass) hacs.data = HacsData(hacs=hacs) hacs.data_client = HacsDataClient( session=clientsession, client_name=f"HACS/{integration.version}", ) hacs.system.running = True hacs.session = clientsession hacs.core.lovelace_mode = LovelaceMode.YAML try: lovelace_info = await system_health_info(hacs.hass) hacs.core.lovelace_mode = LovelaceMode(lovelace_info.get("mode", "yaml")) except BaseException: # lgtm [py/catch-base-exception] pylint: disable=broad-except # If this happens, the users YAML is not valid, we assume YAML mode pass hacs.core.config_path = hacs.hass.config.path() if hacs.core.ha_version is None: hacs.core.ha_version = AwesomeVersion(HAVERSION) ## Legacy GitHub client hacs.github = GitHub( hacs.configuration.token, clientsession, headers={ "User-Agent": f"HACS/{hacs.version}", "Accept": ACCEPT_HEADERS["preview"], }, ) ## New GitHub client hacs.githubapi = GitHubAPI( token=hacs.configuration.token, session=clientsession, **{"client_name": f"HACS/{hacs.version}"}, ) async def async_startup(): """HACS startup tasks.""" hacs.enable_hacs() try: import custom_components.custom_updater except ImportError: pass else: hacs.log.critical( "HACS cannot be used with custom_updater. " "To use HACS you need to remove custom_updater from `custom_components`", ) hacs.disable_hacs(HacsDisabledReason.CONSTRAINS) return False if not version_left_higher_or_equal_then_right( hacs.core.ha_version.string, MINIMUM_HA_VERSION, ): hacs.log.critical( "You need HA version %s or newer to use this integration.", MINIMUM_HA_VERSION, ) hacs.disable_hacs(HacsDisabledReason.CONSTRAINS) return False if not await hacs.data.restore(): hacs.disable_hacs(HacsDisabledReason.RESTORE) return False hacs.set_active_categories() async_register_websocket_commands(hass) await async_register_frontend(hass, hacs) await hass.config_entries.async_forward_entry_setups(config_entry, PLATFORMS) hacs.set_stage(HacsStage.SETUP) if hacs.system.disabled: return False hacs.set_stage(HacsStage.WAITING) hacs.log.info("Setup complete, waiting for Home Assistant before startup tasks starts") # Schedule startup tasks async_at_start(hass=hass, at_start_cb=hacs.startup_tasks) return not hacs.system.disabled async def async_try_startup(_=None): """Startup wrapper for yaml config.""" try: startup_result = await async_startup() except AIOGitHubAPIException: startup_result = False if not startup_result: if hacs.system.disabled_reason != HacsDisabledReason.INVALID_TOKEN: hacs.log.info("Could not setup HACS, trying again in 15 min") async_call_later(hass, 900, async_try_startup) return hacs.enable_hacs() await async_try_startup() # Remove old (v0-v1) sensor if it exists, can be removed in v3 er = async_get_entity_registry(hass) if old_sensor := er.async_get_entity_id("sensor", DOMAIN, HACS_SYSTEM_ID): er.async_remove(old_sensor) # Mischief managed! return True async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: """Set up this integration using UI.""" config_entry.async_on_unload(config_entry.add_update_listener(async_reload_entry)) setup_result = await _async_initialize_integration(hass=hass, config_entry=config_entry) hacs: HacsBase = hass.data[DOMAIN] return setup_result and not hacs.system.disabled async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: """Handle removal of an entry.""" hacs: HacsBase = hass.data[DOMAIN] if hacs.queue.has_pending_tasks: hacs.log.warning("Pending tasks, can not unload, try again later.") return False # Clear out pending queue hacs.queue.clear() for task in hacs.recurring_tasks: # Cancel all pending tasks task() # Store data await hacs.data.async_write(force=True) try: if hass.data.get("frontend_panels", {}).get("hacs"): hacs.log.info("Removing sidepanel") async_remove_panel(hass, "hacs") except AttributeError: pass unload_ok = await hass.config_entries.async_unload_platforms(config_entry, PLATFORMS) hacs.set_stage(None) hacs.disable_hacs(HacsDisabledReason.REMOVED) hass.data.pop(DOMAIN, None) return unload_ok async def async_reload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> None: """Reload the HACS config entry.""" if not await async_unload_entry(hass, config_entry): return await async_setup_entry(hass, config_entry) ================================================ FILE: custom_components/hacs/base.py ================================================ """Base HACS class.""" from __future__ import annotations import asyncio from collections.abc import Awaitable, Callable from dataclasses import asdict, dataclass, field from datetime import timedelta import gzip import math import os import pathlib import shutil from typing import TYPE_CHECKING, Any from aiogithubapi import ( AIOGitHubAPIException, GitHub, GitHubAPI, GitHubAuthenticationException, GitHubException, GitHubNotModifiedException, GitHubRatelimitException, ) from aiogithubapi.objects.repository import AIOGitHubAPIRepository from aiohttp.client import ClientSession, ClientTimeout from awesomeversion import AwesomeVersion from homeassistant.components.persistent_notification import ( async_create as async_create_persistent_notification, ) from homeassistant.config_entries import ConfigEntry from homeassistant.const import EVENT_HOMEASSISTANT_FINAL_WRITE, Platform from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_send from homeassistant.helpers.event import async_track_time_interval from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from homeassistant.loader import Integration from homeassistant.util import dt from .const import DOMAIN, TV, URL_BASE from .coordinator import HacsUpdateCoordinator from .data_client import HacsDataClient from .enums import ( HacsCategory, HacsDisabledReason, HacsDispatchEvent, HacsGitHubRepo, HacsStage, LovelaceMode, ) from .exceptions import ( AddonRepositoryException, HacsException, HacsExecutionStillInProgress, HacsExpectedException, HacsNotModifiedException, HacsRepositoryArchivedException, HacsRepositoryExistException, HomeAssistantCoreRepositoryException, ) from .repositories import REPOSITORY_CLASSES from .repositories.base import HACS_MANIFEST_KEYS_TO_EXPORT, REPOSITORY_KEYS_TO_EXPORT from .utils.file_system import async_exists from .utils.json import json_loads from .utils.logger import LOGGER from .utils.queue_manager import QueueManager from .utils.store import async_load_from_store, async_save_to_store from .utils.workarounds import async_register_static_path if TYPE_CHECKING: from .repositories.base import HacsRepository from .utils.data import HacsData from .validate.manager import ValidationManager @dataclass class RemovedRepository: """Removed repository.""" repository: str | None = None reason: str | None = None link: str | None = None removal_type: str = None # archived, not_compliant, critical, dev, broken acknowledged: bool = False def update_data(self, data: dict): """Update data of the repository.""" for key in data: if data[key] is None: continue if key in ( "reason", "link", "removal_type", "acknowledged", ): self.__setattr__(key, data[key]) def to_json(self): """Return a JSON representation of the data.""" return { "repository": self.repository, "reason": self.reason, "link": self.link, "removal_type": self.removal_type, "acknowledged": self.acknowledged, } @dataclass class HacsConfiguration: """HacsConfiguration class.""" appdaemon_path: str = "appdaemon/apps/" appdaemon: bool = False config: dict[str, Any] = field(default_factory=dict) config_entry: ConfigEntry | None = None country: str = "ALL" debug: bool = False dev: bool = False frontend_repo_url: str = "" frontend_repo: str = "" plugin_path: str = "www/community/" python_script_path: str = "python_scripts/" python_script: bool = False release_limit: int = 5 sidepanel_icon: str = "hacs:hacs" sidepanel_title: str = "HACS" theme_path: str = "themes/" theme: bool = False token: str = None def to_json(self) -> str: """Return a json string.""" return asdict(self) def update_from_dict(self, data: dict) -> None: """Set attributes from dicts.""" if not isinstance(data, dict): raise HacsException("Configuration is not valid.") for key in data: if key in {"experimental", "netdaemon", "release_limit", "debug"}: continue self.__setattr__(key, data[key]) @dataclass class HacsCore: """HACS Core info.""" config_path: pathlib.Path | None = None ha_version: AwesomeVersion | None = None lovelace_mode = LovelaceMode("yaml") @dataclass class HacsCommon: """Common for HACS.""" categories: set[str] = field(default_factory=set) renamed_repositories: dict[str, str] = field(default_factory=dict) archived_repositories: set[str] = field(default_factory=set) ignored_repositories: set[str] = field(default_factory=set) skip: set[str] = field(default_factory=set) @dataclass class HacsStatus: """HacsStatus.""" startup: bool = True new: bool = False active_frontend_endpoint_plugin: bool = False active_frontend_endpoint_theme: bool = False inital_fetch_done: bool = False @dataclass class HacsSystem: """HACS System info.""" disabled_reason: HacsDisabledReason | None = None running: bool = False stage = HacsStage.SETUP action: bool = False generator: bool = False @property def disabled(self) -> bool: """Return if HACS is disabled.""" return self.disabled_reason is not None @dataclass class HacsRepositories: """HACS Repositories.""" _default_repositories: set[str] = field(default_factory=set) _repositories: set[HacsRepository] = field(default_factory=set) _repositories_by_full_name: dict[str, HacsRepository] = field(default_factory=dict) _repositories_by_id: dict[str, HacsRepository] = field(default_factory=dict) _removed_repositories_by_full_name: dict[str, RemovedRepository] = field(default_factory=dict) @property def list_all(self) -> list[HacsRepository]: """Return a list of repositories.""" return list(self._repositories) @property def list_removed(self) -> list[RemovedRepository]: """Return a list of removed repositories.""" return list(self._removed_repositories_by_full_name.values()) @property def list_downloaded(self) -> list[HacsRepository]: """Return a list of downloaded repositories.""" return [repo for repo in self._repositories if repo.data.installed] def category_downloaded(self, category: HacsCategory) -> bool: """Check if a given category has been downloaded.""" for repository in self.list_downloaded: if repository.data.category == category: return True return False def register(self, repository: HacsRepository, default: bool = False) -> None: """Register a repository.""" repo_id = str(repository.data.id) if repo_id == "0": return if registered_repo := self._repositories_by_id.get(repo_id): if registered_repo.data.full_name == repository.data.full_name: return self.unregister(registered_repo) registered_repo.data.full_name = repository.data.full_name registered_repo.data.new = False repository = registered_repo if repository not in self._repositories: self._repositories.add(repository) self._repositories_by_id[repo_id] = repository self._repositories_by_full_name[repository.data.full_name_lower] = repository if default: self.mark_default(repository) def unregister(self, repository: HacsRepository) -> None: """Unregister a repository.""" repo_id = str(repository.data.id) if repo_id == "0": return if not self.is_registered(repository_id=repo_id): return if self.is_default(repo_id): self._default_repositories.remove(repo_id) if repository in self._repositories: self._repositories.remove(repository) self._repositories_by_id.pop(repo_id, None) self._repositories_by_full_name.pop(repository.data.full_name_lower, None) def mark_default(self, repository: HacsRepository) -> None: """Mark a repository as default.""" repo_id = str(repository.data.id) if repo_id == "0": return if not self.is_registered(repository_id=repo_id): return self._default_repositories.add(repo_id) def set_repository_id(self, repository: HacsRepository, repo_id: str): """Update a repository id.""" existing_repo_id = str(repository.data.id) if existing_repo_id == repo_id: return if existing_repo_id != "0": raise ValueError( f"The repo id for {repository.data.full_name_lower} " f"is already set to {existing_repo_id}" ) repository.data.id = repo_id self.register(repository) def is_default(self, repository_id: str | None = None) -> bool: """Check if a repository is default.""" if not repository_id: return False return repository_id in self._default_repositories def is_registered( self, repository_id: str | None = None, repository_full_name: str | None = None, ) -> bool: """Check if a repository is registered.""" if repository_id is not None: return repository_id in self._repositories_by_id if repository_full_name is not None: return repository_full_name in self._repositories_by_full_name return False def is_downloaded( self, repository_id: str | None = None, repository_full_name: str | None = None, ) -> bool: """Check if a repository is registered.""" if repository_id is not None: repo = self.get_by_id(repository_id) if repository_full_name is not None: repo = self.get_by_full_name(repository_full_name) if repo is None: return False return repo.data.installed def get_by_id(self, repository_id: str | None) -> HacsRepository | None: """Get repository by id.""" if not repository_id: return None return self._repositories_by_id.get(str(repository_id)) def get_by_full_name(self, repository_full_name: str | None) -> HacsRepository | None: """Get repository by full name.""" if not repository_full_name: return None return self._repositories_by_full_name.get(repository_full_name.lower()) def is_removed(self, repository_full_name: str) -> bool: """Check if a repository is removed.""" return repository_full_name in self._removed_repositories_by_full_name def removed_repository(self, repository_full_name: str) -> RemovedRepository: """Get repository by full name.""" if removed := self._removed_repositories_by_full_name.get(repository_full_name): return removed removed = RemovedRepository(repository=repository_full_name) self._removed_repositories_by_full_name[repository_full_name] = removed return removed class HacsBase: """Base HACS class.""" data: HacsData | None = None data_client: HacsDataClient | None = None frontend_version: str | None = None github: GitHub | None = None githubapi: GitHubAPI | None = None hass: HomeAssistant | None = None integration: Integration | None = None queue: QueueManager | None = None repository: AIOGitHubAPIRepository | None = None session: ClientSession | None = None stage: HacsStage | None = None validation: ValidationManager | None = None version: AwesomeVersion | None = None def __init__(self) -> None: """Initialize.""" self.common = HacsCommon() self.configuration = HacsConfiguration() self.coordinators: dict[HacsCategory, HacsUpdateCoordinator] = {} self.core = HacsCore() self.log = LOGGER self.recurring_tasks: list[Callable[[], None]] = [] self.repositories = HacsRepositories() self.status = HacsStatus() self.system = HacsSystem() @property def integration_dir(self) -> pathlib.Path: """Return the HACS integration dir.""" return self.integration.file_path def set_stage(self, stage: HacsStage | None) -> None: """Set HACS stage.""" if stage and self.stage == stage: return self.stage = stage if stage is not None: self.log.info("Stage changed: %s", self.stage) self.async_dispatch(HacsDispatchEvent.STAGE, {"stage": self.stage}) def disable_hacs(self, reason: HacsDisabledReason) -> None: """Disable HACS.""" if self.system.disabled_reason == reason: return self.system.disabled_reason = reason if reason != HacsDisabledReason.REMOVED: self.log.error("HACS is disabled - %s", reason) if reason == HacsDisabledReason.INVALID_TOKEN: self.hass.add_job(self.configuration.config_entry.async_start_reauth, self.hass) def enable_hacs(self) -> None: """Enable HACS.""" if self.system.disabled_reason is not None: self.system.disabled_reason = None self.log.info("HACS is enabled") def enable_hacs_category(self, category: HacsCategory) -> None: """Enable HACS category.""" if category not in self.common.categories: self.log.info("Enable category: %s", category) self.common.categories.add(category) self.coordinators[category] = HacsUpdateCoordinator() def disable_hacs_category(self, category: HacsCategory) -> None: """Disable HACS category.""" if category in self.common.categories: self.log.info("Disabling category: %s", category) self.common.categories.pop(category) self.coordinators.pop(category) async def async_save_file(self, file_path: str, content: Any) -> bool: """Save a file.""" def _write_file(): with open( file_path, mode="w" if isinstance(content, str) else "wb", encoding="utf-8" if isinstance(content, str) else None, errors="ignore" if isinstance(content, str) else None, ) as file_handler: file_handler.write(content) # Create gz for .js files if os.path.isfile(file_path): if file_path.endswith(".js"): with open(file_path, "rb") as f_in: with gzip.open(file_path + ".gz", "wb") as f_out: shutil.copyfileobj(f_in, f_out) # LEGACY! Remove with 2.0 if "themes" in file_path and file_path.endswith(".yaml"): filename = file_path.split("/")[-1] base = file_path.split("/themes/")[0] combined = f"{base}/themes/{filename}" if os.path.exists(combined): self.log.info("Removing old theme file %s", combined) os.remove(combined) try: await self.hass.async_add_executor_job(_write_file) except ( # lgtm [py/catch-base-exception] pylint: disable=broad-except BaseException ) as error: self.log.error("Could not write data to %s - %s", file_path, error) return False return await async_exists(self.hass, file_path) async def async_can_update(self) -> int: """Helper to calculate the number of repositories we can fetch data for.""" try: response = await self.async_github_api_method(self.githubapi.rate_limit) if ((limit := response.data.resources.core.remaining or 0) - 1000) >= 10: return math.floor((limit - 1000) / 10) reset = dt.as_local(dt.utc_from_timestamp(response.data.resources.core.reset)) self.log.info( "GitHub API ratelimited - %s remaining (%s)", response.data.resources.core.remaining, f"{reset.hour}:{reset.minute}:{reset.second}", ) self.disable_hacs(HacsDisabledReason.RATE_LIMIT) except ( # lgtm [py/catch-base-exception] pylint: disable=broad-except BaseException ) as exception: self.log.exception(exception) return 0 async def async_github_api_method( self, method: Callable[[], Awaitable[TV]], *args, raise_exception: bool = True, **kwargs, ) -> TV | None: """Call a GitHub API method""" _exception = None try: return await method(*args, **kwargs) except GitHubAuthenticationException as exception: self.disable_hacs(HacsDisabledReason.INVALID_TOKEN) _exception = exception except GitHubRatelimitException as exception: self.disable_hacs(HacsDisabledReason.RATE_LIMIT) _exception = exception except GitHubNotModifiedException as exception: raise exception except GitHubException as exception: _exception = exception except ( # lgtm [py/catch-base-exception] pylint: disable=broad-except BaseException ) as exception: self.log.exception(exception) _exception = exception if raise_exception and _exception is not None: raise HacsException(_exception) return None async def async_register_repository( self, repository_full_name: str, category: HacsCategory, *, check: bool = True, ref: str | None = None, repository_id: str | None = None, default: bool = False, ) -> None: """Register a repository.""" if repository_full_name in self.common.skip: if repository_full_name != HacsGitHubRepo.INTEGRATION: raise HacsExpectedException(f"Skipping {repository_full_name}") if repository_full_name == "home-assistant/core": raise HomeAssistantCoreRepositoryException() if repository_full_name == "home-assistant/addons" or repository_full_name.startswith( "hassio-addons/" ): raise AddonRepositoryException() if category not in REPOSITORY_CLASSES: self.log.warning( "%s is not a valid repository category, %s will not be registered.", category, repository_full_name, ) return if (renamed := self.common.renamed_repositories.get(repository_full_name)) is not None: repository_full_name = renamed repository: HacsRepository = REPOSITORY_CLASSES[category](self, repository_full_name) if check: try: await repository.async_registration(ref) if repository.validate.errors: self.common.skip.add(repository.data.full_name) if not self.status.startup: self.log.error("Validation for %s failed.", repository_full_name) if self.system.action: raise HacsException( f"::error:: Validation for {repository_full_name} failed." ) return repository.validate.errors if self.system.action: repository.logger.info("%s Validation completed", repository.string) else: repository.logger.info("%s Registration completed", repository.string) except (HacsRepositoryExistException, HacsRepositoryArchivedException) as exception: if self.system.generator: repository.logger.error( "%s Registration Failed - %s", repository.string, exception ) return except AIOGitHubAPIException as exception: self.common.skip.add(repository.data.full_name) raise HacsException( f"Validation for {repository_full_name} failed with {exception}." ) from exception if self.status.new: repository.data.new = False if repository_id is not None: repository.data.id = repository_id else: if self.hass is not None and check and repository.data.new: self.async_dispatch( HacsDispatchEvent.REPOSITORY, { "action": "registration", "repository": repository.data.full_name, "repository_id": repository.data.id, }, ) self.repositories.register(repository, default) async def startup_tasks(self, _=None) -> None: """Tasks that are started after setup.""" self.set_stage(HacsStage.STARTUP) await self.async_load_hacs_from_github() if critical := await async_load_from_store(self.hass, "critical"): for repo in critical: if not repo["acknowledged"]: self.log.critical("URGENT!: Check the HACS panel!") async_create_persistent_notification( self.hass, title="URGENT!", message="**Check the HACS panel!**" ) break self.recurring_tasks.append( async_track_time_interval( self.hass, self.async_load_hacs_from_github, timedelta(hours=48), ) ) self.recurring_tasks.append( async_track_time_interval( self.hass, self.async_update_downloaded_custom_repositories, timedelta(hours=48) ) ) self.recurring_tasks.append( async_track_time_interval( self.hass, self.async_get_all_category_repositories, timedelta(hours=6) ) ) self.recurring_tasks.append( async_track_time_interval(self.hass, self.async_check_rate_limit, timedelta(minutes=5)) ) self.recurring_tasks.append( async_track_time_interval(self.hass, self.async_process_queue, timedelta(minutes=10)) ) self.recurring_tasks.append( async_track_time_interval( self.hass, self.async_handle_critical_repositories, timedelta(hours=6) ) ) unsub = self.hass.bus.async_listen_once( EVENT_HOMEASSISTANT_FINAL_WRITE, self.data.async_force_write ) if config_entry := self.configuration.config_entry: config_entry.async_on_unload(unsub) self.log.debug("There are %s scheduled recurring tasks", len(self.recurring_tasks)) self.status.startup = False self.async_dispatch(HacsDispatchEvent.STATUS, {}) await self.async_handle_removed_repositories() await self.async_get_all_category_repositories() self.set_stage(HacsStage.RUNNING) self.async_dispatch(HacsDispatchEvent.RELOAD, {"force": True}) await self.async_handle_critical_repositories() await self.async_process_queue() self.async_dispatch(HacsDispatchEvent.STATUS, {}) async def async_download_file( self, url: str, *, headers: dict | None = None, keep_url: bool = False, nolog: bool = False, handle_rate_limit: bool = False, **_, ) -> bytes | None: """Download files, and return the content.""" if url is None: return None if not keep_url and "tags/" in url: url = url.replace("tags/", "") self.log.debug("Trying to download %s", url) attempt_count = 0 while attempt_count < 5: try: request = await self.session.get( url=url, timeout=ClientTimeout(total=60), headers=headers, ) # Make sure that we got a valid result if request.status == 200: return await request.read() # Handle rate-limits if handle_rate_limit and request.status == 429: header = int(request.headers.get("retry-after") or 10) retry_after = min(header, 60) # Limit to 60 seconds self.log.warning( "GitHub has imposed a ratelimit on the request for %s, " "retrying after %s seconds", url, retry_after, ) attempt_count += 1 await asyncio.sleep(retry_after) continue raise HacsException( f"Got status code {request.status} when trying to download {url}" ) except TimeoutError: self.log.warning( "A timeout of 60! seconds was encountered while downloading %s, " "using over 60 seconds to download a single file is not normal. " "This is not a problem with HACS but how your host communicates with GitHub. " "Retrying up to 5 times to mask/hide your host/network problems to " "stop the flow of issues opened about it. " "Tries left %s", url, (4 - attempt_count), ) attempt_count += 1 await asyncio.sleep(1) continue except ( # lgtm [py/catch-base-exception] pylint: disable=broad-except BaseException ) as exception: if not nolog: self.log.exception("Download failed - %s", exception) return None async def async_recreate_entities(self) -> None: """Recreate entities.""" platforms = [Platform.UPDATE] # Workaround for core versions without https://github.com/home-assistant/core/pull/117084 if self.core.ha_version < AwesomeVersion("2024.6.0"): unload_platforms_lock = asyncio.Lock() async with unload_platforms_lock: on_unload = self.configuration.config_entry._on_unload self.configuration.config_entry._on_unload = [] await self.hass.config_entries.async_unload_platforms( entry=self.configuration.config_entry, platforms=platforms, ) self.configuration.config_entry._on_unload = on_unload else: await self.hass.config_entries.async_unload_platforms( entry=self.configuration.config_entry, platforms=platforms, ) await self.hass.config_entries.async_forward_entry_setups( self.configuration.config_entry, platforms ) @callback def async_dispatch(self, signal: HacsDispatchEvent, data: dict | None = None) -> None: """Dispatch a signal with data.""" async_dispatcher_send(self.hass, signal, data) def set_active_categories(self) -> None: """Set the active categories.""" self.common.categories = set() for category in (HacsCategory.INTEGRATION, HacsCategory.PLUGIN, HacsCategory.TEMPLATE): self.enable_hacs_category(HacsCategory(category)) if ( HacsCategory.PYTHON_SCRIPT in self.hass.config.components or self.repositories.category_downloaded(HacsCategory.PYTHON_SCRIPT) ): self.enable_hacs_category(HacsCategory.PYTHON_SCRIPT) if self.hass.services.has_service( "frontend", "reload_themes" ) or self.repositories.category_downloaded(HacsCategory.THEME): self.enable_hacs_category(HacsCategory.THEME) if self.configuration.appdaemon: self.enable_hacs_category(HacsCategory.APPDAEMON) async def async_load_hacs_from_github(self, _=None) -> None: """Load HACS from GitHub.""" if self.status.inital_fetch_done: return try: repository = self.repositories.get_by_full_name(HacsGitHubRepo.INTEGRATION) should_recreate_entities = False if repository is None: should_recreate_entities = True await self.async_register_repository( repository_full_name=HacsGitHubRepo.INTEGRATION, category=HacsCategory.INTEGRATION, default=True, ) repository = self.repositories.get_by_full_name(HacsGitHubRepo.INTEGRATION) elif not self.status.startup: self.log.error("Scheduling update of hacs/integration") self.queue.add(repository.common_update()) if repository is None: raise HacsException("Unknown error") repository.data.installed = True repository.data.installed_version = self.integration.version.string repository.data.new = False repository.data.releases = True if should_recreate_entities: await self.async_recreate_entities() self.repository = repository.repository_object self.repositories.mark_default(repository) except HacsException as exception: if "403" in str(exception): self.log.critical( "GitHub API is ratelimited, or the token is wrong.", ) else: self.log.critical("Could not load HACS! - %s", exception) self.disable_hacs(HacsDisabledReason.LOAD_HACS) async def async_get_all_category_repositories(self, _=None) -> None: """Get all category repositories.""" if self.system.disabled: return self.log.info("Loading known repositories") await asyncio.gather( *[ self.async_get_category_repositories_experimental(category) for category in self.common.categories or [] ] ) async def async_get_category_repositories_experimental(self, category: str) -> None: """Update all category repositories.""" self.log.debug("Fetching updated content for %s", category) try: category_data = await self.data_client.get_data(category, validate=True) except HacsNotModifiedException: self.log.debug("No updates for %s", category) return except HacsException as exception: self.log.error("Could not update %s - %s", category, exception) return await self.data.register_unknown_repositories(category_data, category) for repo_id, repo_data in category_data.items(): repo_name = repo_data["full_name"] if self.common.renamed_repositories.get(repo_name): repo_name = self.common.renamed_repositories[repo_name] if self.repositories.is_removed(repo_name): continue if repo_name in self.common.archived_repositories: continue if repository := self.repositories.get_by_full_name(repo_name): self.repositories.set_repository_id(repository, repo_id) self.repositories.mark_default(repository) if repository.data.last_fetched is None or ( repository.data.last_fetched.timestamp() < repo_data["last_fetched"] ): repository.data.update_data({**dict(REPOSITORY_KEYS_TO_EXPORT), **repo_data}) if (manifest := repo_data.get("manifest")) is not None: repository.repository_manifest.update_data( {**dict(HACS_MANIFEST_KEYS_TO_EXPORT), **manifest} ) if category == "integration": self.status.inital_fetch_done = True if self.stage == HacsStage.STARTUP: for repository in self.repositories.list_all: if ( repository.data.category == category and not repository.data.installed and not self.repositories.is_default(repository.data.id) ): repository.logger.debug( "%s Unregister stale custom repository", repository.string ) self.repositories.unregister(repository) self.async_dispatch(HacsDispatchEvent.REPOSITORY, {}) self.coordinators[category].async_update_listeners() async def async_check_rate_limit(self, _=None) -> None: """Check rate limit.""" if not self.system.disabled or self.system.disabled_reason != HacsDisabledReason.RATE_LIMIT: return self.log.debug("Checking if ratelimit has lifted") can_update = await self.async_can_update() self.log.debug("Ratelimit indicate we can update %s", can_update) if can_update > 0: self.enable_hacs() await self.async_process_queue() async def async_process_queue(self, _=None) -> None: """Process the queue.""" if self.system.disabled: self.log.debug("HACS is disabled") return if not self.queue.has_pending_tasks: self.log.debug("Nothing in the queue") return if self.queue.running: self.log.debug("Queue is already running") return async def _handle_queue(): if not self.queue.has_pending_tasks: await self.data.async_write() return can_update = await self.async_can_update() self.log.debug( "Can update %s repositories, items in queue %s", can_update, self.queue.pending_tasks, ) if can_update != 0: try: await self.queue.execute(can_update) except HacsExecutionStillInProgress: return await _handle_queue() await _handle_queue() async def async_handle_removed_repositories(self, _=None) -> None: """Handle removed repositories.""" if self.system.disabled: return need_to_save = False self.log.info("Loading removed repositories") try: removed_repositories = await self.data_client.get_data("removed", validate=True) except HacsException: return for item in removed_repositories: removed = self.repositories.removed_repository(item["repository"]) removed.update_data(item) for removed in self.repositories.list_removed: if (repository := self.repositories.get_by_full_name(removed.repository)) is None: continue if repository.data.full_name in self.common.ignored_repositories: continue if repository.data.installed: if removed.removal_type != "critical": async_create_issue( hass=self.hass, domain=DOMAIN, issue_id=f"removed_{repository.data.id}", is_fixable=False, issue_domain=DOMAIN, severity=IssueSeverity.WARNING, translation_key="removed", translation_placeholders={ "name": repository.data.full_name, "reason": removed.reason, "repositry_id": repository.data.id, }, ) self.log.warning( "You have '%s' installed with HACS " "this repository has been removed from HACS, please consider removing it. " "Removal reason (%s)", repository.data.full_name, removed.reason, ) else: need_to_save = True repository.remove() if need_to_save: await self.data.async_write() async def async_update_downloaded_custom_repositories(self, _=None) -> None: """Execute the task.""" if self.system.disabled: return self.log.info("Starting recurring background task for downloaded custom repositories") repositories_to_update = 0 repositories_updated = asyncio.Event() async def update_repository(repository: HacsRepository) -> None: """Update a repository""" nonlocal repositories_to_update await repository.update_repository(ignore_issues=True) repositories_to_update -= 1 if not repositories_to_update: repositories_updated.set() for repository in self.repositories.list_downloaded: if ( repository.data.category in self.common.categories and not self.repositories.is_default(repository.data.id) ): repositories_to_update += 1 self.queue.add(update_repository(repository)) async def update_coordinators() -> None: """Update all coordinators.""" await repositories_updated.wait() for coordinator in self.coordinators.values(): coordinator.async_update_listeners() if config_entry := self.configuration.config_entry: config_entry.async_create_background_task( self.hass, update_coordinators(), "update_coordinators" ) else: self.hass.async_create_background_task(update_coordinators(), "update_coordinators") self.log.debug("Recurring background task for downloaded custom repositories done") async def async_handle_critical_repositories(self, _=None) -> None: """Handle critical repositories.""" critical_queue = QueueManager(hass=self.hass) instored = [] critical = [] was_installed = False try: critical = await self.data_client.get_data("critical", validate=True) except (GitHubNotModifiedException, HacsNotModifiedException): return except HacsException: pass if not critical: self.log.debug("No critical repositories") return stored_critical = await async_load_from_store(self.hass, "critical") for stored in stored_critical or []: instored.append(stored["repository"]) stored_critical = [] for repository in critical: removed_repo = self.repositories.removed_repository(repository["repository"]) removed_repo.removal_type = "critical" repo = self.repositories.get_by_full_name(repository["repository"]) stored = { "repository": repository["repository"], "reason": repository["reason"], "link": repository["link"], "acknowledged": True, } if repository["repository"] not in instored: if repo is not None and repo.data.installed: self.log.critical( "Removing repository %s, it is marked as critical", repository["repository"], ) was_installed = True stored["acknowledged"] = False # Remove from HACS critical_queue.add(repo.uninstall()) repo.remove() stored_critical.append(stored) removed_repo.update_data(stored) # Uninstall await critical_queue.execute() # Save to FS await async_save_to_store(self.hass, "critical", stored_critical) # Restart HASS if was_installed: self.log.critical("Restarting Home Assistant") self.hass.async_create_task(self.hass.async_stop(100)) async def async_setup_frontend_endpoint_plugin(self) -> None: """Setup the http endpoints for plugins if its not already handled.""" if self.status.active_frontend_endpoint_plugin or not await async_exists( self.hass, self.hass.config.path("www/community") ): return self.log.info("Setting up plugin endpoint") use_cache = self.core.lovelace_mode == "storage" self.log.info( " %s mode, cache for /hacsfiles/: %s", self.core.lovelace_mode, use_cache, ) await async_register_static_path( self.hass, URL_BASE, self.hass.config.path("www/community"), cache_headers=use_cache, ) self.status.active_frontend_endpoint_plugin = True ================================================ FILE: custom_components/hacs/config_flow.py ================================================ """Adds config flow for HACS.""" from __future__ import annotations import asyncio from contextlib import suppress from typing import TYPE_CHECKING from aiogithubapi import ( GitHubDeviceAPI, GitHubException, GitHubLoginDeviceModel, GitHubLoginOauthModel, ) from aiogithubapi.common.const import OAUTH_USER_LOGIN from awesomeversion import AwesomeVersion from homeassistant.config_entries import ConfigFlow, OptionsFlow from homeassistant.const import __version__ as HAVERSION from homeassistant.core import callback from homeassistant.data_entry_flow import UnknownFlow from homeassistant.helpers import aiohttp_client from homeassistant.loader import async_get_integration import voluptuous as vol from .base import HacsBase from .const import CLIENT_ID, DOMAIN, LOCALE, MINIMUM_HA_VERSION from .utils.configuration_schema import ( APPDAEMON, COUNTRY, SIDEPANEL_ICON, SIDEPANEL_TITLE, ) from .utils.logger import LOGGER if TYPE_CHECKING: from homeassistant.core import HomeAssistant class HacsFlowHandler(ConfigFlow, domain=DOMAIN): """Config flow for HACS.""" VERSION = 1 hass: HomeAssistant activation_task: asyncio.Task | None = None device: GitHubDeviceAPI | None = None _registration: GitHubLoginDeviceModel | None = None _activation: GitHubLoginOauthModel | None = None _reauth: bool = False def __init__(self) -> None: """Initialize.""" self._errors = {} self._user_input = {} async def async_step_user(self, user_input): """Handle a flow initialized by the user.""" self._errors = {} if self._async_current_entries(): return self.async_abort(reason="single_instance_allowed") if self.hass.data.get(DOMAIN): return self.async_abort(reason="single_instance_allowed") if user_input: if [x for x in user_input if x.startswith("acc_") and not user_input[x]]: self._errors["base"] = "acc" return await self._show_config_form(user_input) self._user_input = user_input return await self.async_step_device(user_input) # Initial form return await self._show_config_form(user_input) async def async_step_device(self, _user_input): """Handle device steps.""" async def _wait_for_activation() -> None: try: response = await self.device.activation(device_code=self._registration.device_code) self._activation = response.data finally: async def _progress(): with suppress(UnknownFlow): await self.hass.config_entries.flow.async_configure(flow_id=self.flow_id) if not self.device: integration = await async_get_integration(self.hass, DOMAIN) self.device = GitHubDeviceAPI( client_id=CLIENT_ID, session=aiohttp_client.async_get_clientsession(self.hass), **{"client_name": f"HACS/{integration.version}"}, ) try: response = await self.device.register() self._registration = response.data except GitHubException as exception: LOGGER.exception(exception) return self.async_abort(reason="could_not_register") if self.activation_task is None: self.activation_task = self.hass.async_create_task(_wait_for_activation()) if self.activation_task.done(): if (exception := self.activation_task.exception()) is not None: LOGGER.exception(exception) return self.async_show_progress_done(next_step_id="could_not_register") return self.async_show_progress_done(next_step_id="device_done") show_progress_kwargs = { "step_id": "device", "progress_action": "wait_for_device", "description_placeholders": { "url": OAUTH_USER_LOGIN, "code": self._registration.user_code, }, "progress_task": self.activation_task, } return self.async_show_progress(**show_progress_kwargs) async def _show_config_form(self, user_input): """Show the configuration form to edit location data.""" if not user_input: user_input = {} if AwesomeVersion(HAVERSION) < MINIMUM_HA_VERSION: return self.async_abort( reason="min_ha_version", description_placeholders={"version": MINIMUM_HA_VERSION}, ) return self.async_show_form( step_id="user", data_schema=vol.Schema( { vol.Required("acc_logs", default=user_input.get("acc_logs", False)): bool, vol.Required("acc_addons", default=user_input.get("acc_addons", False)): bool, vol.Required( "acc_untested", default=user_input.get("acc_untested", False) ): bool, vol.Required("acc_disable", default=user_input.get("acc_disable", False)): bool, } ), errors=self._errors, ) async def async_step_device_done(self, user_input: dict[str, bool] | None = None): """Handle device steps""" if self._reauth: existing_entry = self.hass.config_entries.async_get_entry(self.context["entry_id"]) self.hass.config_entries.async_update_entry( existing_entry, data={**existing_entry.data, "token": self._activation.access_token} ) await self.hass.config_entries.async_reload(existing_entry.entry_id) return self.async_abort(reason="reauth_successful") return self.async_create_entry( title="", data={ "token": self._activation.access_token, }, options={ "experimental": True, }, ) async def async_step_could_not_register(self, _user_input=None): """Handle issues that need transition await from progress step.""" return self.async_abort(reason="could_not_register") async def async_step_reauth(self, _user_input=None): """Perform reauth upon an API authentication error.""" return await self.async_step_reauth_confirm() async def async_step_reauth_confirm(self, user_input=None): """Dialog that informs the user that reauth is required.""" if user_input is None: return self.async_show_form( step_id="reauth_confirm", data_schema=vol.Schema({}), ) self._reauth = True return await self.async_step_device(None) @staticmethod @callback def async_get_options_flow(config_entry): return HacsOptionsFlowHandler(config_entry) class HacsOptionsFlowHandler(OptionsFlow): """HACS config flow options handler.""" def __init__(self, config_entry): """Initialize HACS options flow.""" if AwesomeVersion(HAVERSION) < "2024.11.99": self.config_entry = config_entry async def async_step_init(self, _user_input=None): """Manage the options.""" return await self.async_step_user() async def async_step_user(self, user_input=None): """Handle a flow initialized by the user.""" hacs: HacsBase = self.hass.data.get(DOMAIN) if user_input is not None: return self.async_create_entry(title="", data={**user_input, "experimental": True}) if hacs is None or hacs.configuration is None: return self.async_abort(reason="not_setup") if hacs.queue.has_pending_tasks: return self.async_abort(reason="pending_tasks") schema = { vol.Optional(SIDEPANEL_TITLE, default=hacs.configuration.sidepanel_title): str, vol.Optional(SIDEPANEL_ICON, default=hacs.configuration.sidepanel_icon): str, vol.Optional(COUNTRY, default=hacs.configuration.country): vol.In(LOCALE), vol.Optional(APPDAEMON, default=hacs.configuration.appdaemon): bool, } return self.async_show_form(step_id="user", data_schema=vol.Schema(schema)) ================================================ FILE: custom_components/hacs/const.py ================================================ """Constants for HACS""" from typing import TypeVar from aiogithubapi.common.const import ACCEPT_HEADERS NAME_SHORT = "HACS" DOMAIN = "hacs" CLIENT_ID = "395a8e669c5de9f7c6e8" MINIMUM_HA_VERSION = "0.0.0" URL_BASE = "/hacsfiles" TV = TypeVar("TV") PACKAGE_NAME = "custom_components.hacs" DEFAULT_CONCURRENT_TASKS = 15 DEFAULT_CONCURRENT_BACKOFF_TIME = 1 HACS_REPOSITORY_ID = "172733314" HACS_ACTION_GITHUB_API_HEADERS = { "User-Agent": "HACS/action", "Accept": ACCEPT_HEADERS["preview"], } VERSION_STORAGE = "6" STORENAME = "hacs" HACS_SYSTEM_ID = "0717a0cd-745c-48fd-9b16-c8534c9704f9-bc944b0f-fd42-4a58-a072-ade38d1444cd" LOCALE = [ "ALL", "AF", "AL", "DZ", "AS", "AD", "AO", "AI", "AQ", "AG", "AR", "AM", "AW", "AU", "AT", "AZ", "BS", "BH", "BD", "BB", "BY", "BE", "BZ", "BJ", "BM", "BT", "BO", "BQ", "BA", "BW", "BV", "BR", "IO", "BN", "BG", "BF", "BI", "KH", "CM", "CA", "CV", "KY", "CF", "TD", "CL", "CN", "CX", "CC", "CO", "KM", "CG", "CD", "CK", "CR", "HR", "CU", "CW", "CY", "CZ", "CI", "DK", "DJ", "DM", "DO", "EC", "EG", "SV", "GQ", "ER", "EE", "ET", "FK", "FO", "FJ", "FI", "FR", "GF", "PF", "TF", "GA", "GM", "GE", "DE", "GH", "GI", "GR", "GL", "GD", "GP", "GU", "GT", "GG", "GN", "GW", "GY", "HT", "HM", "VA", "HN", "HK", "HU", "IS", "IN", "ID", "IR", "IQ", "IE", "IM", "IL", "IT", "JM", "JP", "JE", "JO", "KZ", "KE", "KI", "KP", "KR", "KW", "KG", "LA", "LV", "LB", "LS", "LR", "LY", "LI", "LT", "LU", "MO", "MK", "MG", "MW", "MY", "MV", "ML", "MT", "MH", "MQ", "MR", "MU", "YT", "MX", "FM", "MD", "MC", "MN", "ME", "MS", "MA", "MZ", "MM", "NA", "NR", "NP", "NL", "NC", "NZ", "NI", "NE", "NG", "NU", "NF", "MP", "NO", "OM", "PK", "PW", "PS", "PA", "PG", "PY", "PE", "PH", "PN", "PL", "PT", "PR", "QA", "RO", "RU", "RW", "RE", "BL", "SH", "KN", "LC", "MF", "PM", "VC", "WS", "SM", "ST", "SA", "SN", "RS", "SC", "SL", "SG", "SX", "SK", "SI", "SB", "SO", "ZA", "GS", "SS", "ES", "LK", "SD", "SR", "SJ", "SZ", "SE", "CH", "SY", "TW", "TJ", "TZ", "TH", "TL", "TG", "TK", "TO", "TT", "TN", "TR", "TM", "TC", "TV", "UG", "UA", "AE", "GB", "US", "UM", "UY", "UZ", "VU", "VE", "VN", "VG", "VI", "WF", "EH", "YE", "ZM", "ZW", ] ================================================ FILE: custom_components/hacs/coordinator.py ================================================ """Coordinator to trigger entity updates.""" from __future__ import annotations from collections.abc import Callable from typing import Any from homeassistant.core import CALLBACK_TYPE, callback from homeassistant.helpers.update_coordinator import BaseDataUpdateCoordinatorProtocol class HacsUpdateCoordinator(BaseDataUpdateCoordinatorProtocol): """Dispatch updates to update entities.""" def __init__(self) -> None: """Initialize.""" self._listeners: dict[CALLBACK_TYPE, tuple[CALLBACK_TYPE, object | None]] = {} @callback def async_add_listener( self, update_callback: CALLBACK_TYPE, context: Any = None ) -> Callable[[], None]: """Listen for data updates.""" @callback def remove_listener() -> None: """Remove update listener.""" self._listeners.pop(remove_listener) self._listeners[remove_listener] = (update_callback, context) return remove_listener @callback def async_update_listeners(self) -> None: """Update all registered listeners.""" for update_callback, _ in list(self._listeners.values()): update_callback() ================================================ FILE: custom_components/hacs/data_client.py ================================================ """HACS Data client.""" from __future__ import annotations import asyncio from typing import Any from aiohttp import ClientSession, ClientTimeout import voluptuous as vol from .exceptions import HacsException, HacsNotModifiedException from .utils.logger import LOGGER from .utils.validate import ( VALIDATE_FETCHED_V2_CRITICAL_REPO_SCHEMA, VALIDATE_FETCHED_V2_REMOVED_REPO_SCHEMA, VALIDATE_FETCHED_V2_REPO_DATA, ) CRITICAL_REMOVED_VALIDATORS = { "critical": VALIDATE_FETCHED_V2_CRITICAL_REPO_SCHEMA, "removed": VALIDATE_FETCHED_V2_REMOVED_REPO_SCHEMA, } class HacsDataClient: """HACS Data client.""" def __init__(self, session: ClientSession, client_name: str) -> None: """Initialize.""" self._client_name = client_name self._etags = {} self._session = session async def _do_request( self, filename: str, section: str | None = None, ) -> dict[str, dict[str, Any]] | list[str]: """Do request.""" endpoint = "/".join([v for v in [section, filename] if v is not None]) try: response = await self._session.get( f"https://data-v2.hacs.xyz/{endpoint}", timeout=ClientTimeout(total=60), headers={ "User-Agent": self._client_name, "If-None-Match": self._etags.get(endpoint, ""), }, ) if response.status == 304: raise HacsNotModifiedException() from None response.raise_for_status() except HacsNotModifiedException: raise except TimeoutError: raise HacsException("Timeout of 60s reached") from None except Exception as exception: raise HacsException(f"Error fetching data from HACS: {exception}") from exception self._etags[endpoint] = response.headers.get("etag") return await response.json() async def get_data(self, section: str | None, *, validate: bool) -> dict[str, dict[str, Any]]: """Get data.""" data = await self._do_request(filename="data.json", section=section) if not validate: return data if section in VALIDATE_FETCHED_V2_REPO_DATA: validated = {} for key, repo_data in data.items(): try: validated[key] = VALIDATE_FETCHED_V2_REPO_DATA[section](repo_data) except vol.Invalid as exception: LOGGER.info( "Got invalid data for %s (%s)", repo_data.get("full_name", key), exception ) continue return validated if not (validator := CRITICAL_REMOVED_VALIDATORS.get(section)): raise ValueError(f"Do not know how to validate {section}") validated = [] for repo_data in data: try: validated.append(validator(repo_data)) except vol.Invalid as exception: LOGGER.info("Got invalid data for %s (%s)", section, exception) continue return validated async def get_repositories(self, section: str) -> list[str]: """Get repositories.""" return await self._do_request(filename="repositories.json", section=section) ================================================ FILE: custom_components/hacs/diagnostics.py ================================================ """Diagnostics support for HACS.""" from __future__ import annotations from typing import Any from aiogithubapi import GitHubException from homeassistant.components.diagnostics import async_redact_data from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from .base import HacsBase from .const import DOMAIN async def async_get_config_entry_diagnostics( hass: HomeAssistant, entry: ConfigEntry, ) -> dict[str, Any]: """Return diagnostics for a config entry.""" hacs: HacsBase = hass.data[DOMAIN] data = { "entry": entry.as_dict(), "hacs": { "stage": hacs.stage, "version": hacs.version, "disabled_reason": hacs.system.disabled_reason, "new": hacs.status.new, "startup": hacs.status.startup, "categories": hacs.common.categories, "renamed_repositories": hacs.common.renamed_repositories, "archived_repositories": hacs.common.archived_repositories, "ignored_repositories": hacs.common.ignored_repositories, "lovelace_mode": hacs.core.lovelace_mode, "configuration": {}, }, "custom_repositories": [ repo.data.full_name for repo in hacs.repositories.list_all if not hacs.repositories.is_default(str(repo.data.id)) ], "repositories": [], } for key in ( "appdaemon", "country", "debug", "dev", "python_script", "release_limit", "theme", ): data["hacs"]["configuration"][key] = getattr(hacs.configuration, key, None) for repository in hacs.repositories.list_downloaded: data["repositories"].append( { "data": repository.data.to_json(), "integration_manifest": repository.integration_manifest, "repository_manifest": repository.repository_manifest.to_dict(), "ref": repository.ref, "paths": { "localpath": repository.localpath.replace(hacs.core.config_path, "/config"), "local": repository.content.path.local.replace( hacs.core.config_path, "/config" ), "remote": repository.content.path.remote, }, } ) try: rate_limit_response = await hacs.githubapi.rate_limit() data["rate_limit"] = rate_limit_response.data.as_dict except GitHubException as exception: data["rate_limit"] = str(exception) return async_redact_data(data, ("token",)) ================================================ FILE: custom_components/hacs/entity.py ================================================ """HACS Base entities.""" from __future__ import annotations from typing import TYPE_CHECKING, Any from homeassistant.core import callback from homeassistant.helpers.device_registry import DeviceEntryType from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity import Entity from homeassistant.helpers.update_coordinator import BaseCoordinatorEntity from .const import DOMAIN, HACS_SYSTEM_ID, NAME_SHORT from .coordinator import HacsUpdateCoordinator from .enums import HacsDispatchEvent, HacsGitHubRepo if TYPE_CHECKING: from .base import HacsBase from .repositories.base import HacsRepository def system_info(hacs: HacsBase) -> dict: """Return system info.""" return { "identifiers": {(DOMAIN, HACS_SYSTEM_ID)}, "name": NAME_SHORT, "manufacturer": "hacs.xyz", "model": "", "sw_version": str(hacs.version), "configuration_url": "homeassistant://hacs", "entry_type": DeviceEntryType.SERVICE, } class HacsBaseEntity(Entity): """Base HACS entity.""" repository: HacsRepository | None = None _attr_should_poll = False def __init__(self, hacs: HacsBase) -> None: """Initialize.""" self.hacs = hacs class HacsDispatcherEntity(HacsBaseEntity): """Base HACS entity listening to dispatcher signals.""" async def async_added_to_hass(self) -> None: """Register for status events.""" self.async_on_remove( async_dispatcher_connect( self.hass, HacsDispatchEvent.REPOSITORY, self._update_and_write_state, ) ) @callback def _update(self) -> None: """Update the sensor.""" async def async_update(self) -> None: """Manual updates of the sensor.""" self._update() @callback def _update_and_write_state(self, _: Any) -> None: """Update the entity and write state.""" self._update() self.async_write_ha_state() class HacsSystemEntity(HacsDispatcherEntity): """Base system entity.""" _attr_icon = "hacs:hacs" _attr_unique_id = HACS_SYSTEM_ID @property def device_info(self) -> dict[str, any]: """Return device information about HACS.""" return system_info(self.hacs) class HacsRepositoryEntity(BaseCoordinatorEntity[HacsUpdateCoordinator], HacsBaseEntity): """Base repository entity.""" def __init__( self, hacs: HacsBase, repository: HacsRepository, ) -> None: """Initialize.""" BaseCoordinatorEntity.__init__(self, hacs.coordinators[repository.data.category]) HacsBaseEntity.__init__(self, hacs=hacs) self.repository = repository self._attr_unique_id = str(repository.data.id) self._repo_last_fetched = repository.data.last_fetched @property def available(self) -> bool: """Return True if entity is available.""" return self.hacs.repositories.is_downloaded(repository_id=str(self.repository.data.id)) @property def device_info(self) -> dict[str, any]: """Return device information about HACS.""" if self.repository.data.full_name == HacsGitHubRepo.INTEGRATION: return system_info(self.hacs) def _manufacturer(): if authors := self.repository.data.authors: return ", ".join(author.replace("@", "") for author in authors) return self.repository.data.full_name.split("/")[0] return { "identifiers": {(DOMAIN, str(self.repository.data.id))}, "name": self.repository.display_name, "model": self.repository.data.category, "manufacturer": _manufacturer(), "configuration_url": f"homeassistant://hacs/repository/{self.repository.data.id}", "entry_type": DeviceEntryType.SERVICE, } @callback def _handle_coordinator_update(self) -> None: """Handle updated data from the coordinator.""" if ( self._repo_last_fetched is not None and self.repository.data.last_fetched is not None and self._repo_last_fetched >= self.repository.data.last_fetched ): return self._repo_last_fetched = self.repository.data.last_fetched self.async_write_ha_state() async def async_update(self) -> None: """Update the entity. Only used by the generic entity update service. """ ================================================ FILE: custom_components/hacs/enums.py ================================================ """Helper constants.""" # pylint: disable=missing-class-docstring from enum import StrEnum class HacsGitHubRepo(StrEnum): """HacsGitHubRepo.""" DEFAULT = "hacs/default" INTEGRATION = "hacs/integration" class HacsCategory(StrEnum): APPDAEMON = "appdaemon" INTEGRATION = "integration" LOVELACE = "lovelace" PLUGIN = "plugin" # Kept for legacy purposes PYTHON_SCRIPT = "python_script" TEMPLATE = "template" THEME = "theme" REMOVED = "removed" def __str__(self): return str(self.value) class HacsDispatchEvent(StrEnum): """HacsDispatchEvent.""" CONFIG = "hacs_dispatch_config" ERROR = "hacs_dispatch_error" RELOAD = "hacs_dispatch_reload" REPOSITORY = "hacs_dispatch_repository" REPOSITORY_DOWNLOAD_PROGRESS = "hacs_dispatch_repository_download_progress" STAGE = "hacs_dispatch_stage" STARTUP = "hacs_dispatch_startup" STATUS = "hacs_dispatch_status" class RepositoryFile(StrEnum): """Repository file names.""" HACS_JSON = "hacs.json" MAINIFEST_JSON = "manifest.json" class LovelaceMode(StrEnum): """Lovelace Modes.""" STORAGE = "storage" AUTO = "auto" AUTO_GEN = "auto-gen" YAML = "yaml" class HacsStage(StrEnum): SETUP = "setup" STARTUP = "startup" WAITING = "waiting" RUNNING = "running" BACKGROUND = "background" class HacsDisabledReason(StrEnum): RATE_LIMIT = "rate_limit" REMOVED = "removed" INVALID_TOKEN = "invalid_token" CONSTRAINS = "constrains" LOAD_HACS = "load_hacs" RESTORE = "restore" ================================================ FILE: custom_components/hacs/exceptions.py ================================================ """Custom Exceptions for HACS.""" class HacsException(Exception): """Super basic.""" class HacsRepositoryArchivedException(HacsException): """For repositories that are archived.""" class HacsNotModifiedException(HacsException): """For responses that are not modified.""" class HacsExpectedException(HacsException): """For stuff that are expected.""" class HacsRepositoryExistException(HacsException): """For repositories that are already exist.""" class HacsExecutionStillInProgress(HacsException): """Exception to raise if execution is still in progress.""" class AddonRepositoryException(HacsException): """Exception to raise when user tries to add add-on repository.""" exception_message = ( "The repository does not seem to be a integration, " "but an add-on repository. HACS does not manage add-ons." ) def __init__(self) -> None: super().__init__(self.exception_message) class HomeAssistantCoreRepositoryException(HacsException): """Exception to raise when user tries to add the home-assistant/core repository.""" exception_message = ( "You can not add homeassistant/core, to use core integrations " "check the Home Assistant documentation for how to add them." ) def __init__(self) -> None: super().__init__(self.exception_message) ================================================ FILE: custom_components/hacs/frontend.py ================================================ """Starting setup task: Frontend.""" from __future__ import annotations import os from typing import TYPE_CHECKING from homeassistant.components.frontend import ( add_extra_js_url, async_register_built_in_panel, ) from .const import DOMAIN, URL_BASE from .hacs_frontend import VERSION as FE_VERSION, locate_dir from .utils.workarounds import async_register_static_path if TYPE_CHECKING: from homeassistant.core import HomeAssistant from .base import HacsBase async def async_register_frontend(hass: HomeAssistant, hacs: HacsBase) -> None: """Register the frontend.""" # Register frontend if hacs.configuration.dev and (frontend_path := os.getenv("HACS_FRONTEND_DIR")): hacs.log.warning( " Frontend development mode enabled. Do not run in production!" ) await async_register_static_path( hass, f"{URL_BASE}/frontend", f"{frontend_path}/hacs_frontend", cache_headers=False ) hacs.frontend_version = "dev" else: await async_register_static_path( hass, f"{URL_BASE}/frontend", locate_dir(), cache_headers=False ) hacs.frontend_version = FE_VERSION # Custom iconset await async_register_static_path( hass, f"{URL_BASE}/iconset.js", str(hacs.integration_dir / "iconset.js") ) add_extra_js_url(hass, f"{URL_BASE}/iconset.js") # Add to sidepanel if needed if DOMAIN not in hass.data.get("frontend_panels", {}): async_register_built_in_panel( hass, component_name="custom", sidebar_title=hacs.configuration.sidepanel_title, sidebar_icon=hacs.configuration.sidepanel_icon, frontend_url_path=DOMAIN, config={ "_panel_custom": { "name": "hacs-frontend", "embed_iframe": True, "trust_external": False, "js_url": f"/hacsfiles/frontend/entrypoint.js?hacstag={hacs.frontend_version}", } }, require_admin=True, ) # Setup plugin endpoint if needed await hacs.async_setup_frontend_endpoint_plugin() ================================================ FILE: custom_components/hacs/icons.json ================================================ { "entity": { "switch": { "pre-release": { "state": { "on": "mdi:test-tube", "off": "mdi:test-tube-off" } } } } } ================================================ FILE: custom_components/hacs/iconset.js ================================================ const hacsIcons = { hacs: { path: "m 20.064849,22.306912 c -0.0319,0.369835 -0.280561,0.707789 -0.656773,0.918212 -0.280572,0.153036 -0.605773,0.229553 -0.950094,0.229553 -0.0765,0 -0.146661,-0.0064 -0.216801,-0.01275 -0.605774,-0.05739 -1.135016,-0.344329 -1.402827,-0.7588 l 0.784304,-0.516495 c 0.0893,0.146659 0.344331,0.312448 0.707793,0.34433 0.235931,0.02551 0.471852,-0.01913 0.637643,-0.108401 0.101998,-0.05101 0.172171,-0.127529 0.17854,-0.191295 0.0065,-0.08289 -0.0255,-0.369835 -0.733293,-0.439975 -1.013854,-0.09565 -1.645127,-0.688661 -1.568606,-1.460214 0.0319,-0.382589 0.280561,-0.714165 0.663153,-0.930965 0.331571,-0.172165 0.752423,-0.25506 1.166895,-0.210424 0.599382,0.05739 1.128635,0.344329 1.402816,0.7588 l -0.784304,0.510118 c -0.0893,-0.140282 -0.344331,-0.299694 -0.707782,-0.331576 -0.235932,-0.02551 -0.471863,0.01913 -0.637654,0.10202 -0.0956,0.05739 -0.165791,0.133906 -0.17216,0.191295 -0.0255,0.293317 0.465482,0.420847 0.726913,0.439976 v 0.0064 c 1.020234,0.09565 1.638757,0.66953 1.562237,1.460213 z m -7.466854,-0.988354 c 0,-1.192401 0.962855,-2.155249 2.15525,-2.155249 0.599393,0 1.179645,0.25506 1.594117,0.707789 l -0.695033,0.624895 c -0.235931,-0.25506 -0.561133,-0.401718 -0.899084,-0.401718 -0.675903,0 -1.217906,0.542 -1.217906,1.217906 0,0.66953 0.542003,1.217908 1.217906,1.217908 0.337951,0 0.663153,-0.140283 0.899084,-0.401718 l 0.695033,0.631271 c -0.414472,0.452729 -0.988355,0.707788 -1.594117,0.707788 -1.192395,0 -2.15525,-0.969224 -2.15525,-2.148872 z M 8.6573365,23.461054 10.353474,19.14418 h 0.624893 l 1.568618,4.316874 H 11.52037 L 11.265308,22.734136 H 9.964513 l -0.274192,0.726918 z m 1.6833885,-1.68339 h 0.580263 L 10.646796,21.012487 Z M 8.1089536,19.156932 v 4.297745 H 7.1461095 v -1.645131 h -1.606867 v 1.645131 H 4.5763876 v -4.297745 h 0.9628549 v 1.696143 h 1.606867 V 19.156932 Z M 20.115859,4.2997436 C 20.090359,4.159461 19.969198,4.0574375 19.822548,4.0574375 H 14.141102 10.506516 4.8250686 c -0.14665,0 -0.2678112,0.1020202 -0.2933108,0.2423061 L 3.690064,8.8461703 c -0.00651,0.01913 -0.00651,0.03826 -0.00651,0.057391 v 1.5239797 c 0,0.165789 0.133911,0.299694 0.2996911,0.299694 H 4.5762579 20.0711 20.664112 c 0.165781,0 0.299691,-0.133905 0.299691,-0.299694 V 8.8971848 c 0,-0.01913 0,-0.03826 -0.0065,-0.05739 z M 4.5763876,17.358767 c 0,0.184917 0.1466608,0.331577 0.3315819,0.331577 h 5.5985465 3.634586 0.924594 c 0.184911,0 0.331571,-0.14666 0.331571,-0.331577 v -4.744098 c 0,-0.184918 0.146661,-0.331577 0.331582,-0.331577 h 2.894913 c 0.184921,0 0.331582,0.146659 0.331582,0.331577 v 4.744098 c 0,0.184917 0.146661,0.331577 0.331571,0.331577 h 0.446363 c 0.18491,0 0.331571,-0.14666 0.331571,-0.331577 v -5.636804 c 0,-0.184918 -0.146661,-0.331577 -0.331571,-0.331577 H 4.9079695 c -0.1849211,0 -0.3315819,0.146659 -0.3315819,0.331577 z m 1.6578879,-4.852498 h 5.6495565 c 0.15303,0 0.280561,0.12753 0.280561,0.280564 v 3.513438 c 0,0.153036 -0.127531,0.280566 -0.280561,0.280566 H 6.2342755 c -0.1530412,0 -0.2805719,-0.12753 -0.2805719,-0.280566 v -3.513438 c 0,-0.159411 0.1275307,-0.280564 0.2805719,-0.280564 z M 19.790657,3.3879075 H 4.8569594 c -0.1530412,0 -0.2805718,-0.1275296 -0.2805718,-0.2805642 V 1.3665653 C 4.5763876,1.2135296 4.7039182,1.086 4.8569594,1.086 H 19.790657 c 0.153041,0 0.280572,0.1275296 0.280572,0.2805653 v 1.740778 c 0,0.1530346 -0.127531,0.2805642 -0.280572,0.2805642 z", keywords: ["hacs", "home assistant community store"], }, }; window.customIcons = window.customIcons || {}; window.customIconsets = window.customIconsets || {}; window.customIcons["hacs"] = { getIcon: async (iconName) => ( { path: hacsIcons[iconName]?.path } ), getIconList: async () => Object.entries(hacsIcons).map(([icon, content]) => ({ name: icon, keywords: content.keywords, }) ) }; ================================================ FILE: custom_components/hacs/manifest.json ================================================ { "domain": "hacs", "name": "HACS", "after_dependencies": [ "python_script" ], "codeowners": [ "@ludeeus" ], "config_flow": true, "dependencies": [ "http", "websocket_api", "frontend", "persistent_notification", "lovelace", "repairs" ], "documentation": "https://hacs.xyz/docs/use/", "iot_class": "cloud_polling", "issue_tracker": "https://github.com/hacs/integration/issues", "requirements": [ "aiogithubapi>=22.10.1" ], "version": "0.0.0" } ================================================ FILE: custom_components/hacs/repairs.py ================================================ """Repairs platform for HACS.""" from __future__ import annotations from typing import Any from homeassistant import data_entry_flow from homeassistant.components.repairs import RepairsFlow from homeassistant.core import HomeAssistant import voluptuous as vol from custom_components.hacs.base import HacsBase from .const import DOMAIN class RestartRequiredFixFlow(RepairsFlow): """Handler for an issue fixing flow.""" def __init__(self, issue_id: str) -> None: self.issue_id = issue_id async def async_step_init( self, user_input: dict[str, str] | None = None ) -> data_entry_flow.FlowResult: """Handle the first step of a fix flow.""" return await self.async_step_confirm_restart() async def async_step_confirm_restart( self, user_input: dict[str, str] | None = None ) -> data_entry_flow.FlowResult: """Handle the confirm step of a fix flow.""" if user_input is not None: await self.hass.services.async_call("homeassistant", "restart") return self.async_create_entry(title="", data={}) hacs: HacsBase = self.hass.data[DOMAIN] integration = hacs.repositories.get_by_id(self.issue_id.split("_")[2]) return self.async_show_form( step_id="confirm_restart", data_schema=vol.Schema({}), description_placeholders={"name": integration.display_name}, ) async def async_create_fix_flow( hass: HomeAssistant, issue_id: str, data: dict[str, str | int | float | None] | None = None, *args: Any, **kwargs: Any, ) -> RepairsFlow | None: """Create flow.""" if issue_id.startswith("restart_required"): return RestartRequiredFixFlow(issue_id) return None ================================================ FILE: custom_components/hacs/repositories/__init__.py ================================================ """Initialize repositories.""" from __future__ import annotations from ..enums import HacsCategory from .appdaemon import HacsAppdaemonRepository from .base import HacsRepository from .integration import HacsIntegrationRepository from .plugin import HacsPluginRepository from .python_script import HacsPythonScriptRepository from .template import HacsTemplateRepository from .theme import HacsThemeRepository REPOSITORY_CLASSES: dict[HacsCategory, HacsRepository] = { HacsCategory.THEME: HacsThemeRepository, HacsCategory.INTEGRATION: HacsIntegrationRepository, HacsCategory.PYTHON_SCRIPT: HacsPythonScriptRepository, HacsCategory.APPDAEMON: HacsAppdaemonRepository, HacsCategory.PLUGIN: HacsPluginRepository, HacsCategory.TEMPLATE: HacsTemplateRepository, } ================================================ FILE: custom_components/hacs/repositories/appdaemon.py ================================================ """Class for appdaemon apps in HACS.""" from __future__ import annotations from typing import TYPE_CHECKING from aiogithubapi import AIOGitHubAPIException from ..enums import HacsCategory, HacsDispatchEvent from ..exceptions import HacsException from ..utils.decorator import concurrent from .base import HacsRepository if TYPE_CHECKING: from ..base import HacsBase class HacsAppdaemonRepository(HacsRepository): """Appdaemon apps in HACS.""" def __init__(self, hacs: HacsBase, full_name: str): """Initialize.""" super().__init__(hacs=hacs) self.data.full_name = full_name self.data.full_name_lower = full_name.lower() self.data.category = HacsCategory.APPDAEMON self.content.path.local = self.localpath self.content.path.remote = "apps" @property def localpath(self): """Return localpath.""" return f"{self.hacs.core.config_path}/appdaemon/apps/{self.data.name}" async def validate_repository(self): """Validate.""" await self.common_validate() # Custom step 1: Validate content. try: addir = await self.repository_object.get_contents("apps", self.ref) except AIOGitHubAPIException: raise HacsException( f"{self.string} Repository structure for {self.ref.replace('tags/', '')} is not compliant" ) from None if not isinstance(addir, list): self.validate.errors.append(f"{self.string} Repository structure not compliant") self.content.path.remote = addir[0].path self.content.objects = await self.repository_object.get_contents( self.content.path.remote, self.ref ) # Handle potential errors if self.validate.errors: for error in self.validate.errors: if not self.hacs.status.startup: self.logger.error("%s %s", self.string, error) return self.validate.success @concurrent(concurrenttasks=10, backoff_time=5) async def update_repository(self, ignore_issues=False, force=False): """Update.""" if not await self.common_update(ignore_issues, force) and not force: return # Get appdaemon objects. if self.repository_manifest: if self.repository_manifest.content_in_root: self.content.path.remote = "" if self.content.path.remote == "apps": addir = await self.repository_object.get_contents(self.content.path.remote, self.ref) self.content.path.remote = addir[0].path self.content.objects = await self.repository_object.get_contents( self.content.path.remote, self.ref ) # Set local path self.content.path.local = self.localpath # Signal frontend to refresh if self.data.installed: self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY, { "id": 1337, "action": "update", "repository": self.data.full_name, "repository_id": self.data.id, }, ) ================================================ FILE: custom_components/hacs/repositories/base.py ================================================ """Repository.""" from __future__ import annotations from asyncio import sleep from datetime import UTC, datetime import os import pathlib import shutil import tempfile from typing import TYPE_CHECKING, Any import zipfile from aiogithubapi import ( AIOGitHubAPIException, AIOGitHubAPINotModifiedException, GitHubReleaseModel, ) from aiogithubapi.objects.repository import AIOGitHubAPIRepository import attr from homeassistant.helpers import device_registry as dr, issue_registry as ir from ..const import DOMAIN from ..enums import HacsDispatchEvent, RepositoryFile from ..exceptions import ( HacsException, HacsNotModifiedException, HacsRepositoryArchivedException, HacsRepositoryExistException, ) from ..types import DownloadableContent from ..utils.backup import Backup from ..utils.decode import decode_content from ..utils.decorator import concurrent, return_none_on_exception from ..utils.file_system import async_exists, async_remove, async_remove_directory from ..utils.filters import filter_content_return_one_of_type from ..utils.github_graphql_query import GET_REPOSITORY_RELEASES from ..utils.json import json_loads from ..utils.logger import LOGGER from ..utils.path import is_safe from ..utils.queue_manager import QueueManager from ..utils.store import async_remove_store from ..utils.url import github_archive, github_release_asset from ..utils.validate import Validate from ..utils.version import ( version_left_higher_or_equal_then_right, version_left_higher_then_right, ) from ..utils.workarounds import DOMAIN_OVERRIDES if TYPE_CHECKING: from ..base import HacsBase TOPIC_FILTER = ( "add-on", "addon", "app", "appdaemon-apps", "appdaemon", "custom-card", "custom-cards", "custom-component", "custom-components", "customcomponents", "hacktoberfest", "hacs-default", "hacs-integration", "hacs-repository", "hacs", "hass", "hassio", "home-assistant-custom", "home-assistant-frontend", "home-assistant-hacs", "home-assistant-sensor", "home-assistant", "home-automation", "homeassistant-components", "homeassistant-integration", "homeassistant-sensor", "homeassistant", "homeautomation", "integration", "lovelace-ui", "lovelace", "media-player", "mediaplayer", "plugin", "python_script", "python-script", "python", "sensor", "smart-home", "smarthome", "template", "templates", "theme", "themes", ) REPOSITORY_KEYS_TO_EXPORT = ( # Keys can not be removed from this list until v3 # If keys are added, the action need to be re-run with force ("description", ""), ("downloads", 0), ("domain", None), ("etag_releases", None), ("etag_repository", None), ("full_name", ""), ("last_commit", None), ("last_updated", 0), ("last_version", None), ("manifest_name", None), ("open_issues", 0), ("prerelease", None), ("stargazers_count", 0), ("topics", []), ) HACS_MANIFEST_KEYS_TO_EXPORT = ( # Keys can not be removed from this list until v3 # If keys are added, the action need to be re-run with force ("country", []), ("name", None), ) class FileInformation: """FileInformation.""" def __init__(self, url, path, name): self.download_url = url self.path = path self.name = name @attr.s(auto_attribs=True) class RepositoryData: """RepositoryData class.""" archived: bool = False authors: list[str] = [] category: str = "" config_flow: bool = False default_branch: str = None description: str = "" domain: str = None downloads: int = 0 etag_repository: str = None etag_releases: str = None file_name: str = "" first_install: bool = False full_name: str = "" hide: bool = False has_issues: bool = True id: int = 0 installed_commit: str = None installed_version: str = None installed: bool = False last_commit: str = None last_fetched: datetime = None last_updated: str = 0 last_version: str = None manifest_name: str = None new: bool = True open_issues: int = 0 prerelease: str = None published_tags: list[str] = [] releases: bool = False selected_tag: str = None show_beta: bool = False stargazers_count: int = 0 topics: list[str] = [] @property def name(self): """Return the name.""" if self.category == "integration": return self.domain return self.full_name.split("/")[-1] def to_json(self): """Export to json.""" return attr.asdict(self, filter=lambda attr, value: attr.name != "last_fetched") @staticmethod def create_from_dict(source: dict, action: bool = False) -> RepositoryData: """Set attributes from dicts.""" data = RepositoryData() data.update_data(source, action) return data def update_data(self, data: dict, action: bool = False) -> None: """Update data of the repository.""" for key, value in data.items(): if key not in self.__dict__: continue if key == "last_fetched" and isinstance(value, float): setattr(self, key, datetime.fromtimestamp(value, UTC)) elif key == "id": setattr(self, key, str(value)) elif key == "country": if isinstance(value, str): setattr(self, key, [value]) else: setattr(self, key, value) elif key == "topics" and not action: setattr(self, key, [topic for topic in value if topic not in TOPIC_FILTER]) else: setattr(self, key, value) @attr.s(auto_attribs=True) class HacsManifest: """HacsManifest class.""" content_in_root: bool = False country: list[str] = [] filename: str = None hacs: str = None # Minimum HACS version hide_default_branch: bool = False homeassistant: str = None # Minimum Home Assistant version manifest: dict = {} name: str = None persistent_directory: str = None render_readme: bool = False zip_release: bool = False def to_dict(self): """Export to json.""" return attr.asdict(self) @staticmethod def from_dict(manifest: dict): """Set attributes from dicts.""" if manifest is None: raise HacsException("Missing manifest data") manifest_data = HacsManifest() manifest_data.manifest = { k: v for k, v in manifest.items() if k in manifest_data.__dict__ and v != manifest_data.__getattribute__(k) } for key, value in manifest_data.manifest.items(): if key == "country" and isinstance(value, str): setattr(manifest_data, key, [value]) elif key in manifest_data.__dict__: setattr(manifest_data, key, value) return manifest_data def update_data(self, data: dict) -> None: """Update the manifest data.""" for key, value in data.items(): if key not in self.__dict__: continue if key == "country": if isinstance(value, str): setattr(self, key, [value]) else: setattr(self, key, value) else: setattr(self, key, value) class RepositoryReleases: """RepositoyReleases.""" last_release = None last_release_object = None published_tags = [] objects: list[GitHubReleaseModel] = [] releases = False downloads = None class RepositoryPath: """RepositoryPath.""" local: str | None = None remote: str | None = None class RepositoryContent: """RepositoryContent.""" path: RepositoryPath | None = None files = [] objects = [] single = False class HacsRepository: """HacsRepository.""" def __init__(self, hacs: HacsBase) -> None: """Set up HacsRepository.""" self.hacs = hacs self.additional_info = "" self.data = RepositoryData() self.content = RepositoryContent() self.content.path = RepositoryPath() self.repository_object: AIOGitHubAPIRepository | None = None self.updated_info = False self.state = None self.force_branch = False self.integration_manifest = {} self.repository_manifest = HacsManifest.from_dict({}) self.validate = Validate() self.releases = RepositoryReleases() self.pending_restart = False self.tree = [] self.treefiles = [] self.ref = None self.logger = LOGGER def __str__(self) -> str: """Return a string representation of the repository.""" return self.string @property def string(self) -> str: """Return a string representation of the repository.""" return f"<{self.data.category.title()} {self.data.full_name}>" @property def display_name(self) -> str: """Return display name.""" if self.repository_manifest.name is not None: return self.repository_manifest.name if self.data.category == "integration": if self.data.manifest_name is not None: return self.data.manifest_name if "name" in self.integration_manifest: return self.integration_manifest["name"] return self.data.full_name.split("/")[-1].replace("-", " ").replace("_", " ").title() @property def ignored_by_country_configuration(self) -> bool: """Return True if hidden by country.""" if self.data.installed: return False configuration = self.hacs.configuration.country.lower() if configuration == "all": return False manifest = [entry.lower() for entry in self.repository_manifest.country or []] if not manifest: return False return configuration not in manifest @property def display_status(self) -> str: """Return display_status.""" if self.data.new: status = "new" elif self.pending_restart: status = "pending-restart" elif self.pending_update: status = "pending-upgrade" elif self.data.installed: status = "installed" else: status = "default" return status @property def display_installed_version(self) -> str: """Return display_authors""" if self.data.installed_version is not None: installed = self.data.installed_version else: if self.data.installed_commit is not None: installed = self.data.installed_commit else: installed = "" return str(installed) @property def display_available_version(self) -> str: """Return display_authors""" if self.data.show_beta and self.data.prerelease is not None: available = self.data.prerelease elif self.data.last_version is not None: available = self.data.last_version else: if self.data.last_commit is not None: available = self.data.last_commit else: available = "" return str(available) @property def display_version_or_commit(self) -> str: """Does the repositoriy use releases or commits?""" if self.data.releases: version_or_commit = "version" else: version_or_commit = "commit" return version_or_commit @property def pending_update(self) -> bool: """Return True if pending update.""" if self.data.installed: if self.data.selected_tag is not None: if self.data.selected_tag == self.data.default_branch: if self.data.installed_commit != self.data.last_commit: return True return False if self.display_version_or_commit == "version": if ( result := version_left_higher_then_right( self.display_available_version, self.display_installed_version, ) ) is not None: return result if self.display_installed_version != self.display_available_version: return True return False @property def can_download(self) -> bool: """Return True if we can download.""" if self.repository_manifest.homeassistant is not None: if self.data.releases: if not version_left_higher_or_equal_then_right( self.hacs.core.ha_version.string, self.repository_manifest.homeassistant, ): return False return True @property def localpath(self) -> str | None: """Return localpath.""" return None @property def should_try_releases(self) -> bool: """Return a boolean indicating whether to download releases or not.""" if self.repository_manifest.zip_release: if self.repository_manifest.filename.endswith(".zip"): if self.ref != self.data.default_branch: return True if self.ref == self.data.default_branch: return False if self.data.category not in ["plugin", "theme"]: return False if not self.data.releases: return False return True async def validate_repository(self) -> None: """Validate.""" @concurrent(concurrenttasks=10, backoff_time=5) async def update_repository(self, ignore_issues=False, force=False) -> None: """Update the repository""" async def common_validate(self, ignore_issues: bool = False) -> None: """Common validation steps of the repository.""" self.validate.errors.clear() # Make sure the repository exist. self.logger.debug("%s Checking repository.", self.string) await self.common_update_data(ignore_issues=ignore_issues) # Get the content of hacs.json if RepositoryFile.HACS_JSON in [x.filename for x in self.tree]: if manifest := await self.async_get_hacs_json(): self.repository_manifest = HacsManifest.from_dict(manifest) self.data.update_data( self.repository_manifest.to_dict(), action=self.hacs.system.action, ) async def common_registration(self) -> None: """Common registration steps of the repository.""" # Attach repository if self.repository_object is None: try: self.repository_object, etag = await self.async_get_legacy_repository_object( etag=None if self.data.installed else self.data.etag_repository, ) self.data.update_data( self.repository_object.attributes, action=self.hacs.system.action, ) self.data.etag_repository = etag except HacsNotModifiedException: self.logger.debug("%s Did not update, content was not modified", self.string) return if self.repository_object: self.data.last_updated = self.repository_object.attributes.get("pushed_at", 0) self.data.last_fetched = datetime.now(UTC) @concurrent(concurrenttasks=10, backoff_time=5) async def common_update(self, ignore_issues=False, force=False, skip_releases=False) -> bool: """Common information update steps of the repository.""" self.logger.debug("%s Getting repository information", self.string) # Attach repository current_etag = self.data.etag_repository try: await self.common_update_data( ignore_issues=ignore_issues, force=force, skip_releases=skip_releases, ) except HacsRepositoryExistException: self.data.full_name = self.hacs.common.renamed_repositories[self.data.full_name] await self.common_update_data(ignore_issues=ignore_issues, force=force) except HacsException: if not ignore_issues and not force: return False if not self.data.installed and (current_etag == self.data.etag_repository) and not force: self.logger.debug("%s Did not update, content was not modified", self.string) return False # Update last updated if self.repository_object: self.data.last_updated = self.repository_object.attributes.get("pushed_at", 0) # Update last available commit await self.repository_object.set_last_commit() self.data.last_commit = self.repository_object.last_commit # Get the content of hacs.json if RepositoryFile.HACS_JSON in [x.filename for x in self.tree]: if manifest := await self.async_get_hacs_json(): self.repository_manifest = HacsManifest.from_dict(manifest) self.data.update_data( self.repository_manifest.to_dict(), action=self.hacs.system.action, ) # Update "info.md" self.additional_info = await self.async_get_info_file_contents() # Set last fetch attribute self.data.last_fetched = datetime.now(UTC) return True async def download_zip_files(self, validate: Validate) -> None: """Download ZIP archive from repository release.""" try: await self.async_download_zip_file( DownloadableContent( name=self.repository_manifest.filename, url=github_release_asset( repository=self.data.full_name, version=self.ref, filename=self.repository_manifest.filename, ), ), validate, ) # lgtm [py/catch-base-exception] pylint: disable=broad-except except BaseException: validate.errors.append( f"Download of {self.repository_manifest.filename} was not completed" ) async def async_download_zip_file( self, content: DownloadableContent, validate: Validate, ) -> None: """Download ZIP archive from repository release.""" try: filecontent = await self.hacs.async_download_file(content["url"]) if filecontent is None: validate.errors.append(f"Failed to download {content['url']}") return temp_dir = await self.hacs.hass.async_add_executor_job(tempfile.mkdtemp) temp_file = f"{temp_dir}/{self.repository_manifest.filename}" result = await self.hacs.async_save_file(temp_file, filecontent) def _extract_zip_file(): with zipfile.ZipFile(temp_file, "r") as zip_file: zip_file.extractall(self.content.path.local) await self.hacs.hass.async_add_executor_job(_extract_zip_file) def cleanup_temp_dir(): """Cleanup temp_dir.""" if os.path.exists(temp_dir): self.logger.debug("%s Cleaning up %s", self.string, temp_dir) shutil.rmtree(temp_dir) if result: self.logger.info("%s Download of %s completed", self.string, content["name"]) await self.hacs.hass.async_add_executor_job(cleanup_temp_dir) return validate.errors.append(f"[{content['name']}] was not downloaded") # lgtm [py/catch-base-exception] pylint: disable=broad-except except BaseException: validate.errors.append("Download was not completed") async def download_content(self, version: string | None = None) -> None: """Download the content of a directory.""" contents: list[FileInformation] | None = None if ( not self.repository_manifest.zip_release and not self.data.file_name and self.content.path.remote is not None ): self.logger.info("%s Downloading repository archive", self.string) try: await self.download_repository_zip() return except HacsException as exception: self.logger.exception(exception) if self.repository_manifest.filename: self.logger.debug("%s %s", self.string, self.repository_manifest.filename) if self.content.path.remote == "release" and version is not None: contents = await self.release_contents(version) if not contents: contents = self.gather_files_to_download() if not contents: raise HacsException("No content to download") download_queue = QueueManager(hass=self.hacs.hass) for content in contents: if self.repository_manifest.content_in_root and self.repository_manifest.filename: if content.name != self.repository_manifest.filename: continue download_queue.add(self.dowload_repository_content(content)) await download_queue.execute() async def download_repository_zip(self): """Download the zip archive of the repository.""" ref = f"{self.ref}".replace("tags/", "") if not ref: raise HacsException("Missing required elements.") filecontent = await self.hacs.async_download_file( github_archive(repository=self.data.full_name, version=ref, variant="tags"), keep_url=True, nolog=True, ) if filecontent is None: filecontent = await self.hacs.async_download_file( github_archive(repository=self.data.full_name, version=ref, variant="heads"), keep_url=True, ) if filecontent is None: raise HacsException(f"[{self}] Failed to download zipball") temp_dir = await self.hacs.hass.async_add_executor_job(tempfile.mkdtemp) temp_file = f"{temp_dir}/{self.repository_manifest.filename}" result = await self.hacs.async_save_file(temp_file, filecontent) if not result: raise HacsException("Could not save ZIP file") def _extract_zip_file(): with zipfile.ZipFile(temp_file, "r") as zip_file: extractable = [] for path in zip_file.filelist: filename = "/".join(path.filename.split("/")[1:]) if ( filename.startswith(self.content.path.remote) and filename != self.content.path.remote ): path.filename = filename.replace(self.content.path.remote, "") if path.filename == "/": # Blank files is not valid, and will start to throw in Python 3.12 continue extractable.append(path) if len(extractable) == 0: raise HacsException("No content to extract") zip_file.extractall(self.content.path.local, extractable) await self.hacs.hass.async_add_executor_job(_extract_zip_file) def cleanup_temp_dir(): """Cleanup temp_dir.""" if os.path.exists(temp_dir): self.logger.debug("%s Cleaning up %s", self.string, temp_dir) shutil.rmtree(temp_dir) await self.hacs.hass.async_add_executor_job(cleanup_temp_dir) self.logger.info("%s Content was extracted to %s", self.string, self.content.path.local) async def async_get_hacs_json(self, ref: str = None) -> dict[str, Any] | None: """Get the content of the hacs.json file.""" try: response = await self.hacs.async_github_api_method( method=self.hacs.githubapi.repos.contents.get, raise_exception=False, repository=self.data.full_name, path=RepositoryFile.HACS_JSON, **{"params": {"ref": ref or self.version_to_download()}}, ) if response: return json_loads(decode_content(response.data.content)) # lgtm [py/catch-base-exception] pylint: disable=broad-except except BaseException: pass async def async_get_info_file_contents(self, *, version: str | None = None, **kwargs) -> str: """Get the content of the info.md file.""" def _info_file_variants() -> tuple[str, ...]: name: str = "readme" return ( f"{name.upper()}.md", f"{name}.md", f"{name}.MD", f"{name.upper()}.MD", name.upper(), name, ) info_files = [filename for filename in _info_file_variants() if filename in self.treefiles] if not info_files: return "" return await self.get_documentation(filename=info_files[0], version=version) or "" def remove(self) -> None: """Run remove tasks.""" if self.hacs.repositories.is_registered(repository_id=str(self.data.id)): self.logger.info("%s Starting removal", self.string) self.hacs.repositories.unregister(self) async def uninstall(self) -> None: """Run uninstall tasks.""" self.logger.info("%s Removing", self.string) if not await self.remove_local_directory(): raise HacsException("Could not uninstall") self.data.installed = False await self._async_post_uninstall() await async_remove_store(self.hacs.hass, f"hacs/{self.data.id}.hacs") self.data.installed_version = None self.data.installed_commit = None self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY, { "id": 1337, "action": "uninstall", "repository": self.data.full_name, "repository_id": self.data.id, }, ) await self.async_remove_entity_device() ir.async_delete_issue(self.hacs.hass, DOMAIN, f"removed_{self.data.id}") async def remove_local_directory(self) -> None: """Check the local directory.""" try: if self.data.category == "python_script": local_path = f"{self.content.path.local}/{self.data.file_name}" elif self.data.category == "template": local_path = f"{self.content.path.local}/{self.data.file_name}" elif self.data.category == "theme": path = ( f"{self.hacs.core.config_path}/" f"{self.hacs.configuration.theme_path}/" f"{self.data.name}.yaml" ) await async_remove(self.hacs.hass, path, missing_ok=True) local_path = self.content.path.local elif self.data.category == "integration": if not self.data.domain: if domain := DOMAIN_OVERRIDES.get(self.data.full_name): self.data.domain = domain self.content.path.local = self.localpath else: self.logger.error("%s Missing domain", self.string) return False local_path = self.content.path.local else: local_path = self.content.path.local if await async_exists(self.hacs.hass, local_path): if not is_safe(self.hacs, local_path): self.logger.error("%s Path %s is blocked from removal", self.string, local_path) return False self.logger.debug("%s Removing %s", self.string, local_path) if self.data.category in ["python_script", "template"]: await async_remove(self.hacs.hass, local_path) else: await async_remove_directory(self.hacs.hass, local_path) while await async_exists(self.hacs.hass, local_path): await sleep(1) else: self.logger.debug( "%s Presumed local content path %s does not exist", self.string, local_path ) except ( # lgtm [py/catch-base-exception] pylint: disable=broad-except BaseException ) as exception: self.logger.debug("%s Removing %s failed with %s", self.string, local_path, exception) return False return True async def async_pre_registration(self) -> None: """Run pre registration steps.""" @concurrent(concurrenttasks=10) async def async_registration(self, ref=None) -> None: """Run registration steps.""" await self.async_pre_registration() if ref is not None: self.data.selected_tag = ref self.ref = ref self.force_branch = True if not await self.validate_repository(): return False # Run common registration steps. await self.common_registration() # Set correct local path self.content.path.local = self.localpath # Run local post registration steps. await self.async_post_registration() async def async_post_registration(self) -> None: """Run post registration steps.""" if not self.hacs.system.action: return await self.hacs.validation.async_run_repository_checks(self) async def async_pre_install(self) -> None: """Run pre install steps.""" async def _async_pre_install(self) -> None: """Run pre install steps.""" self.logger.info("%s Running pre installation steps", self.string) await self.async_pre_install() self.logger.info("%s Pre installation steps completed", self.string) async def async_install(self, *, version: str | None = None, **_) -> None: """Run install steps.""" await self._async_pre_install() self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS, {"repository": self.data.full_name, "progress": 30}, ) self.logger.info("%s Running installation steps", self.string) await self.async_install_repository(version=version) self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS, {"repository": self.data.full_name, "progress": 90}, ) self.logger.info("%s Installation steps completed", self.string) await self._async_post_install() self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS, {"repository": self.data.full_name, "progress": False}, ) async def async_post_installation(self) -> None: """Run post install steps.""" async def async_post_uninstall(self): """Run post uninstall steps.""" async def _async_post_uninstall(self): """Run post uninstall steps.""" await self.async_post_uninstall() async def _async_post_install(self) -> None: """Run post install steps.""" self.logger.info("%s Running post installation steps", self.string) await self.async_post_installation() self.data.new = False self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY, { "id": 1337, "action": "install", "repository": self.data.full_name, "repository_id": self.data.id, }, ) self.logger.info("%s Post installation steps completed", self.string) async def async_install_repository(self, *, version: str | None = None, **_) -> None: """Common installation steps of the repository.""" persistent_directory = None force_update = version is None or ( self.data.last_version is not None and version != self.data.last_version ) await self.update_repository(force=force_update) if self.content.path.local is None: raise HacsException("repository.content.path.local is None") self.validate.errors.clear() version_to_install = version or self.version_to_download() if version_to_install == self.data.default_branch: self.ref = version_to_install else: self.ref = f"tags/{version_to_install}" self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS, {"repository": self.data.full_name, "progress": 40}, ) if self.repository_manifest.persistent_directory: if await async_exists( self.hacs.hass, f"{self.content.path.local}/{self.repository_manifest.persistent_directory}", ): persistent_directory = Backup( hacs=self.hacs, local_path=f"{self.content.path.local}/{self.repository_manifest.persistent_directory}", backup_path=tempfile.gettempdir() + "/hacs_persistent_directory/", ) await self.hacs.hass.async_add_executor_job(persistent_directory.create) if self.data.installed and not self.content.single: backup = Backup(hacs=self.hacs, local_path=self.content.path.local) await self.hacs.hass.async_add_executor_job(backup.create) self.hacs.log.debug("%s Local path is set to %s", self.string, self.content.path.local) self.hacs.log.debug("%s Remote path is set to %s", self.string, self.content.path.remote) self.hacs.log.debug("%s Version to install: %s", self.string, version_to_install) self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS, {"repository": self.data.full_name, "progress": 50}, ) if self.repository_manifest.zip_release and self.repository_manifest.filename: await self.download_zip_files(self.validate) else: await self.download_content(version_to_install) self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS, {"repository": self.data.full_name, "progress": 70}, ) if self.validate.errors: for error in self.validate.errors: self.logger.error("%s %s", self.string, error) if self.data.installed and not self.content.single: await self.hacs.hass.async_add_executor_job(backup.restore) await self.hacs.hass.async_add_executor_job(backup.cleanup) raise HacsException("Could not download, see log for details") self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS, {"repository": self.data.full_name, "progress": 80}, ) if self.data.installed and not self.content.single: await self.hacs.hass.async_add_executor_job(backup.cleanup) if persistent_directory is not None: await self.hacs.hass.async_add_executor_job(persistent_directory.restore) await self.hacs.hass.async_add_executor_job(persistent_directory.cleanup) if self.validate.success: self.data.installed = True self.data.installed_commit = self.data.last_commit if version_to_install == self.data.default_branch: self.data.installed_version = None else: self.data.installed_version = version_to_install async def async_get_legacy_repository_object( self, etag: str | None = None, ) -> tuple[AIOGitHubAPIRepository, Any | None]: """Return a repository object.""" try: repository = await self.hacs.github.get_repo(self.data.full_name, etag) return repository, self.hacs.github.client.last_response.etag except AIOGitHubAPINotModifiedException as exception: raise HacsNotModifiedException(exception) from exception except (ValueError, AIOGitHubAPIException, Exception) as exception: raise HacsException(exception) from exception def update_filenames(self) -> None: """Get the filename to target.""" async def get_tree(self, ref: str): """Return the repository tree.""" if self.repository_object is None: raise HacsException("No repository_object") try: tree = await self.repository_object.get_tree(ref) return tree except (ValueError, AIOGitHubAPIException) as exception: raise HacsException(exception) from exception async def get_releases(self, prerelease=False, returnlimit=5) -> list[GitHubReleaseModel]: """Return the repository releases.""" response = await self.hacs.async_github_api_method( method=self.hacs.githubapi.repos.releases.list, repository=self.data.full_name, ) releases = [] for release in response.data or []: if len(releases) == returnlimit: break if release.draft or (release.prerelease and not prerelease): continue releases.append(release) return releases async def common_update_data( self, ignore_issues: bool = False, force: bool = False, retry=False, skip_releases=False, ) -> None: """Common update data.""" releases = [] try: repository_object, etag = await self.async_get_legacy_repository_object( etag=None if force or self.data.installed else self.data.etag_repository, ) self.repository_object = repository_object if self.data.full_name.lower() != repository_object.full_name.lower(): self.hacs.common.renamed_repositories[self.data.full_name] = ( repository_object.full_name ) if not self.hacs.system.generator: raise HacsRepositoryExistException self.logger.error( "%s Repository has been renamed - %s", self.string, repository_object.full_name ) self.data.update_data( repository_object.attributes, action=self.hacs.system.action, ) self.data.etag_repository = etag except HacsNotModifiedException: return except HacsRepositoryExistException: raise HacsRepositoryExistException from None except (AIOGitHubAPIException, HacsException) as exception: if not self.hacs.status.startup or self.hacs.system.generator: self.logger.error("%s %s", self.string, exception) if not ignore_issues: self.validate.errors.append("Repository does not exist.") raise HacsException(exception) from exception # Make sure the repository is not archived. if self.data.archived and not ignore_issues: self.validate.errors.append("Repository is archived.") if self.data.full_name not in self.hacs.common.archived_repositories: self.hacs.common.archived_repositories.add(self.data.full_name) raise HacsRepositoryArchivedException(f"{self} Repository is archived.") # Make sure the repository is not in the blacklist. if self.hacs.repositories.is_removed(self.data.full_name): removed = self.hacs.repositories.removed_repository(self.data.full_name) if removed.removal_type != "remove" and not ignore_issues: self.validate.errors.append("Repository has been requested to be removed.") raise HacsException(f"{self} Repository has been requested to be removed.") # Get releases. if not skip_releases: try: releases = await self.get_releases(prerelease=True, returnlimit=30) if releases: self.data.prerelease = None for release in releases: if release.draft: continue elif release.prerelease: if self.data.prerelease is None: self.data.prerelease = release.tag_name else: self.data.last_version = release.tag_name break self.data.releases = True filtered_releases = [ release for release in releases if not release.draft and (self.data.show_beta or not release.prerelease) ] self.releases.objects = filtered_releases self.data.published_tags = [x.tag_name for x in filtered_releases] except HacsException: self.data.releases = False if not self.force_branch: self.ref = self.version_to_download() if self.data.releases: for release in self.releases.objects or []: if release.tag_name == self.ref: if assets := release.assets: downloads = next(iter(assets)).download_count self.data.downloads = downloads elif self.hacs.system.generator and self.repository_object: await self.repository_object.set_last_commit() self.data.last_commit = self.repository_object.last_commit self.hacs.log.debug( "%s Running checks against %s", self.string, self.ref.replace("tags/", "") ) try: self.tree = await self.get_tree(self.ref) if not self.tree: raise HacsException("No files in tree") self.treefiles = [] for treefile in self.tree: self.treefiles.append(treefile.full_path) except (AIOGitHubAPIException, HacsException) as exception: if ( not retry and self.ref is not None and str(exception).startswith("GitHub returned 404") ): # Handle tags/branches being deleted. self.data.selected_tag = None self.ref = self.version_to_download() self.logger.warning( "%s Selected version/branch %s has been removed, falling back to default", self.string, self.ref, ) return await self.common_update_data(ignore_issues, force, True) if not self.hacs.status.startup and not ignore_issues: self.logger.error("%s %s", self.string, exception) if not ignore_issues: raise HacsException(exception) from None def gather_files_to_download(self) -> list[FileInformation]: """Return a list of file objects to be downloaded.""" files = [] tree = self.tree ref = f"{self.ref}".replace("tags/", "") releaseobjects = self.releases.objects category = self.data.category remotelocation = self.content.path.remote if self.should_try_releases: for release in releaseobjects or []: if ref == release.tag_name: for asset in release.assets or []: files.append( FileInformation(asset.browser_download_url, asset.name, asset.name) ) if files: return files if self.content.single: for treefile in tree: if treefile.filename == self.data.file_name: files.append( FileInformation( treefile.download_url, treefile.full_path, treefile.filename ) ) return files if category == "plugin": for treefile in tree: if treefile.path in ["", "dist"]: if remotelocation == "dist" and not treefile.filename.startswith("dist"): continue if not remotelocation: if not treefile.filename.endswith(".js"): continue if treefile.path != "": continue if not treefile.is_directory: files.append( FileInformation( treefile.download_url, treefile.full_path, treefile.filename ) ) if files: return files if self.repository_manifest.content_in_root: if not self.repository_manifest.filename: if category == "theme": tree = filter_content_return_one_of_type(self.tree, "", "yaml", "full_path") for path in tree: if path.is_directory: continue if path.full_path.startswith(self.content.path.remote): files.append(FileInformation(path.download_url, path.full_path, path.filename)) return files async def release_contents(self, version: str | None = None) -> list[FileInformation] | None: """Gather the contents of a release.""" release = await self.hacs.async_github_api_method( method=self.hacs.githubapi.generic, endpoint=f"/repos/{self.data.full_name}/releases/tags/{version}", raise_exception=False, ) if release is None: return None return [ FileInformation( url=asset.get("browser_download_url"), path=asset.get("name"), name=asset.get("name"), ) for asset in release.data.get("assets", []) ] @concurrent(concurrenttasks=10) async def dowload_repository_content(self, content: FileInformation) -> None: """Download content.""" try: self.logger.debug("%s Downloading %s", self.string, content.name) filecontent = await self.hacs.async_download_file(content.download_url) if filecontent is None: self.validate.errors.append(f"[{content.name}] was not downloaded.") return # Save the content of the file. if self.content.single or content.path is None: local_directory = self.content.path.local else: _content_path = content.path if not self.repository_manifest.content_in_root: _content_path = _content_path.replace(f"{self.content.path.remote}", "") local_directory = f"{self.content.path.local}/{_content_path}" local_directory = local_directory.split("/") del local_directory[-1] local_directory = "/".join(local_directory) # Check local directory pathlib.Path(local_directory).mkdir(parents=True, exist_ok=True) local_file_path = (f"{local_directory}/{content.name}").replace("//", "/") result = await self.hacs.async_save_file(local_file_path, filecontent) if result: self.logger.info("%s Download of %s completed", self.string, content.name) return self.validate.errors.append(f"[{content.name}] was not downloaded.") except ( # lgtm [py/catch-base-exception] pylint: disable=broad-except BaseException ) as exception: self.validate.errors.append(f"Download was not completed [{exception}]") async def async_remove_entity_device(self) -> None: """Remove the entity device.""" device_registry: dr.DeviceRegistry = dr.async_get(hass=self.hacs.hass) device = device_registry.async_get_device(identifiers={(DOMAIN, str(self.data.id))}) if device is None: return device_registry.async_remove_device(device_id=device.id) def version_to_download(self) -> str: """Determine which version to download.""" if self.force_branch and self.ref is not None: return self.ref if self.data.last_version is not None: if self.data.selected_tag is not None: if self.data.selected_tag == self.data.last_version: self.data.selected_tag = None return self.data.last_version return self.data.selected_tag return self.data.last_version if self.data.selected_tag is not None: if self.data.selected_tag == self.data.default_branch: return self.data.default_branch if self.data.selected_tag in self.data.published_tags: return self.data.selected_tag return self.data.default_branch or "main" async def get_documentation( self, *, filename: str | None = None, version: str | None = None, **kwargs, ) -> str | None: """Get the documentation of the repository.""" if filename is None: return None if version is not None: target_version = version elif self.data.installed: target_version = self.data.installed_version or self.data.installed_commit else: target_version = self.data.last_version or self.data.last_commit or self.ref self.logger.debug( "%s Getting documentation for version=%s,filename=%s", self.string, target_version, filename, ) if target_version is None: return None result = await self.hacs.async_download_file( f"https://raw.githubusercontent.com/{self.data.full_name}/{target_version}/{filename}", nolog=True, ) return ( result.decode(encoding="utf-8") .replace(" HacsManifest | None: """Get the hacs.json file of the repository.""" if (result := await self.get_hacs_json_raw(version=version)) is None: return None return HacsManifest.from_dict(result) @return_none_on_exception async def get_hacs_json_raw( self, *, version: str, **kwargs, ) -> dict[str, Any] | None: """Get the hacs.json file of the repository.""" self.logger.debug("%s Getting hacs.json for version=%s", self.string, version) result = await self.hacs.async_download_file( f"https://raw.githubusercontent.com/{self.data.full_name}/{version}/hacs.json", nolog=True, handle_rate_limit=True, ) return json_loads(result) if result else None async def _ensure_download_capabilities(self, ref: str | None, **kwargs: Any) -> None: """Ensure that the download can be handled.""" target_manifest: HacsManifest | None = None if ref is None: if not self.can_download: raise HacsException( f"This {self.data.category.value} is not available for download." ) return if not ref: target_manifest = self.repository_manifest else: target_manifest = await self.get_hacs_json(version=ref) if target_manifest is None: raise HacsException( f"The version {ref} for this {self.data.category.value} can not be used with HACS." ) if ( target_manifest.homeassistant is not None and self.hacs.core.ha_version < target_manifest.homeassistant ): raise HacsException( f"This version requires Home Assistant {target_manifest.homeassistant} or newer." ) if target_manifest.hacs is not None and self.hacs.version < target_manifest.hacs: raise HacsException(f"This version requires HACS {target_manifest.hacs} or newer.") async def async_download_repository(self, *, ref: str | None = None, **_) -> None: """Download the content of a repository.""" await self._ensure_download_capabilities(ref) self.logger.info("Starting download, %s", ref) if self.display_version_or_commit == "version": self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS, {"repository": self.data.full_name, "progress": 10}, ) if not ref: await self.update_repository(force=True) else: self.ref = ref self.data.selected_tag = ref self.force_branch = ref is not None self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS, {"repository": self.data.full_name, "progress": 20}, ) try: await self.async_install(version=ref) except HacsException as exception: raise HacsException( f"Downloading {self.data.full_name} with version {ref or self.data.last_version or self.data.last_commit} failed with ({exception})" ) from exception finally: self.data.selected_tag = None self.force_branch = False self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS, {"repository": self.data.full_name, "progress": False}, ) async def async_get_releases(self, *, first: int = 30) -> list[GitHubReleaseModel]: """Get the last x releases of a repository.""" response = await self.hacs.async_github_api_method( method=self.hacs.githubapi.repos.releases.list, repository=self.data.full_name, kwargs={"per_page": 30}, ) return response.data ================================================ FILE: custom_components/hacs/repositories/integration.py ================================================ """Class for integrations in HACS.""" from __future__ import annotations from typing import TYPE_CHECKING, Any from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from homeassistant.loader import async_get_custom_components from ..const import DOMAIN from ..enums import HacsCategory, HacsDispatchEvent, HacsGitHubRepo, RepositoryFile from ..exceptions import AddonRepositoryException, HacsException from ..utils.decode import decode_content from ..utils.decorator import concurrent from ..utils.filters import get_first_directory_in_directory from ..utils.json import json_loads from .base import HacsRepository if TYPE_CHECKING: from ..base import HacsBase class HacsIntegrationRepository(HacsRepository): """Integrations in HACS.""" def __init__(self, hacs: HacsBase, full_name: str): """Initialize.""" super().__init__(hacs=hacs) self.data.full_name = full_name self.data.full_name_lower = full_name.lower() self.data.category = HacsCategory.INTEGRATION self.content.path.remote = "custom_components" self.content.path.local = self.localpath @property def localpath(self): """Return localpath.""" return f"{self.hacs.core.config_path}/custom_components/{self.data.domain}" async def async_post_installation(self): """Run post installation steps.""" self.pending_restart = True if self.data.config_flow: if self.data.full_name != HacsGitHubRepo.INTEGRATION: await self.reload_custom_components() if self.data.first_install: self.pending_restart = False if self.pending_restart: self.logger.debug("%s Creating restart_required issue", self.string) async_create_issue( hass=self.hacs.hass, domain=DOMAIN, issue_id=f"restart_required_{self.data.id}_{self.ref}", is_fixable=True, issue_domain=self.data.domain or DOMAIN, severity=IssueSeverity.WARNING, translation_key="restart_required", translation_placeholders={ "name": self.display_name, }, ) async def async_post_uninstall(self) -> None: """Run post uninstall steps.""" if self.data.config_flow: await self.reload_custom_components() else: self.pending_restart = True async def validate_repository(self): """Validate.""" await self.common_validate() # Custom step 1: Validate content. if self.repository_manifest.content_in_root: self.content.path.remote = "" if self.content.path.remote == "custom_components": name = get_first_directory_in_directory(self.tree, "custom_components") if name is None: if ( "repository.json" in self.treefiles or "repository.yaml" in self.treefiles or "repository.yml" in self.treefiles ): raise AddonRepositoryException() raise HacsException( f"{self.string} Repository structure for {self.ref.replace('tags/', '')} is not compliant" ) self.content.path.remote = f"custom_components/{name}" # Get the content of manifest.json if manifest := await self.async_get_integration_manifest(): try: self.integration_manifest = manifest self.data.authors = manifest.get("codeowners", []) self.data.domain = manifest["domain"] self.data.manifest_name = manifest.get("name") self.data.config_flow = manifest.get("config_flow", False) except KeyError as exception: self.validate.errors.append( f"Missing expected key '{exception}' in {RepositoryFile.MAINIFEST_JSON}" ) self.hacs.log.error( "Missing expected key '%s' in '%s'", exception, RepositoryFile.MAINIFEST_JSON ) # Set local path self.content.path.local = self.localpath # Handle potential errors if self.validate.errors: for error in self.validate.errors: if not self.hacs.status.startup: self.logger.error("%s %s", self.string, error) return self.validate.success @concurrent(concurrenttasks=10, backoff_time=5) async def update_repository(self, ignore_issues=False, force=False): """Update.""" if not await self.common_update(ignore_issues, force) and not force: return if self.repository_manifest.content_in_root: self.content.path.remote = "" if self.content.path.remote == "custom_components": name = get_first_directory_in_directory(self.tree, "custom_components") self.content.path.remote = f"custom_components/{name}" # Get the content of manifest.json if manifest := await self.async_get_integration_manifest(): try: self.integration_manifest = manifest self.data.authors = manifest.get("codeowners", []) self.data.domain = manifest["domain"] self.data.manifest_name = manifest.get("name") self.data.config_flow = manifest.get("config_flow", False) except KeyError as exception: self.validate.errors.append( f"Missing expected key '{exception}' in {RepositoryFile.MAINIFEST_JSON}" ) self.hacs.log.error( "Missing expected key '%s' in '%s'", exception, RepositoryFile.MAINIFEST_JSON ) # Set local path self.content.path.local = self.localpath # Signal frontend to refresh if self.data.installed: self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY, { "id": 1337, "action": "update", "repository": self.data.full_name, "repository_id": self.data.id, }, ) async def reload_custom_components(self): """Reload custom_components (and config flows)in HA.""" self.logger.info("Reloading custom_component cache") del self.hacs.hass.data["custom_components"] await async_get_custom_components(self.hacs.hass) self.logger.info("Custom_component cache reloaded") async def async_get_integration_manifest(self, ref: str = None) -> dict[str, Any] | None: """Get the content of the manifest.json file.""" manifest_path = ( "manifest.json" if self.repository_manifest.content_in_root else f"{self.content.path.remote}/{RepositoryFile.MAINIFEST_JSON}" ) if not manifest_path in (x.full_path for x in self.tree): raise HacsException(f"No {RepositoryFile.MAINIFEST_JSON} file found '{manifest_path}'") target_ref = ref or self.version_to_download() self.logger.debug("%s Getting %s for ref=%s", self.string, manifest_path, target_ref) response = await self.hacs.async_github_api_method( method=self.hacs.githubapi.repos.contents.get, repository=self.data.full_name, path=manifest_path, **{"params": {"ref": target_ref}}, ) if response: return json_loads(decode_content(response.data.content)) async def get_integration_manifest(self, *, version: str, **kwargs) -> dict[str, Any] | None: """Get the content of the manifest.json file.""" manifest_path = ( "manifest.json" if self.repository_manifest.content_in_root else f"{self.content.path.remote}/{RepositoryFile.MAINIFEST_JSON}" ) if manifest_path not in (x.full_path for x in self.tree): raise HacsException(f"No {RepositoryFile.MAINIFEST_JSON} file found '{manifest_path}'") self.logger.debug("%s Getting manifest.json for version=%s", self.string, version) try: result = await self.hacs.async_download_file( f"https://raw.githubusercontent.com/{self.data.full_name}/{version}/{manifest_path}", nolog=True, ) if result is None: return None return json_loads(result) except Exception: # pylint: disable=broad-except return None ================================================ FILE: custom_components/hacs/repositories/plugin.py ================================================ """Class for plugins in HACS.""" from __future__ import annotations import re from typing import TYPE_CHECKING from ..enums import HacsCategory, HacsDispatchEvent from ..exceptions import HacsException from ..utils.decorator import concurrent from ..utils.json import json_loads from .base import HacsRepository HACSTAG_REPLACER = re.compile(r"\D+") if TYPE_CHECKING: from homeassistant.components.lovelace.resources import ResourceStorageCollection from ..base import HacsBase class HacsPluginRepository(HacsRepository): """Plugins in HACS.""" def __init__(self, hacs: HacsBase, full_name: str): """Initialize.""" super().__init__(hacs=hacs) self.data.full_name = full_name self.data.full_name_lower = full_name.lower() self.data.file_name = None self.data.category = HacsCategory.PLUGIN self.content.path.local = self.localpath @property def localpath(self): """Return localpath.""" return f"{self.hacs.core.config_path}/www/community/{self.data.full_name.split('/')[-1]}" async def validate_repository(self): """Validate.""" # Run common validation steps. await self.common_validate() # Custom step 1: Validate content. self.update_filenames() if self.content.path.remote is None: raise HacsException( f"{self.string} Repository structure for {self.ref.replace('tags/', '')} is not compliant" ) if self.content.path.remote == "release": self.content.single = True # Handle potential errors if self.validate.errors: for error in self.validate.errors: if not self.hacs.status.startup: self.logger.error("%s %s", self.string, error) return self.validate.success async def async_post_installation(self): """Run post installation steps.""" await self.hacs.async_setup_frontend_endpoint_plugin() await self.update_dashboard_resources() async def async_post_uninstall(self): """Run post uninstall steps.""" await self.remove_dashboard_resources() @concurrent(concurrenttasks=10, backoff_time=5) async def update_repository(self, ignore_issues=False, force=False): """Update.""" if not await self.common_update(ignore_issues, force) and not force: return # Get plugin objects. self.update_filenames() if self.content.path.remote is None: self.validate.errors.append( f"{self.string} Repository structure for {self.ref.replace('tags/', '')} is not compliant" ) if self.content.path.remote == "release": self.content.single = True # Signal frontend to refresh if self.data.installed: self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY, { "id": 1337, "action": "update", "repository": self.data.full_name, "repository_id": self.data.id, }, ) async def get_package_content(self): """Get package content.""" try: package = await self.repository_object.get_contents("package.json", self.ref) package = json_loads(package.content) if package: self.data.authors = package["author"] except BaseException: # lgtm [py/catch-base-exception] pylint: disable=broad-except pass def update_filenames(self) -> None: """Get the filename to target.""" content_in_root = self.repository_manifest.content_in_root if specific_filename := self.repository_manifest.filename: valid_filenames = (specific_filename,) else: valid_filenames = ( f"{self.data.name.replace('lovelace-', '')}.js", f"{self.data.name}.js", f"{self.data.name}.umd.js", f"{self.data.name}-bundle.js", ) if not content_in_root: if self.releases.objects: release = self.releases.objects[0] if release.assets: if assetnames := [ filename for filename in valid_filenames for asset in release.assets if filename == asset.name ]: self.data.file_name = assetnames[0] self.content.path.remote = "release" return all_paths = {x.full_path for x in self.tree} for filename in valid_filenames: if filename in all_paths: self.data.file_name = filename self.content.path.remote = "" return if not content_in_root and f"dist/{filename}" in all_paths: self.data.file_name = filename.split("/")[-1] self.content.path.remote = "dist" return def generate_dashboard_resource_hacstag(self) -> str: """Get the HACS tag used by dashboard resources.""" version = ( self.display_installed_version or self.data.selected_tag or self.display_available_version ) return f"{self.data.id}{HACSTAG_REPLACER.sub('', version)}" def generate_dashboard_resource_namespace(self) -> str: """Get the dashboard resource namespace.""" return f"/hacsfiles/{self.data.full_name.split('/')[1]}" def generate_dashboard_resource_url(self) -> str: """Get the dashboard resource namespace.""" filename = self.data.file_name if "/" in filename: self.logger.warning("%s have defined an invalid file name %s", self.string, filename) filename = filename.split("/")[-1] return ( f"{self.generate_dashboard_resource_namespace()}/{filename}" f"?hacstag={self.generate_dashboard_resource_hacstag()}" ) def _get_resource_handler(self) -> ResourceStorageCollection | None: """Get the resource handler.""" resources: ResourceStorageCollection | None if not (hass_data := self.hacs.hass.data): self.logger.error("%s Can not access the hass data", self.string) return if (lovelace_data := hass_data.get("lovelace")) is None: self.logger.warning("%s Can not access the lovelace integration data", self.string) return if self.hacs.core.ha_version > "2025.1.99": # Changed to 2025.2.0 # Changed in https://github.com/home-assistant/core/pull/136313 resources = lovelace_data.resources else: resources = lovelace_data.get("resources") if resources is None: self.logger.warning("%s Can not access the dashboard resources", self.string) return if not hasattr(resources, "store") or resources.store is None: self.logger.info("%s YAML mode detected, can not update resources", self.string) return if resources.store.key != "lovelace_resources" or resources.store.version != 1: self.logger.warning("%s Can not use the dashboard resources", self.string) return return resources async def update_dashboard_resources(self) -> None: """Update dashboard resources.""" if not (resources := self._get_resource_handler()): return if not resources.loaded: await resources.async_load() namespace = self.generate_dashboard_resource_namespace() url = self.generate_dashboard_resource_url() for entry in resources.async_items(): if (entry_url := entry["url"]).startswith(namespace): if entry_url != url: self.logger.info( "%s Updating existing dashboard resource from %s to %s", self.string, entry_url, url, ) await resources.async_update_item(entry["id"], {"url": url}) return # Nothing was updated, add the resource self.logger.info("%s Adding dashboard resource %s", self.string, url) await resources.async_create_item({"res_type": "module", "url": url}) async def remove_dashboard_resources(self) -> None: """Remove dashboard resources.""" if not (resources := self._get_resource_handler()): return if not resources.loaded: await resources.async_load() namespace = self.generate_dashboard_resource_namespace() for entry in resources.async_items(): if entry["url"].startswith(namespace): self.logger.info("%s Removing dashboard resource %s", self.string, entry["url"]) await resources.async_delete_item(entry["id"]) return ================================================ FILE: custom_components/hacs/repositories/python_script.py ================================================ """Class for python_scripts in HACS.""" from __future__ import annotations from typing import TYPE_CHECKING from ..enums import HacsCategory, HacsDispatchEvent from ..exceptions import HacsException from ..utils.decorator import concurrent from .base import HacsRepository if TYPE_CHECKING: from ..base import HacsBase class HacsPythonScriptRepository(HacsRepository): """python_scripts in HACS.""" category = "python_script" def __init__(self, hacs: HacsBase, full_name: str): """Initialize.""" super().__init__(hacs=hacs) self.data.full_name = full_name self.data.full_name_lower = full_name.lower() self.data.category = HacsCategory.PYTHON_SCRIPT self.content.path.remote = "python_scripts" self.content.path.local = self.localpath self.content.single = True @property def localpath(self): """Return localpath.""" return f"{self.hacs.core.config_path}/python_scripts" async def validate_repository(self): """Validate.""" # Run common validation steps. await self.common_validate() # Custom step 1: Validate content. if self.repository_manifest.content_in_root: self.content.path.remote = "" compliant = False for treefile in self.treefiles: if treefile.startswith(f"{self.content.path.remote}") and treefile.endswith(".py"): compliant = True break if not compliant: raise HacsException( f"{self.string} Repository structure for {self.ref.replace('tags/', '')} is not compliant" ) # Handle potential errors if self.validate.errors: for error in self.validate.errors: if not self.hacs.status.startup: self.logger.error("%s %s", self.string, error) return self.validate.success async def async_post_registration(self): """Registration.""" # Set name self.update_filenames() if self.hacs.system.action: await self.hacs.validation.async_run_repository_checks(self) @concurrent(concurrenttasks=10, backoff_time=5) async def update_repository(self, ignore_issues=False, force=False): """Update.""" if not await self.common_update(ignore_issues, force) and not force: return # Get python_script objects. if self.repository_manifest.content_in_root: self.content.path.remote = "" compliant = False for treefile in self.treefiles: if treefile.startswith(f"{self.content.path.remote}") and treefile.endswith(".py"): compliant = True break if not compliant: raise HacsException( f"{self.string} Repository structure for {self.ref.replace('tags/', '')} is not compliant" ) # Update name self.update_filenames() # Signal frontend to refresh if self.data.installed: self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY, { "id": 1337, "action": "update", "repository": self.data.full_name, "repository_id": self.data.id, }, ) def update_filenames(self) -> None: """Get the filename to target.""" for treefile in self.tree: if treefile.full_path.startswith( self.content.path.remote ) and treefile.full_path.endswith(".py"): self.data.file_name = treefile.filename ================================================ FILE: custom_components/hacs/repositories/template.py ================================================ """Class for themes in HACS.""" from __future__ import annotations from typing import TYPE_CHECKING from homeassistant.exceptions import HomeAssistantError from ..enums import HacsCategory, HacsDispatchEvent from ..exceptions import HacsException from ..utils.decorator import concurrent from .base import HacsRepository if TYPE_CHECKING: from ..base import HacsBase class HacsTemplateRepository(HacsRepository): """Custom templates in HACS.""" def __init__(self, hacs: HacsBase, full_name: str): """Initialize.""" super().__init__(hacs=hacs) self.data.full_name = full_name self.data.full_name_lower = full_name.lower() self.data.category = HacsCategory.TEMPLATE self.content.path.remote = "" self.content.path.local = self.localpath self.content.single = True @property def localpath(self): """Return localpath.""" return f"{self.hacs.core.config_path}/custom_templates" async def async_post_installation(self): """Run post installation steps.""" await self._reload_custom_templates() async def validate_repository(self): """Validate.""" # Run common validation steps. await self.common_validate() # Custom step 1: Validate content. self.data.file_name = self.repository_manifest.filename if ( not self.data.file_name or "/" in self.data.file_name or not self.data.file_name.endswith(".jinja") or self.data.file_name not in self.treefiles ): raise HacsException( f"{self.string} Repository structure for {self.ref.replace('tags/', '')} is not compliant" ) # Handle potential errors if self.validate.errors: for error in self.validate.errors: if not self.hacs.status.startup: self.logger.error("%s %s", self.string, error) return self.validate.success async def async_post_registration(self): """Registration.""" # Set filenames self.data.file_name = self.repository_manifest.filename self.content.path.local = self.localpath if self.hacs.system.action: await self.hacs.validation.async_run_repository_checks(self) async def async_post_uninstall(self) -> None: """Run post uninstall steps.""" await self._reload_custom_templates() async def _reload_custom_templates(self) -> None: """Reload custom templates.""" self.logger.debug("%s Reloading custom templates", self.string) try: await self.hacs.hass.services.async_call("homeassistant", "reload_custom_templates", {}) except HomeAssistantError as exception: self.logger.exception("%s %s", self.string, exception) @concurrent(concurrenttasks=10, backoff_time=5) async def update_repository(self, ignore_issues=False, force=False): """Update.""" if not await self.common_update(ignore_issues, force) and not force: return # Update filenames self.data.file_name = self.repository_manifest.filename self.content.path.local = self.localpath # Signal frontend to refresh if self.data.installed: self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY, { "id": 1337, "action": "update", "repository": self.data.full_name, "repository_id": self.data.id, }, ) ================================================ FILE: custom_components/hacs/repositories/theme.py ================================================ """Class for themes in HACS.""" from __future__ import annotations from typing import TYPE_CHECKING from homeassistant.exceptions import HomeAssistantError from ..enums import HacsCategory, HacsDispatchEvent from ..exceptions import HacsException from ..utils.decorator import concurrent from .base import HacsRepository if TYPE_CHECKING: from ..base import HacsBase class HacsThemeRepository(HacsRepository): """Themes in HACS.""" def __init__(self, hacs: HacsBase, full_name: str): """Initialize.""" super().__init__(hacs=hacs) self.data.full_name = full_name self.data.full_name_lower = full_name.lower() self.data.category = HacsCategory.THEME self.content.path.remote = "themes" self.content.path.local = self.localpath self.content.single = False @property def localpath(self): """Return localpath.""" return f"{self.hacs.core.config_path}/themes/{self.data.file_name.replace('.yaml', '')}" async def async_post_installation(self): """Run post installation steps.""" await self._reload_frontend_themes() async def validate_repository(self): """Validate.""" # Run common validation steps. await self.common_validate() # Custom step 1: Validate content. compliant = False for treefile in self.treefiles: if treefile.startswith("themes/") and treefile.endswith(".yaml"): compliant = True break if not compliant: raise HacsException( f"{self.string} Repository structure for {self.ref.replace('tags/', '')} is not compliant" ) if self.repository_manifest.content_in_root: self.content.path.remote = "" # Handle potential errors if self.validate.errors: for error in self.validate.errors: if not self.hacs.status.startup: self.logger.error("%s %s", self.string, error) return self.validate.success async def async_post_registration(self): """Registration.""" # Set name self.update_filenames() self.content.path.local = self.localpath if self.hacs.system.action: await self.hacs.validation.async_run_repository_checks(self) async def _reload_frontend_themes(self) -> None: """Reload frontend themes.""" self.logger.debug("%s Reloading frontend themes", self.string) try: await self.hacs.hass.services.async_call("frontend", "reload_themes", {}) except HomeAssistantError as exception: self.logger.exception("%s %s", self.string, exception) async def async_post_uninstall(self) -> None: """Run post uninstall steps.""" await self._reload_frontend_themes() @concurrent(concurrenttasks=10, backoff_time=5) async def update_repository(self, ignore_issues=False, force=False): """Update.""" if not await self.common_update(ignore_issues, force) and not force: return # Get theme objects. if self.repository_manifest.content_in_root: self.content.path.remote = "" # Update name self.update_filenames() self.content.path.local = self.localpath # Signal frontend to refresh if self.data.installed: self.hacs.async_dispatch( HacsDispatchEvent.REPOSITORY, { "id": 1337, "action": "update", "repository": self.data.full_name, "repository_id": self.data.id, }, ) def update_filenames(self) -> None: """Get the filename to target.""" for treefile in self.tree: if treefile.full_path.startswith( self.content.path.remote ) and treefile.full_path.endswith(".yaml"): self.data.file_name = treefile.filename ================================================ FILE: custom_components/hacs/switch.py ================================================ """Switch entities for HACS.""" from __future__ import annotations from typing import Any from homeassistant.components.switch import SwitchEntity from homeassistant.config_entries import ConfigEntry from homeassistant.const import EntityCategory from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from .base import HacsBase from .const import DOMAIN from .entity import HacsRepositoryEntity from .repositories.base import HacsRepository async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Setup switch platform.""" hacs: HacsBase = hass.data[DOMAIN] async_add_entities( HacsRepositoryPreReleaseSwitchEntity(hacs=hacs, repository=repository) for repository in hacs.repositories.list_downloaded ) class HacsRepositoryPreReleaseSwitchEntity(HacsRepositoryEntity, SwitchEntity): """Pre-release switch entities for repositories downloaded with HACS.""" _attr_entity_category = EntityCategory.DIAGNOSTIC _attr_has_entity_name = True _attr_translation_key = "pre-release" def __init__(self, hacs: HacsBase, repository: HacsRepository) -> None: """Initialize the repository pre-release switch.""" super().__init__(hacs, repository) self._attr_entity_registry_enabled_default = self.repository.data.show_beta @property def is_on(self) -> bool: """Return if the pre-release option is enabled for the repository.""" return self.repository.data.show_beta async def async_turn_on(self, **kwargs: Any) -> None: """Turn the entity on.""" await self._handle_change(value=True) async def async_turn_off(self, **kwargs: Any) -> None: """Turn the entity off.""" await self._handle_change(value=False) async def _handle_change(self, value: bool) -> None: """Handle attribute value changes.""" self.repository.data.show_beta = value # As this value is directly affecting what data points is in use by other entities # we need to update all entities to reflect the change # Do force an update of the entities we need to clear the last fetched data # since that is used to limit state updates # Once we have signaled the update we can restore the last fetched data _last_fetch = self.repository.data.last_fetched self.repository.data.last_fetched = None self.coordinator.async_update_listeners() self.repository.data.last_fetched = _last_fetch # Restore last fetched # Write the HACS data and update the entity state await self.hacs.data.async_write() self.async_write_ha_state() ================================================ FILE: custom_components/hacs/system_health.py ================================================ """Provide info to system health.""" from typing import Any from aiogithubapi.common.const import BASE_API_URL from homeassistant.components import system_health from homeassistant.core import HomeAssistant, callback from .base import HacsBase from .const import DOMAIN GITHUB_STATUS = "https://www.githubstatus.com/" CLOUDFLARE_STATUS = "https://www.cloudflarestatus.com/" @callback def async_register(hass: HomeAssistant, register: system_health.SystemHealthRegistration) -> None: """Register system health callbacks.""" register.domain = "Home Assistant Community Store" register.async_register_info(system_health_info, "/hacs") async def system_health_info(hass: HomeAssistant) -> dict[str, Any]: """Get info for the info page.""" if DOMAIN not in hass.data: return {"Disabled": "HACS is not loaded, but HA still requests this information..."} hacs: HacsBase = hass.data[DOMAIN] response = await hacs.githubapi.rate_limit() data = { "GitHub API": system_health.async_check_can_reach_url(hass, BASE_API_URL, GITHUB_STATUS), "GitHub Content": system_health.async_check_can_reach_url( hass, "https://raw.githubusercontent.com/hacs/integration/main/hacs.json" ), "GitHub Web": system_health.async_check_can_reach_url( hass, "https://github.com/", GITHUB_STATUS ), "HACS Data": system_health.async_check_can_reach_url( hass, "https://data-v2.hacs.xyz/data.json", CLOUDFLARE_STATUS ), "GitHub API Calls Remaining": response.data.resources.core.remaining, "Installed Version": hacs.version, "Stage": hacs.stage, "Available Repositories": len(hacs.repositories.list_all), "Downloaded Repositories": len(hacs.repositories.list_downloaded), } if hacs.system.disabled: data["Disabled"] = hacs.system.disabled_reason return data ================================================ FILE: custom_components/hacs/types.py ================================================ """Custom HACS types.""" from typing import TypedDict class DownloadableContent(TypedDict): """Downloadable content.""" url: str name: str ================================================ FILE: custom_components/hacs/update.py ================================================ """Update entities for HACS.""" from __future__ import annotations from typing import Any from homeassistant.components.update import UpdateEntity, UpdateEntityFeature from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, HomeAssistantError, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.entity_platform import AddEntitiesCallback from .base import HacsBase from .const import DOMAIN from .entity import HacsRepositoryEntity from .enums import HacsCategory, HacsDispatchEvent from .exceptions import HacsException async def async_setup_entry( hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback ) -> None: """Setup update platform.""" hacs: HacsBase = hass.data[DOMAIN] async_add_entities( HacsRepositoryUpdateEntity(hacs=hacs, repository=repository) for repository in hacs.repositories.list_downloaded ) class HacsRepositoryUpdateEntity(HacsRepositoryEntity, UpdateEntity): """Update entities for repositories downloaded with HACS.""" _attr_supported_features = ( UpdateEntityFeature.INSTALL | UpdateEntityFeature.SPECIFIC_VERSION | UpdateEntityFeature.PROGRESS | UpdateEntityFeature.RELEASE_NOTES ) @property def name(self) -> str | None: """Return the name.""" return f"{self.repository.display_name} update" @property def latest_version(self) -> str: """Return latest version of the entity.""" return self.repository.display_available_version @property def release_url(self) -> str: """Return the URL of the release page.""" if self.repository.display_version_or_commit == "commit": return f"https://github.com/{self.repository.data.full_name}" return f"https://github.com/{self.repository.data.full_name}/releases/{self.latest_version}" @property def installed_version(self) -> str: """Return downloaded version of the entity.""" return self.repository.display_installed_version @property def release_summary(self) -> str | None: """Return the release summary.""" if self.repository.pending_restart: return "Restart of Home Assistant required" return None @property def entity_picture(self) -> str | None: """Return the entity picture to use in the frontend.""" if ( self.repository.data.category != HacsCategory.INTEGRATION or self.repository.data.domain is None ): return None return f"https://brands.home-assistant.io/_/{self.repository.data.domain}/icon.png" async def async_install(self, version: str | None, backup: bool, **kwargs: Any) -> None: """Install an update.""" to_download = version or self.latest_version if to_download == self.installed_version: raise HomeAssistantError( f"Version {self.installed_version} of {self.repository.data.full_name} is already downloaded" ) try: await self.repository.async_download_repository(ref=version or self.latest_version) except HacsException as exception: raise HomeAssistantError(exception) from exception async def async_release_notes(self) -> str | None: """Return the release notes.""" if self.repository.pending_restart: return None if self.latest_version not in self.repository.data.published_tags: releases = await self.repository.get_releases( prerelease=self.repository.data.show_beta, returnlimit=self.hacs.configuration.release_limit, ) if releases: self.repository.data.releases = True self.repository.releases.objects = releases self.repository.data.published_tags = [x.tag_name for x in releases] self.repository.data.last_version = next(iter(self.repository.data.published_tags)) release_notes = "" # Compile release notes from installed version up to the latest if self.installed_version in self.repository.data.published_tags: for release in self.repository.releases.objects: if release.tag_name == self.installed_version: break release_notes += f"# {release.tag_name}" if release.tag_name != release.name: release_notes += f" - {release.name}" release_notes += f"\n\n{release.body}" release_notes += "\n\n---\n\n" elif any(self.repository.releases.objects): release_notes += self.repository.releases.objects[0].body if self.repository.pending_update: if self.repository.data.category == HacsCategory.INTEGRATION: release_notes += ( "\n\nYou need to restart" " Home Assistant manually after updating.\n\n" ) if self.repository.data.category == HacsCategory.PLUGIN: release_notes += ( "\n\nYou need to manually" " clear the frontend cache after updating.\n\n" ) return release_notes.replace("\n#", "\n\n#") async def async_added_to_hass(self) -> None: """Register for status events.""" await super().async_added_to_hass() self.async_on_remove( async_dispatcher_connect( self.hass, HacsDispatchEvent.REPOSITORY_DOWNLOAD_PROGRESS, self._update_download_progress, ) ) @callback def _update_download_progress(self, data: dict) -> None: """Update the download progress.""" if data["repository"] != self.repository.data.full_name: return self._update_in_progress(progress=data["progress"]) @callback def _update_in_progress(self, progress: int | bool) -> None: """Update the download progress.""" self._attr_in_progress = progress self.async_write_ha_state() ================================================ FILE: custom_components/hacs/utils/__init__.py ================================================ """Initialize HACS utils.""" ================================================ FILE: custom_components/hacs/utils/backup.py ================================================ """Backup.""" from __future__ import annotations import os import shutil import tempfile from time import sleep from typing import TYPE_CHECKING from .path import is_safe if TYPE_CHECKING: from ..base import HacsBase from ..repositories.base import HacsRepository DEFAULT_BACKUP_PATH = f"{tempfile.gettempdir()}/hacs_backup/" class Backup: """Backup.""" def __init__( self, hacs: HacsBase, local_path: str | None = None, backup_path: str = DEFAULT_BACKUP_PATH, repository: HacsRepository | None = None, ) -> None: """Initialize.""" self.hacs = hacs self.repository = repository self.local_path = local_path or repository.content.path.local self.backup_path = backup_path if repository: self.backup_path = ( tempfile.gettempdir() + f"/hacs_persistent_{repository.data.category}/" + repository.data.name ) self.backup_path_full = f"{self.backup_path}{self.local_path.split('/')[-1]}" def _init_backup_dir(self) -> bool: """Init backup dir.""" if not os.path.exists(self.local_path): return False if not is_safe(self.hacs, self.local_path): return False if os.path.exists(self.backup_path): shutil.rmtree(self.backup_path) # Wait for the folder to be removed while os.path.exists(self.backup_path): sleep(0.1) os.makedirs(self.backup_path, exist_ok=True) return True def create(self) -> None: """Create a backup in /tmp""" if not self._init_backup_dir(): return try: if os.path.isfile(self.local_path): shutil.copyfile(self.local_path, self.backup_path_full) os.remove(self.local_path) else: shutil.copytree(self.local_path, self.backup_path_full) shutil.rmtree(self.local_path) while os.path.exists(self.local_path): sleep(0.1) self.hacs.log.debug( "Backup for %s, created in %s", self.local_path, self.backup_path_full, ) except ( BaseException # lgtm [py/catch-base-exception] pylint: disable=broad-except ) as exception: self.hacs.log.warning("Could not create backup: %s", exception) def restore(self) -> None: """Restore from backup.""" if not os.path.exists(self.backup_path_full): return if os.path.isfile(self.backup_path_full): if os.path.exists(self.local_path): os.remove(self.local_path) shutil.copyfile(self.backup_path_full, self.local_path) else: if os.path.exists(self.local_path): shutil.rmtree(self.local_path) while os.path.exists(self.local_path): sleep(0.1) shutil.copytree(self.backup_path_full, self.local_path) self.hacs.log.debug("Restored %s, from backup %s", self.local_path, self.backup_path_full) def cleanup(self) -> None: """Cleanup backup files.""" if not os.path.exists(self.backup_path): return shutil.rmtree(self.backup_path) # Wait for the folder to be removed while os.path.exists(self.backup_path): sleep(0.1) self.hacs.log.debug("Backup dir %s cleared", self.backup_path) ================================================ FILE: custom_components/hacs/utils/configuration_schema.py ================================================ """HACS Configuration Schemas.""" # Configuration: SIDEPANEL_TITLE = "sidepanel_title" SIDEPANEL_ICON = "sidepanel_icon" APPDAEMON = "appdaemon" # Options: COUNTRY = "country" ================================================ FILE: custom_components/hacs/utils/data.py ================================================ """Data handler for HACS.""" from __future__ import annotations import asyncio from datetime import UTC, datetime from typing import Any from homeassistant.core import callback from homeassistant.exceptions import HomeAssistantError from ..base import HacsBase from ..const import HACS_REPOSITORY_ID from ..enums import HacsDisabledReason, HacsDispatchEvent from ..repositories.base import TOPIC_FILTER, HacsManifest, HacsRepository from .logger import LOGGER from .path import is_safe from .store import async_load_from_store, async_save_to_store EXPORTED_BASE_DATA = ( ("new", False), ("full_name", ""), ) EXPORTED_REPOSITORY_DATA = EXPORTED_BASE_DATA + ( ("authors", []), ("category", ""), ("description", ""), ("domain", None), ("downloads", 0), ("etag_repository", None), ("hide", False), ("last_updated", 0), ("new", False), ("stargazers_count", 0), ("topics", []), ) EXPORTED_DOWNLOADED_REPOSITORY_DATA = EXPORTED_REPOSITORY_DATA + ( ("archived", False), ("config_flow", False), ("default_branch", None), ("first_install", False), ("installed_commit", None), ("installed", False), ("last_commit", None), ("last_version", None), ("manifest_name", None), ("open_issues", 0), ("prerelease", None), ("published_tags", []), ("releases", False), ("selected_tag", None), ("show_beta", False), ) class HacsData: """HacsData class.""" def __init__(self, hacs: HacsBase): """Initialize.""" self.logger = LOGGER self.hacs = hacs self.content = {} async def async_force_write(self, _=None): """Force write.""" await self.async_write(force=True) async def async_write(self, force: bool = False) -> None: """Write content to the store files.""" if not force and self.hacs.system.disabled: return self.logger.debug(" Saving data") # Hacs await async_save_to_store( self.hacs.hass, "hacs", { "archived_repositories": self.hacs.common.archived_repositories, "renamed_repositories": self.hacs.common.renamed_repositories, "ignored_repositories": self.hacs.common.ignored_repositories, }, ) await self._async_store_experimental_content_and_repos() await self._async_store_content_and_repos() async def _async_store_content_and_repos(self, _=None): # bb: ignore """Store the main repos file and each repo that is out of date.""" # Repositories self.content = {} for repository in self.hacs.repositories.list_all: if repository.data.category in self.hacs.common.categories: self.async_store_repository_data(repository) await async_save_to_store(self.hacs.hass, "repositories", self.content) for event in (HacsDispatchEvent.REPOSITORY, HacsDispatchEvent.CONFIG): self.hacs.async_dispatch(event, {}) async def _async_store_experimental_content_and_repos(self, _=None): """Store the main repos file and each repo that is out of date.""" # Repositories self.content = {} for repository in self.hacs.repositories.list_all: if repository.data.category in self.hacs.common.categories: self.async_store_experimental_repository_data(repository) await async_save_to_store(self.hacs.hass, "data", {"repositories": self.content}) @callback def async_store_repository_data(self, repository: HacsRepository) -> dict: """Store the repository data.""" data = {"repository_manifest": repository.repository_manifest.manifest} for key, default in ( EXPORTED_DOWNLOADED_REPOSITORY_DATA if repository.data.installed else EXPORTED_REPOSITORY_DATA ): if (value := getattr(repository.data, key, default)) != default: data[key] = value if repository.data.installed_version: data["version_installed"] = repository.data.installed_version if repository.data.last_fetched: data["last_fetched"] = repository.data.last_fetched.timestamp() self.content[str(repository.data.id)] = data @callback def async_store_experimental_repository_data(self, repository: HacsRepository) -> None: """Store the experimental repository data for non downloaded repositories.""" data = {} self.content.setdefault(repository.data.category, []) if repository.data.installed: data["repository_manifest"] = repository.repository_manifest.manifest for key, default in EXPORTED_DOWNLOADED_REPOSITORY_DATA: if (value := getattr(repository.data, key, default)) != default: data[key] = value if repository.data.installed_version: data["version_installed"] = repository.data.installed_version if repository.data.last_fetched: data["last_fetched"] = repository.data.last_fetched.timestamp() else: for key, default in EXPORTED_BASE_DATA: if (value := getattr(repository.data, key, default)) != default: data[key] = value self.content[repository.data.category].append({"id": str(repository.data.id), **data}) async def restore(self): """Restore saved data.""" self.hacs.status.new = False repositories = {} hacs = {} try: hacs = await async_load_from_store(self.hacs.hass, "hacs") or {} except HomeAssistantError: pass try: repositories = await async_load_from_store(self.hacs.hass, "repositories") if not repositories and (data := await async_load_from_store(self.hacs.hass, "data")): for category, entries in data.get("repositories", {}).items(): for repository in entries: repositories[repository["id"]] = {"category": category, **repository} except HomeAssistantError as exception: self.hacs.log.error( "Could not read %s, restore the file from a backup - %s", self.hacs.hass.config.path(".storage/hacs.data"), exception, ) self.hacs.disable_hacs(HacsDisabledReason.RESTORE) return False if not hacs and not repositories: # Assume new install self.hacs.status.new = True return True self.logger.info(" Restore started") # Hacs self.hacs.common.archived_repositories = set() self.hacs.common.ignored_repositories = set() self.hacs.common.renamed_repositories = {} # Clear out doubble renamed values renamed = hacs.get("renamed_repositories", {}) for entry in renamed: value = renamed.get(entry) if value not in renamed: self.hacs.common.renamed_repositories[entry] = value # Clear out doubble archived values for entry in hacs.get("archived_repositories", set()): if entry not in self.hacs.common.archived_repositories: self.hacs.common.archived_repositories.add(entry) # Clear out doubble ignored values for entry in hacs.get("ignored_repositories", set()): if entry not in self.hacs.common.ignored_repositories: self.hacs.common.ignored_repositories.add(entry) try: await self.register_unknown_repositories(repositories) for entry, repo_data in repositories.items(): if entry == "0": # Ignore repositories with ID 0 self.logger.debug( " Found repository with ID %s - %s", entry, repo_data ) continue self.async_restore_repository(entry, repo_data) self.logger.info(" Restore done") except ( # lgtm [py/catch-base-exception] pylint: disable=broad-except BaseException ) as exception: self.logger.critical( " [%s] Restore Failed!", exception, exc_info=exception ) return False return True async def register_unknown_repositories( self, repositories: dict[str, dict[str, Any]], category: str | None = None ): """Registry any unknown repositories.""" for repo_idx, (entry, repo_data) in enumerate(repositories.items()): # async_register_repository is awaited in a loop # since its unlikely to ever suspend at startup if ( entry == "0" or repo_data.get("category", category) is None or self.hacs.repositories.is_registered(repository_id=entry) ): continue await self.hacs.async_register_repository( repository_full_name=repo_data["full_name"], category=repo_data.get("category", category), check=False, repository_id=entry, ) if repo_idx % 100 == 0: # yield to avoid blocking the event loop await asyncio.sleep(0) @callback def async_restore_repository(self, entry: str, repository_data: dict[str, Any]): """Restore repository.""" repository: HacsRepository | None = None if full_name := repository_data.get("full_name"): repository = self.hacs.repositories.get_by_full_name(full_name) if not repository: repository = self.hacs.repositories.get_by_id(entry) if not repository: return try: self.hacs.repositories.set_repository_id(repository, entry) except ValueError as exception: self.logger.warning(" duplicate IDs %s", exception) return # Restore repository attributes repository.data.authors = repository_data.get("authors", []) repository.data.description = repository_data.get("description", "") repository.data.downloads = repository_data.get("downloads", 0) repository.data.last_updated = repository_data.get("last_updated", 0) if self.hacs.system.generator: repository.data.etag_releases = repository_data.get("etag_releases") repository.data.open_issues = repository_data.get("open_issues", 0) repository.data.etag_repository = repository_data.get("etag_repository") repository.data.topics = [ topic for topic in repository_data.get("topics", []) if topic not in TOPIC_FILTER ] repository.data.domain = repository_data.get("domain") repository.data.stargazers_count = repository_data.get( "stargazers_count" ) or repository_data.get("stars", 0) repository.releases.last_release = repository_data.get("last_release_tag") repository.data.releases = repository_data.get("releases", False) repository.data.installed = repository_data.get("installed", False) repository.data.new = repository_data.get("new", False) repository.data.selected_tag = repository_data.get("selected_tag") repository.data.show_beta = repository_data.get("show_beta", False) repository.data.last_version = repository_data.get("last_version") repository.data.prerelease = repository_data.get("prerelease") repository.data.last_commit = repository_data.get("last_commit") repository.data.installed_version = repository_data.get("version_installed") repository.data.installed_commit = repository_data.get("installed_commit") repository.data.manifest_name = repository_data.get("manifest_name") if last_fetched := repository_data.get("last_fetched"): repository.data.last_fetched = datetime.fromtimestamp(last_fetched, UTC) repository.repository_manifest = HacsManifest.from_dict( repository_data.get("manifest") or repository_data.get("repository_manifest") or {} ) if repository.data.prerelease == repository.data.last_version: repository.data.prerelease = None if repository.localpath is not None and is_safe(self.hacs, repository.localpath): # Set local path repository.content.path.local = repository.localpath if repository.data.installed: repository.data.first_install = False if entry == HACS_REPOSITORY_ID: repository.data.installed_version = self.hacs.version repository.data.installed = True ================================================ FILE: custom_components/hacs/utils/decode.py ================================================ """Util to decode content from the github API.""" from base64 import b64decode def decode_content(content: str) -> str: """Decode content.""" return b64decode(bytearray(content, "utf-8")).decode() ================================================ FILE: custom_components/hacs/utils/decorator.py ================================================ """HACS Decorators.""" from __future__ import annotations import asyncio from collections.abc import Coroutine from functools import wraps from typing import TYPE_CHECKING, Any from ..const import DEFAULT_CONCURRENT_BACKOFF_TIME, DEFAULT_CONCURRENT_TASKS if TYPE_CHECKING: from ..base import HacsBase def concurrent( concurrenttasks: int = DEFAULT_CONCURRENT_TASKS, backoff_time: int = DEFAULT_CONCURRENT_BACKOFF_TIME, ) -> Coroutine[Any, Any, None]: """Return a modified function.""" max_concurrent = asyncio.Semaphore(concurrenttasks) def inner_function(function) -> Coroutine[Any, Any, None]: @wraps(function) async def wrapper(*args, **kwargs) -> None: hacs: HacsBase = getattr(args[0], "hacs", None) async with max_concurrent: result = await function(*args, **kwargs) if ( hacs is None or hacs.queue is None or hacs.queue.has_pending_tasks or "update" not in function.__name__ ): await asyncio.sleep(backoff_time) return result return wrapper return inner_function def return_none_on_exception(func): """Decorator to return None on any exception, works for sync/async, methods/functions.""" @wraps(func) def sync_wrapper(*args, **kwargs): try: return func(*args, **kwargs) except Exception: # pylint: disable=broad-except return None @wraps(func) async def async_wrapper(*args, **kwargs): try: return await func(*args, **kwargs) except Exception: # pylint: disable=broad-except return None if asyncio.iscoroutinefunction(func): return async_wrapper return sync_wrapper ================================================ FILE: custom_components/hacs/utils/file_system.py ================================================ """File system functions.""" from __future__ import annotations import os import shutil from typing import TypeAlias from homeassistant.core import HomeAssistant # From typeshed StrOrBytesPath: TypeAlias = str | bytes | os.PathLike[str] | os.PathLike[bytes] FileDescriptorOrPath: TypeAlias = int | StrOrBytesPath async def async_exists(hass: HomeAssistant, path: FileDescriptorOrPath) -> bool: """Test whether a path exists.""" return await hass.async_add_executor_job(os.path.exists, path) async def async_remove( hass: HomeAssistant, path: StrOrBytesPath, *, missing_ok: bool = False ) -> None: """Remove a path.""" try: return await hass.async_add_executor_job(os.remove, path) except FileNotFoundError: if missing_ok: return raise async def async_remove_directory( hass: HomeAssistant, path: StrOrBytesPath, *, missing_ok: bool = False ) -> None: """Remove a directory.""" try: return await hass.async_add_executor_job(shutil.rmtree, path) except FileNotFoundError: if missing_ok: return raise ================================================ FILE: custom_components/hacs/utils/filters.py ================================================ """Filter functions.""" from __future__ import annotations from typing import Any def filter_content_return_one_of_type( content: list[str | Any], namestartswith: str, filterfiltype: str, attr: str = "name", ) -> list[str]: """Only match 1 of the filter.""" contents = [] filetypefound = False for filename in content: if isinstance(filename, str): if filename.startswith(namestartswith): if filename.endswith(f".{filterfiltype}"): if not filetypefound: contents.append(filename) filetypefound = True continue else: contents.append(filename) else: if getattr(filename, attr).startswith(namestartswith): if getattr(filename, attr).endswith(f".{filterfiltype}"): if not filetypefound: contents.append(filename) filetypefound = True continue else: contents.append(filename) return contents def get_first_directory_in_directory(content: list[str | Any], dirname: str) -> str | None: """Return the first directory in dirname or None.""" directory = None for path in content: if path.full_path.startswith(dirname) and path.full_path != dirname: if path.is_directory: directory = path.filename break return directory ================================================ FILE: custom_components/hacs/utils/github_graphql_query.py ================================================ """GitHub GraphQL Queries.""" GET_REPOSITORY_RELEASES = """ query ($owner: String!, $name: String!, $first: Int!) { rateLimit { cost } repository(owner: $owner, name: $name) { releases(first: $first, orderBy: {field: CREATED_AT, direction: DESC}) { nodes { tagName name isPrerelease publishedAt } } } } """ ================================================ FILE: custom_components/hacs/utils/json.py ================================================ """JSON utils.""" from homeassistant.util.json import json_loads __all__ = ["json_loads"] ================================================ FILE: custom_components/hacs/utils/logger.py ================================================ """Custom logger for HACS.""" import logging from ..const import PACKAGE_NAME LOGGER: logging.Logger = logging.getLogger(PACKAGE_NAME) ================================================ FILE: custom_components/hacs/utils/path.py ================================================ """Path utils""" from __future__ import annotations from functools import lru_cache from pathlib import Path from typing import TYPE_CHECKING if TYPE_CHECKING: from ..base import HacsBase @lru_cache(maxsize=1) def _get_safe_paths( config_path: str, appdaemon_path: str, plugin_path: str, python_script_path: str, theme_path: str, ) -> set[str]: """Get safe paths.""" return { Path(f"{config_path}/{appdaemon_path}").as_posix(), Path(f"{config_path}/{plugin_path}").as_posix(), Path(f"{config_path}/{python_script_path}").as_posix(), Path(f"{config_path}/{theme_path}").as_posix(), Path(f"{config_path}/custom_components/").as_posix(), Path(f"{config_path}/custom_templates/").as_posix(), } def is_safe(hacs: HacsBase, path: str | Path) -> bool: """Helper to check if path is safe to remove.""" configuration = hacs.configuration return Path(path).as_posix() not in _get_safe_paths( hacs.core.config_path, configuration.appdaemon_path, configuration.plugin_path, configuration.python_script_path, configuration.theme_path, ) ================================================ FILE: custom_components/hacs/utils/queue_manager.py ================================================ """The QueueManager class.""" from __future__ import annotations import asyncio from collections.abc import Coroutine import time from homeassistant.core import HomeAssistant from ..exceptions import HacsExecutionStillInProgress from .logger import LOGGER _LOGGER = LOGGER class QueueManager: """The QueueManager class.""" def __init__(self, hass: HomeAssistant) -> None: self.hass = hass self.queue: list[Coroutine] = [] self.running = False @property def pending_tasks(self) -> int: """Return a count of pending tasks in the queue.""" return len(self.queue) @property def has_pending_tasks(self) -> bool: """Return a count of pending tasks in the queue.""" return self.pending_tasks != 0 def clear(self) -> None: """Clear the queue.""" self.queue = [] def add(self, task: Coroutine) -> None: """Add a task to the queue.""" self.queue.append(task) async def execute(self, number_of_tasks: int | None = None) -> None: """Execute the tasks in the queue.""" if self.running: _LOGGER.debug(" Execution is already running") raise HacsExecutionStillInProgress if len(self.queue) == 0: _LOGGER.debug(" The queue is empty") return self.running = True _LOGGER.debug(" Checking out tasks to execute") local_queue = [] if number_of_tasks: for task in self.queue[:number_of_tasks]: local_queue.append(task) else: for task in self.queue: local_queue.append(task) _LOGGER.debug(" Starting queue execution for %s tasks", len(local_queue)) start = time.time() result = await asyncio.gather(*local_queue, return_exceptions=True) for entry in result: if isinstance(entry, Exception): _LOGGER.error(" %s", entry) end = time.time() - start for task in local_queue: self.queue.remove(task) _LOGGER.debug( " Queue execution finished for %s tasks finished in %.2f seconds", len(local_queue), end, ) if self.has_pending_tasks: _LOGGER.debug(" %s tasks remaining in the queue", len(self.queue)) self.running = False ================================================ FILE: custom_components/hacs/utils/regex.py ================================================ """Regex utils""" from __future__ import annotations import re RE_REPOSITORY = re.compile( r"(?:(?:.*github.com.)|^)([A-Za-z0-9-]+\/[\w.-]+?)(?:(?:\.git)?|(?:[^\w.-].*)?)$" ) def extract_repository_from_url(url: str) -> str | None: """Extract the owner/repo part form a URL.""" match = re.match(RE_REPOSITORY, url) if not match: return None return match.group(1).lower() ================================================ FILE: custom_components/hacs/utils/store.py ================================================ """Storage handers.""" from homeassistant.helpers.json import JSONEncoder from homeassistant.helpers.storage import Store from homeassistant.util import json as json_util from ..const import VERSION_STORAGE from ..exceptions import HacsException from .logger import LOGGER _LOGGER = LOGGER class HACSStore(Store): """A subclass of Store that allows multiple loads in the executor.""" def load(self): """Load the data from disk if version matches.""" try: data = json_util.load_json(self.path) except ( BaseException # lgtm [py/catch-base-exception] pylint: disable=broad-except ) as exception: _LOGGER.critical( "Could not load '%s', restore it from a backup or delete the file: %s", self.path, exception, ) raise HacsException(exception) from exception if data == {} or data["version"] != self.version: return None return data["data"] def get_store_key(key): """Return the key to use with homeassistant.helpers.storage.Storage.""" return key if "/" in key else f"hacs.{key}" def _get_store_for_key(hass, key, encoder): """Create a Store object for the key.""" return HACSStore(hass, VERSION_STORAGE, get_store_key(key), encoder=encoder, atomic_writes=True) def get_store_for_key(hass, key): """Create a Store object for the key.""" return _get_store_for_key(hass, key, JSONEncoder) async def async_load_from_store(hass, key): """Load the retained data from store and return de-serialized data.""" return await get_store_for_key(hass, key).async_load() or {} async def async_save_to_store(hass, key, data): """Generate dynamic data to store and save it to the filesystem. The data is only written if the content on the disk has changed by reading the existing content and comparing it. If the data has changed this will generate two executor jobs If the data has not changed this will generate one executor job """ current = await async_load_from_store(hass, key) if current is None or current != data: await get_store_for_key(hass, key).async_save(data) return _LOGGER.debug( " Did not store data for '%s'. Content did not change", get_store_key(key), ) async def async_remove_store(hass, key): """Remove a store element that should no longer be used.""" if "/" not in key: return await get_store_for_key(hass, key).async_remove() ================================================ FILE: custom_components/hacs/utils/url.py ================================================ """Various URL utils for HACS.""" import re from typing import Literal GIT_SHA = re.compile(r"^[a-fA-F0-9]{40}$") def github_release_asset( *, repository: str, version: str, filename: str, **_, ) -> str: """Generate a download URL for a release asset.""" return f"https://github.com/{repository}/releases/download/{version}/{filename}" def github_archive( *, repository: str, version: str, variant: Literal["heads", "tags"] = "heads", **_, ) -> str: """Generate a download URL for a repository zip.""" if GIT_SHA.match(version): return f"https://github.com/{repository}/archive/{version}.zip" return f"https://github.com/{repository}/archive/refs/{variant}/{version}.zip" ================================================ FILE: custom_components/hacs/utils/validate.py ================================================ """Validation utilities.""" from __future__ import annotations from collections.abc import Callable from dataclasses import dataclass, field from typing import Any from awesomeversion import AwesomeVersion from homeassistant.helpers.config_validation import url as url_validator import voluptuous as vol from ..const import LOCALE @dataclass class Validate: """Validate.""" errors: list[str] = field(default_factory=list) @property def success(self) -> bool: """Return bool if the validation was a success.""" return len(self.errors) == 0 def _country_validator(values) -> list[str]: """Custom country validator.""" countries = [] if isinstance(values, str): countries.append(values.upper()) elif isinstance(values, list): for value in values: countries.append(value.upper()) else: raise vol.Invalid(f"Value '{values}' is not a string or list.", path=["country"]) for country in countries: if country not in LOCALE: raise vol.Invalid(f"Value '{country}' is not in {LOCALE}.", path=["country"]) return countries HACS_MANIFEST_JSON_SCHEMA = vol.Schema( { vol.Optional("content_in_root"): bool, vol.Optional("country"): _country_validator, vol.Optional("filename"): str, vol.Optional("hacs"): str, vol.Optional("hide_default_branch"): bool, vol.Optional("homeassistant"): str, vol.Optional("persistent_directory"): str, vol.Optional("render_readme"): bool, vol.Optional("zip_release"): bool, vol.Required("name"): str, }, extra=vol.PREVENT_EXTRA, ) INTEGRATION_MANIFEST_JSON_SCHEMA = vol.Schema( { vol.Required("codeowners"): list, vol.Required("documentation"): url_validator, vol.Required("domain"): str, vol.Required("issue_tracker"): url_validator, vol.Required("name"): str, vol.Required("version"): vol.Coerce(AwesomeVersion), }, extra=vol.ALLOW_EXTRA, ) def validate_repo_data(schema: dict[str, Any], extra: int) -> Callable[[Any], Any]: """Return a validator for repo data. This is used instead of vol.All to always try both the repo schema and and the validate_version validator. """ _schema = vol.Schema(schema, extra=extra) def validate_repo_data(data: Any) -> Any: """Validate integration repo data.""" schema_errors: vol.MultipleInvalid | None = None try: _schema(data) except vol.MultipleInvalid as err: schema_errors = err try: validate_version(data) except vol.Invalid as err: if schema_errors: schema_errors.add(err) else: raise if schema_errors: raise schema_errors return data return validate_repo_data def validate_version(data: Any) -> Any: """Ensure at least one of last_commit or last_version is present.""" if "last_commit" not in data and "last_version" not in data: raise vol.Invalid("Expected at least one of [`last_commit`, `last_version`], got none") return data V2_COMMON_DATA_JSON_SCHEMA = { vol.Required("description"): vol.Any(str, None), vol.Optional("downloads"): int, vol.Optional("etag_releases"): str, vol.Required("etag_repository"): str, vol.Required("full_name"): str, vol.Optional("last_commit"): str, vol.Required("last_fetched"): vol.Any(int, float), vol.Required("last_updated"): str, vol.Optional("last_version"): str, vol.Optional("prerelease"): str, vol.Required("manifest"): { vol.Optional("country"): vol.Any([str], False), vol.Optional("name"): str, }, vol.Optional("open_issues"): int, vol.Optional("stargazers_count"): int, vol.Optional("topics"): [str], } V2_INTEGRATION_DATA_JSON_SCHEMA = { **V2_COMMON_DATA_JSON_SCHEMA, vol.Required("domain"): str, vol.Required("manifest_name"): str, } _V2_REPO_SCHEMAS = { "appdaemon": V2_COMMON_DATA_JSON_SCHEMA, "integration": V2_INTEGRATION_DATA_JSON_SCHEMA, "plugin": V2_COMMON_DATA_JSON_SCHEMA, "python_script": V2_COMMON_DATA_JSON_SCHEMA, "template": V2_COMMON_DATA_JSON_SCHEMA, "theme": V2_COMMON_DATA_JSON_SCHEMA, } # Used when validating repos in the hacs integration, discards extra keys VALIDATE_FETCHED_V2_REPO_DATA = { category: validate_repo_data(schema, vol.REMOVE_EXTRA) for category, schema in _V2_REPO_SCHEMAS.items() } # Used when validating repos when generating data, fails on extra keys VALIDATE_GENERATED_V2_REPO_DATA = { category: vol.Schema({str: validate_repo_data(schema, vol.PREVENT_EXTRA)}) for category, schema in _V2_REPO_SCHEMAS.items() } V2_CRITICAL_REPO_DATA_SCHEMA = { vol.Required("link"): str, vol.Required("reason"): str, vol.Required("repository"): str, } # Used when validating critical repos in the hacs integration, discards extra keys VALIDATE_FETCHED_V2_CRITICAL_REPO_SCHEMA = vol.Schema( V2_CRITICAL_REPO_DATA_SCHEMA, extra=vol.REMOVE_EXTRA, ) # Used when validating critical repos when generating data, fails on extra keys VALIDATE_GENERATED_V2_CRITICAL_REPO_SCHEMA = vol.Schema( [ vol.Schema( V2_CRITICAL_REPO_DATA_SCHEMA, extra=vol.PREVENT_EXTRA, ) ] ) V2_REMOVED_REPO_DATA_SCHEMA = { vol.Optional("link"): str, vol.Optional("reason"): str, vol.Required("removal_type"): vol.In( [ "Integration is missing a version, and is abandoned.", "Remove", "archived", "blacklist", "critical", "deprecated", "removal", "remove", "removed", "replaced", "repository", ] ), vol.Required("repository"): str, } # Used when validating removed repos in the hacs integration, discards extra keys VALIDATE_FETCHED_V2_REMOVED_REPO_SCHEMA = vol.Schema( V2_REMOVED_REPO_DATA_SCHEMA, extra=vol.REMOVE_EXTRA, ) # Used when validating removed repos when generating data, fails on extra keys VALIDATE_GENERATED_V2_REMOVED_REPO_SCHEMA = vol.Schema( [ vol.Schema( V2_REMOVED_REPO_DATA_SCHEMA, extra=vol.PREVENT_EXTRA, ) ] ) ================================================ FILE: custom_components/hacs/utils/version.py ================================================ """Version utils.""" from __future__ import annotations from functools import lru_cache from awesomeversion import ( AwesomeVersion, AwesomeVersionException, AwesomeVersionStrategy, ) @lru_cache(maxsize=1024) def version_left_higher_then_right(left: str, right: str) -> bool | None: """Return a bool if source is newer than target, will also be true if identical.""" try: left_version = AwesomeVersion(left) right_version = AwesomeVersion(right) if ( left_version.strategy != AwesomeVersionStrategy.UNKNOWN and right_version.strategy != AwesomeVersionStrategy.UNKNOWN ): return left_version > right_version except (AwesomeVersionException, AttributeError, KeyError): pass return None def version_left_higher_or_equal_then_right(left: str, right: str) -> bool: """Return a bool if source is newer than target, will also be true if identical.""" if left == right: return True return version_left_higher_then_right(left, right) ================================================ FILE: custom_components/hacs/utils/workarounds.py ================================================ """Workarounds.""" from homeassistant.core import HomeAssistant DOMAIN_OVERRIDES = { # https://github.com/hacs/integration/issues/2465 "custom-components/sensor.custom_aftership": "custom_aftership" } try: from homeassistant.components.http import StaticPathConfig async def async_register_static_path( hass: HomeAssistant, url_path: str, path: str, cache_headers: bool = True, ) -> None: """Register a static path with the HTTP component.""" await hass.http.async_register_static_paths( [StaticPathConfig(url_path, path, cache_headers)] ) except ImportError: async def async_register_static_path( hass: HomeAssistant, url_path: str, path: str, cache_headers: bool = True, ) -> None: """Register a static path with the HTTP component. Legacy: Can be removed when min version is 2024.7 https://developers.home-assistant.io/blog/2024/06/18/async_register_static_paths/ """ hass.http.register_static_path(url_path, path, cache_headers) ================================================ FILE: custom_components/hacs/validate/README.md ================================================ # Repository validation This is where the validation rules that run against the various repository categories live. ## Structure - There is one file pr. rule. - All rule needs tests to verify every possible outcome for the rule. - It's better with multiple files than a big rule. - All rules uses `ActionValidationBase` as the base class. - Only use `validate` or `async_validate` methods to define validation rules. - If a rule should fail, raise `ValidationException` with the failure message. ## Example ```python from .base import ( ActionValidationBase, ValidationBase, ValidationException, ) class SuperAwesomeRepository(ActionValidationBase): category = "integration" async def async_validate(self): if self.repository != "super-awesome": raise ValidationException("The repository is not super-awesome") ``` ================================================ FILE: custom_components/hacs/validate/__init__.py ================================================ """Initialize validation.""" ================================================ FILE: custom_components/hacs/validate/archived.py ================================================ from __future__ import annotations from typing import TYPE_CHECKING from .base import ActionValidationBase, ValidationException if TYPE_CHECKING: from ..repositories.base import HacsRepository async def async_setup_validator(repository: HacsRepository) -> Validator: """Set up this validator.""" return Validator(repository=repository) class Validator(ActionValidationBase): """Validate the repository.""" more_info = "https://hacs.xyz/docs/publish/include#check-archived" allow_fork = False async def async_validate(self) -> None: """Validate the repository.""" if self.repository.data.archived: raise ValidationException("The repository is archived") ================================================ FILE: custom_components/hacs/validate/base.py ================================================ """Base class for validation.""" from __future__ import annotations from typing import TYPE_CHECKING, Any from ..exceptions import HacsException if TYPE_CHECKING: from ..enums import HacsCategory from ..repositories.base import HacsRepository class ValidationException(HacsException): """Raise when there is a validation issue.""" class ActionValidationBase: """Base class for action validation.""" categories: tuple[HacsCategory, ...] = () allow_fork: bool = True more_info: str = "https://hacs.xyz/docs/publish/action" def __init__(self, repository: HacsRepository) -> None: self.hacs = repository.hacs self.repository = repository self.failed = False @property def slug(self) -> str: """Return the check slug.""" return self.__class__.__module__.rsplit(".", maxsplit=1)[-1] async def async_validate(self) -> None: """Validate the repository.""" async def execute_validation(self, *_: Any, **__: Any) -> None: """Execute the task defined in subclass.""" self.failed = False try: await self.async_validate() except ValidationException as exception: self.failed = True self.hacs.log.error( " failed: %s (More info: %s )", self.slug, exception, self.more_info, ) else: self.hacs.log.info(" completed", self.slug) ================================================ FILE: custom_components/hacs/validate/brands.py ================================================ from __future__ import annotations from typing import TYPE_CHECKING from custom_components.hacs.enums import HacsCategory from .base import ActionValidationBase, ValidationException if TYPE_CHECKING: from ..repositories.base import HacsRepository URL = "https://brands.home-assistant.io/domains.json" ASSET_FILENAME = "icon.png" async def async_setup_validator(repository: HacsRepository) -> Validator: """Set up this validator.""" return Validator(repository=repository) class Validator(ActionValidationBase): """Validate the repository.""" more_info = "https://hacs.xyz/docs/publish/include#check-brands" categories = (HacsCategory.INTEGRATION,) async def async_validate(self) -> None: """Validate the repository.""" treefiles = self.repository.treefiles if self.repository.repository_manifest.content_in_root: asset_path = f"brand/{ASSET_FILENAME}" else: asset_path = f"{self.repository.content.path.remote}/brand/{ASSET_FILENAME}" # Check if the integraiton provides local brand assets if asset_path in treefiles: self.repository.logger.debug("The repository contains brands assets at %s", asset_path) return self.repository.logger.warning( "The repository does not contain brands assets at %s. " "Falling back to checking the brands repository.", asset_path, ) # Fallback the checking the Home Assistant brands repository for the domain response = await self.hacs.session.get(URL) content = await response.json() if self.repository.data.domain not in content["custom"]: raise ValidationException( "The repository does not provide brand assets " "and is not listed in the Home Assistant brands repository." ) ================================================ FILE: custom_components/hacs/validate/description.py ================================================ from __future__ import annotations from typing import TYPE_CHECKING from .base import ActionValidationBase, ValidationException if TYPE_CHECKING: from ..repositories.base import HacsRepository async def async_setup_validator(repository: HacsRepository) -> Validator: """Set up this validator.""" return Validator(repository=repository) class Validator(ActionValidationBase): """Validate the repository.""" more_info = "https://hacs.xyz/docs/publish/include#check-repository" allow_fork = False async def async_validate(self) -> None: """Validate the repository.""" if not self.repository.data.description: raise ValidationException("The repository has no description") ================================================ FILE: custom_components/hacs/validate/hacsjson.py ================================================ from __future__ import annotations from voluptuous.error import Invalid from voluptuous.humanize import humanize_error from ..enums import HacsCategory, RepositoryFile from ..repositories.base import HacsManifest, HacsRepository from ..utils.validate import HACS_MANIFEST_JSON_SCHEMA from .base import ActionValidationBase, ValidationException async def async_setup_validator(repository: HacsRepository) -> Validator: """Set up this validator.""" return Validator(repository=repository) class Validator(ActionValidationBase): """Validate the repository.""" more_info = "https://hacs.xyz/docs/publish/include#check-hacs-manifest" async def async_validate(self) -> None: """Validate the repository.""" if RepositoryFile.HACS_JSON not in [x.filename for x in self.repository.tree]: raise ValidationException(f"The repository has no '{RepositoryFile.HACS_JSON}' file") rawhacsjson = await self.repository.get_hacs_json_raw(version=self.repository.ref) if rawhacsjson is None: raise ValidationException( f"The repository has an invalid '{RepositoryFile.HACS_JSON}' file" ) try: hacsjson = HacsManifest.from_dict(HACS_MANIFEST_JSON_SCHEMA(rawhacsjson)) except Invalid as exception: self.repository.logger.warning( "HACS JSON validation failed for: %s", rawhacsjson, ) raise ValidationException(humanize_error(rawhacsjson, exception)) from exception if self.repository.data.category == HacsCategory.INTEGRATION: if hacsjson.zip_release and not hacsjson.filename: raise ValidationException("zip_release is True, but filename is not set") ================================================ FILE: custom_components/hacs/validate/images.py ================================================ from __future__ import annotations from typing import TYPE_CHECKING from ..enums import HacsCategory from .base import ActionValidationBase, ValidationException if TYPE_CHECKING: from ..repositories.base import HacsRepository IGNORED = ["-shield", "img.shields.io", "buymeacoffee.com"] async def async_setup_validator(repository: HacsRepository) -> Validator: """Set up this validator.""" return Validator(repository=repository) class Validator(ActionValidationBase): """Validate the repository.""" categories = (HacsCategory.PLUGIN, HacsCategory.THEME) more_info = "https://hacs.xyz/docs/publish/include#check-images" async def async_validate(self) -> None: """Validate the repository.""" info = await self.repository.async_get_info_file_contents(version=self.repository.ref) for line in info.split("\n"): if " Validator: """Set up this validator.""" return Validator(repository=repository) class Validator(ActionValidationBase): """Validate the repository.""" more_info = "https://hacs.xyz/docs/publish/include#check-info" async def async_validate(self) -> None: """Validate the repository.""" filenames = [x.filename.lower() for x in self.repository.tree] if "readme" in filenames: pass elif "readme.md" in filenames: pass elif "info" in filenames: pass elif "info.md" in filenames: pass else: raise ValidationException("The repository has no information file") ================================================ FILE: custom_components/hacs/validate/integration_manifest.py ================================================ from __future__ import annotations from typing import TYPE_CHECKING from voluptuous.error import Invalid from voluptuous.humanize import humanize_error from ..enums import HacsCategory, RepositoryFile from ..utils.validate import INTEGRATION_MANIFEST_JSON_SCHEMA from .base import ActionValidationBase, ValidationException if TYPE_CHECKING: from ..repositories.base import HacsRepository from ..repositories.integration import HacsIntegrationRepository async def async_setup_validator(repository: HacsRepository) -> Validator: """Set up this validator.""" return Validator(repository=repository) class Validator(ActionValidationBase): """Validate the repository.""" repository: HacsIntegrationRepository more_info = "https://hacs.xyz/docs/publish/include#check-manifest" categories = (HacsCategory.INTEGRATION,) async def async_validate(self) -> None: """Validate the repository.""" if RepositoryFile.MAINIFEST_JSON not in [x.filename for x in self.repository.tree]: raise ValidationException( f"The repository has no '{RepositoryFile.MAINIFEST_JSON}' file" ) content = await self.repository.get_integration_manifest(version=self.repository.ref) try: INTEGRATION_MANIFEST_JSON_SCHEMA(content) except Invalid as exception: self.repository.logger.warning( "Integration manifest validation failed for: %s", content ) raise ValidationException(humanize_error(content, exception)) from exception ================================================ FILE: custom_components/hacs/validate/issues.py ================================================ from __future__ import annotations from typing import TYPE_CHECKING from .base import ActionValidationBase, ValidationException if TYPE_CHECKING: from ..repositories.base import HacsRepository async def async_setup_validator(repository: HacsRepository) -> Validator: """Set up this validator.""" return Validator(repository=repository) class Validator(ActionValidationBase): """Validate the repository.""" more_info = "https://hacs.xyz/docs/publish/include#check-repository" allow_fork = False async def async_validate(self) -> None: """Validate the repository.""" if not self.repository.data.has_issues: raise ValidationException("The repository does not have issues enabled") ================================================ FILE: custom_components/hacs/validate/manager.py ================================================ """Hacs validation manager.""" from __future__ import annotations import asyncio from importlib import import_module import os from pathlib import Path from typing import TYPE_CHECKING if TYPE_CHECKING: from homeassistant.core import HomeAssistant from ..base import HacsBase from ..repositories.base import HacsRepository from .base import ActionValidationBase class ValidationManager: """Hacs validation manager.""" def __init__(self, hacs: HacsBase, hass: HomeAssistant) -> None: """Initialize the setup manager class.""" self.hacs = hacs self.hass = hass self._validators: dict[str, ActionValidationBase] = {} @property def validators(self) -> list[ActionValidationBase]: """Return all list of all tasks.""" return list(self._validators.values()) async def async_load(self, repository: HacsRepository) -> None: """Load all tasks.""" self._validators = {} validator_files = Path(__file__).parent validator_modules = ( module.stem for module in validator_files.glob("*.py") if module.name not in ("base.py", "__init__.py", "manager.py") ) async def _load_module(module: str) -> None: task_module = import_module(f"{__package__}.{module}") if task := await task_module.async_setup_validator(repository=repository): self._validators[task.slug] = task await asyncio.gather(*[_load_module(task) for task in validator_modules]) async def async_run_repository_checks(self, repository: HacsRepository) -> None: """Run all validators for a repository.""" if not self.hacs.system.action: return await self.async_load(repository) is_pull_from_fork = ( not os.getenv("INPUT_REPOSITORY") and os.getenv("GITHUB_REPOSITORY") != repository.data.full_name ) validators = [ validator for validator in self.validators or [] if ( (not validator.categories or repository.data.category in validator.categories) and validator.slug not in os.getenv("INPUT_IGNORE", "").split(" ") and (not is_pull_from_fork or validator.allow_fork) ) ] await asyncio.gather(*[validator.execute_validation() for validator in validators]) total = len(validators) failed = len([x for x in validators if x.failed]) if failed != 0: repository.logger.error("%s %s/%s checks failed", repository.string, failed, total) exit(1) else: repository.logger.info("%s All (%s) checks passed", repository.string, total) ================================================ FILE: custom_components/hacs/validate/topics.py ================================================ from __future__ import annotations from typing import TYPE_CHECKING from .base import ActionValidationBase, ValidationException if TYPE_CHECKING: from ..repositories.base import HacsRepository async def async_setup_validator(repository: HacsRepository) -> Validator: """Set up this validator.""" return Validator(repository=repository) class Validator(ActionValidationBase): """Validate the repository.""" more_info = "https://hacs.xyz/docs/publish/include#check-repository" allow_fork = False async def async_validate(self) -> None: """Validate the repository.""" if not self.repository.data.topics: raise ValidationException("The repository has no valid topics") ================================================ FILE: custom_components/hacs/websocket/__init__.py ================================================ """Register_commands.""" from __future__ import annotations from typing import TYPE_CHECKING, Any from homeassistant.components import websocket_api from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.dispatcher import async_dispatcher_connect import voluptuous as vol from ..const import DOMAIN from .critical import hacs_critical_acknowledge, hacs_critical_list from .repositories import ( hacs_repositories_add, hacs_repositories_clear_new, hacs_repositories_list, hacs_repositories_remove, hacs_repositories_removed, ) from .repository import ( hacs_repository_beta, hacs_repository_download, hacs_repository_ignore, hacs_repository_info, hacs_repository_refresh, hacs_repository_release_notes, hacs_repository_releases, hacs_repository_remove, hacs_repository_state, hacs_repository_version, ) if TYPE_CHECKING: from ..base import HacsBase @callback def async_register_websocket_commands(hass: HomeAssistant) -> None: """Register_commands.""" websocket_api.async_register_command(hass, hacs_info) websocket_api.async_register_command(hass, hacs_subscribe) websocket_api.async_register_command(hass, hacs_repository_info) websocket_api.async_register_command(hass, hacs_repository_download) websocket_api.async_register_command(hass, hacs_repository_ignore) websocket_api.async_register_command(hass, hacs_repository_state) websocket_api.async_register_command(hass, hacs_repository_version) websocket_api.async_register_command(hass, hacs_repository_beta) websocket_api.async_register_command(hass, hacs_repository_refresh) websocket_api.async_register_command(hass, hacs_repository_release_notes) websocket_api.async_register_command(hass, hacs_repository_remove) websocket_api.async_register_command(hass, hacs_critical_acknowledge) websocket_api.async_register_command(hass, hacs_critical_list) websocket_api.async_register_command(hass, hacs_repositories_list) websocket_api.async_register_command(hass, hacs_repositories_add) websocket_api.async_register_command(hass, hacs_repositories_clear_new) websocket_api.async_register_command(hass, hacs_repositories_removed) websocket_api.async_register_command(hass, hacs_repositories_remove) websocket_api.async_register_command(hass, hacs_repository_releases) @websocket_api.websocket_command( { vol.Required("type"): "hacs/subscribe", vol.Required("signal"): str, } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_subscribe( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict, ) -> None: """Handle websocket subscriptions.""" @callback def forward_messages(data: dict | None = None) -> None: """Forward events to websocket.""" connection.send_message(websocket_api.event_message(msg["id"], data)) connection.subscriptions[msg["id"]] = async_dispatcher_connect( hass, msg["signal"], forward_messages, ) connection.send_message(websocket_api.result_message(msg["id"])) @websocket_api.websocket_command( { vol.Required("type"): "hacs/info", } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_info( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """Return information about HACS.""" hacs: HacsBase = hass.data.get(DOMAIN) connection.send_message( websocket_api.result_message( msg["id"], { "categories": hacs.common.categories, "country": hacs.configuration.country, "debug": hacs.configuration.debug, "dev": hacs.configuration.dev, "disabled_reason": hacs.system.disabled_reason, "has_pending_tasks": hacs.queue.has_pending_tasks, "lovelace_mode": hacs.core.lovelace_mode, "stage": hacs.stage, "startup": hacs.status.startup, "version": hacs.version, }, ) ) ================================================ FILE: custom_components/hacs/websocket/critical.py ================================================ """Register info websocket commands.""" from __future__ import annotations from typing import TYPE_CHECKING, Any from homeassistant.components import websocket_api import homeassistant.helpers.config_validation as cv import voluptuous as vol from ..utils.store import async_load_from_store, async_save_to_store if TYPE_CHECKING: from homeassistant.core import HomeAssistant @websocket_api.websocket_command( { vol.Required("type"): "hacs/critical/list", } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_critical_list( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """List critical repositories.""" connection.send_message( websocket_api.result_message( msg["id"], (await async_load_from_store(hass, "critical") or []), ) ) @websocket_api.websocket_command( { vol.Required("type"): "hacs/critical/acknowledge", vol.Optional("repository"): cv.string, } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_critical_acknowledge( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """Acknowledge critical repository.""" repository = msg["repository"] critical = await async_load_from_store(hass, "critical") for repo in critical: if repository == repo["repository"]: repo["acknowledged"] = True await async_save_to_store(hass, "critical", critical) connection.send_message(websocket_api.result_message(msg["id"], critical)) ================================================ FILE: custom_components/hacs/websocket/repositories.py ================================================ """Register info websocket commands.""" from __future__ import annotations import sys from typing import TYPE_CHECKING, Any from homeassistant.components import websocket_api import homeassistant.helpers.config_validation as cv import voluptuous as vol from custom_components.hacs.utils import regex from ..const import DOMAIN from ..enums import HacsDispatchEvent if TYPE_CHECKING: from homeassistant.core import HomeAssistant from ..base import HacsBase @websocket_api.websocket_command( { vol.Required("type"): "hacs/repositories/list", vol.Optional("categories"): [str], } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_repositories_list( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """List repositories.""" hacs: HacsBase = hass.data.get(DOMAIN) connection.send_message( websocket_api.result_message( msg["id"], [ { "authors": repo.data.authors, "available_version": repo.display_available_version, "installed_version": repo.display_installed_version, "config_flow": repo.data.config_flow, "can_download": repo.can_download, "category": repo.data.category, "country": repo.repository_manifest.country, "custom": not hacs.repositories.is_default(str(repo.data.id)), "description": repo.data.description, "domain": repo.data.domain, "downloads": repo.data.downloads, "file_name": repo.data.file_name, "full_name": repo.data.full_name, "hide": repo.data.hide, "homeassistant": repo.repository_manifest.homeassistant, "id": repo.data.id, "installed": repo.data.installed, "last_updated": repo.data.last_updated, "local_path": repo.content.path.local, "name": repo.display_name, "new": repo.data.new, "pending_upgrade": repo.pending_update, "stars": repo.data.stargazers_count, "state": repo.state, "status": repo.display_status, "topics": repo.data.topics, } for repo in hacs.repositories.list_all if repo.data.category in msg.get("categories", hacs.common.categories) and not repo.ignored_by_country_configuration and repo.data.last_fetched ], ) ) @websocket_api.websocket_command( { vol.Required("type"): "hacs/repositories/clear_new", vol.Optional("categories"): cv.ensure_list, vol.Optional("repository"): cv.string, } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_repositories_clear_new( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """Clear new repositories for specific categories.""" hacs: HacsBase = hass.data.get(DOMAIN) if repo := msg.get("repository"): repository = hacs.repositories.get_by_id(repo) repository.data.new = False else: for repo in hacs.repositories.list_all: if repo.data.new and repo.data.category in msg.get("categories", []): hacs.log.debug( "Clearing new flag from '%s'", repo.data.full_name, ) repo.data.new = False hacs.async_dispatch(HacsDispatchEvent.REPOSITORY, {}) await hacs.data.async_write() connection.send_message(websocket_api.result_message(msg["id"])) @websocket_api.websocket_command( { vol.Required("type"): "hacs/repositories/removed", } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_repositories_removed( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """Get information about removed repositories.""" hacs: HacsBase = hass.data.get(DOMAIN) content = [] for repo in hacs.repositories.list_removed: if repo.repository not in hacs.common.ignored_repositories: content.append(repo.to_json()) connection.send_message(websocket_api.result_message(msg["id"], content)) @websocket_api.websocket_command( { vol.Required("type"): "hacs/repositories/add", vol.Required("repository"): cv.string, vol.Required("category"): vol.Lower, } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_repositories_add( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """Add custom repositoriy.""" hacs: HacsBase = hass.data.get(DOMAIN) repository = regex.extract_repository_from_url(msg["repository"]) category = msg["category"] if repository is None: return if repository in hacs.common.skip: hacs.common.skip.remove(repository) if renamed := hacs.common.renamed_repositories.get(repository): repository = renamed if category not in hacs.common.categories: hacs.log.error("%s is not a valid category for %s", category, repository) elif not hacs.repositories.get_by_full_name(repository): try: await hacs.async_register_repository( repository_full_name=repository, category=category, ) except ( BaseException # lgtm [py/catch-base-exception] pylint: disable=broad-except ) as exception: hacs.async_dispatch( HacsDispatchEvent.ERROR, { "action": "add_repository", "exception": str(sys.exc_info()[0].__name__), "message": str(exception), }, ) else: hacs.async_dispatch( HacsDispatchEvent.ERROR, { "action": "add_repository", "message": f"Repository '{repository}' exists in the store.", }, ) connection.send_message(websocket_api.result_message(msg["id"], {})) @websocket_api.websocket_command( { vol.Required("type"): "hacs/repositories/remove", vol.Required("repository"): cv.string, } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_repositories_remove( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """Remove custom repositoriy.""" hacs: HacsBase = hass.data.get(DOMAIN) repository = hacs.repositories.get_by_id(msg["repository"]) repository.remove() await hacs.data.async_write() connection.send_message(websocket_api.result_message(msg["id"], {})) ================================================ FILE: custom_components/hacs/websocket/repository.py ================================================ """Register info websocket commands.""" from __future__ import annotations from typing import TYPE_CHECKING, Any from homeassistant.components import websocket_api import homeassistant.helpers.config_validation as cv import voluptuous as vol from ..const import DOMAIN from ..enums import HacsDispatchEvent from ..exceptions import HacsException from ..utils.version import version_left_higher_then_right if TYPE_CHECKING: from homeassistant.core import HomeAssistant from ..base import HacsBase @websocket_api.websocket_command( { vol.Required("type"): "hacs/repository/info", vol.Required("repository_id"): str, } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_repository_info( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """Return information about a repository.""" hacs: HacsBase = hass.data.get(DOMAIN) repository_id = msg["repository_id"] repository = hacs.repositories.get_by_id(repository_id) if repository is None: connection.send_error( msg["id"], "repository_not_found", f"Repository with ID ({repository_id}) not found", ) return if not repository.updated_info: try: await repository.update_repository(ignore_issues=True, force=True) except Exception as exception: # pylint: disable=broad-except repository.logger.error("%s %s", repository.string, exception) repository.updated_info = True if repository.data.new: repository.data.new = False await hacs.data.async_write() connection.send_message( websocket_api.result_message( msg["id"], { "additional_info": repository.additional_info, "authors": repository.data.authors, "available_version": repository.display_available_version, "beta": repository.data.show_beta, "can_download": repository.can_download, "category": repository.data.category, "config_flow": repository.data.config_flow, "country": repository.repository_manifest.country, "custom": not hacs.repositories.is_default(str(repository.data.id)), "default_branch": repository.data.default_branch, "description": repository.data.description, "domain": repository.data.domain, "downloads": repository.data.downloads, "file_name": repository.data.file_name, "full_name": repository.data.full_name, "hide_default_branch": repository.repository_manifest.hide_default_branch, "homeassistant": repository.repository_manifest.homeassistant, "id": repository.data.id, "installed_version": repository.display_installed_version, "installed": repository.data.installed, "issues": repository.data.open_issues, "last_updated": repository.data.last_updated, "local_path": repository.content.path.local, "name": repository.display_name, "new": False, "pending_upgrade": repository.pending_update, "releases": repository.data.published_tags, "ref": repository.ref, "selected_tag": repository.data.selected_tag, "stars": repository.data.stargazers_count, "state": repository.state, "status": repository.display_status, "topics": repository.data.topics, "version_or_commit": repository.display_version_or_commit, }, ) ) @websocket_api.websocket_command( { vol.Required("type"): "hacs/repository/ignore", vol.Required("repository"): str, } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_repository_ignore( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """Ignore a repository.""" hacs: HacsBase = hass.data.get(DOMAIN) repository_id = msg["repository"] hacs.log.info("Ignoring %s", repository_id) repository = hacs.repositories.get_by_id(repository_id) if repository is None: connection.send_error( msg["id"], "repository_not_found", f"Repository with ID ({repository_id}) not found", ) return hacs.common.ignored_repositories.add(repository.data.full_name) await hacs.data.async_write() connection.send_message(websocket_api.result_message(msg["id"])) @websocket_api.websocket_command( { vol.Required("type"): "hacs/repository/state", vol.Required("repository"): cv.string, vol.Required("state"): cv.string, } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_repository_state( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """Set the state of a repository""" hacs: HacsBase = hass.data.get(DOMAIN) repository = hacs.repositories.get_by_id(msg["repository"]) repository.state = msg["state"] await hacs.data.async_write() connection.send_message(websocket_api.result_message(msg["id"], {})) @websocket_api.websocket_command( { vol.Required("type"): "hacs/repository/version", vol.Required("repository"): cv.string, vol.Required("version"): cv.string, } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_repository_version( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """Set the version of a repository""" hacs: HacsBase = hass.data.get(DOMAIN) repository = hacs.repositories.get_by_id(msg["repository"]) if msg["version"] == repository.data.default_branch: repository.data.selected_tag = None else: repository.data.selected_tag = msg["version"] await repository.update_repository(force=True) repository.state = None await hacs.data.async_write() connection.send_message(websocket_api.result_message(msg["id"], {})) @websocket_api.websocket_command( { vol.Required("type"): "hacs/repository/beta", vol.Required("repository"): cv.string, vol.Required("show_beta"): cv.boolean, } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_repository_beta( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """Show or hide beta versions of a repository""" hacs: HacsBase = hass.data.get(DOMAIN) repository = hacs.repositories.get_by_id(msg["repository"]) repository.data.show_beta = msg["show_beta"] await repository.update_repository(force=True) repository.state = None await hacs.data.async_write() connection.send_message(websocket_api.result_message(msg["id"], {})) @websocket_api.websocket_command( { vol.Required("type"): "hacs/repository/download", vol.Required("repository"): cv.string, vol.Optional("version"): cv.string, } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_repository_download( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """Set the version of a repository""" hacs: HacsBase = hass.data.get(DOMAIN) repository = hacs.repositories.get_by_id(msg["repository"]) try: was_installed = repository.data.installed await repository.async_download_repository(ref=msg.get("version")) if not was_installed: hacs.async_dispatch(HacsDispatchEvent.RELOAD, {"force": True}) await hacs.async_recreate_entities() await hacs.data.async_write() connection.send_message(websocket_api.result_message(msg["id"], {})) except HacsException as exception: repository.logger.error("%s %s", repository.string, exception) connection.send_error(msg["id"], "error", str(exception)) @websocket_api.websocket_command( { vol.Required("type"): "hacs/repository/remove", vol.Required("repository"): cv.string, } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_repository_remove( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """Remove a repository.""" hacs: HacsBase = hass.data.get(DOMAIN) repository = hacs.repositories.get_by_id(msg["repository"]) repository.data.new = False try: await repository.update_repository(ignore_issues=True, force=True) except Exception as exception: # pylint: disable=broad-except repository.logger.error("%s %s", repository.string, exception) await repository.uninstall() await hacs.data.async_write() connection.send_message(websocket_api.result_message(msg["id"], {})) @websocket_api.websocket_command( { vol.Required("type"): "hacs/repository/refresh", vol.Required("repository"): cv.string, } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_repository_refresh( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """Refresh a repository.""" hacs: HacsBase = hass.data.get(DOMAIN) repository = hacs.repositories.get_by_id(msg["repository"]) await repository.update_repository(ignore_issues=True, force=True) await hacs.data.async_write() # Update state of update entity hacs.coordinators[repository.data.category].async_update_listeners() connection.send_message(websocket_api.result_message(msg["id"], {})) @websocket_api.websocket_command( { vol.Required("type"): "hacs/repository/release_notes", vol.Required("repository"): cv.string, } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_repository_release_notes( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """Return release notes.""" hacs: HacsBase = hass.data.get(DOMAIN) repository = hacs.repositories.get_by_id(msg["repository"]) connection.send_message( websocket_api.result_message( msg["id"], [ { "name": x.name, "body": x.body, "tag": x.tag_name, } for x in repository.releases.objects if not repository.data.installed_version or version_left_higher_then_right(x.tag_name, repository.data.installed_version) ], ) ) @websocket_api.websocket_command( { vol.Required("type"): "hacs/repository/releases", vol.Required("repository_id"): cv.string, } ) @websocket_api.require_admin @websocket_api.async_response async def hacs_repository_releases( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict[str, Any], ) -> None: """Return releases.""" hacs: HacsBase = hass.data.get(DOMAIN) repository = hacs.repositories.get_by_id(msg["repository_id"]) try: releases = await repository.async_get_releases() except Exception as exception: hacs.log.exception(exception) connection.send_error(msg["id"], "unknown", str(exception)) return connection.send_message( websocket_api.result_message( msg["id"], [ { "name": release.name, "tag": release.tag_name, "published_at": release.published_at, "prerelease": release.prerelease, } for release in releases ], ) ) ================================================ FILE: hacs.json ================================================ { "name": "HACS", "zip_release": true, "hide_default_branch": true, "homeassistant": "2025.3.0", "hacs": "0.19.0", "filename": "hacs.zip" } ================================================ FILE: info.md ================================================ ## Useful links - [General documentation](https://hacs.xyz/) - [Configuration](https://hacs.xyz/docs/configuration/basic) - [FAQ](https://hacs.xyz/docs/faq) - [GitHub](https://github.com/hacs) - [Discord](https://discord.gg/apgchf8) - [Become a GitHub sponsor? ❤️](https://github.com/sponsors/ludeeus) - [BuyMe~~Coffee~~Beer? 🍺🙈](https://buymeacoffee.com/ludeeus) ================================================ FILE: pyproject.toml ================================================ [tool.isort] # https://github.com/PyCQA/isort/wiki/isort-Settings profile = "black" # will group `import x` and `from x import` of the same module. force_sort_within_sections = true known_first_party = [ "custom_components", "tests", ] forced_separate = [ "tests", ] combine_as_imports = true [tool.pytest.ini_options] asyncio_mode="auto" addopts = "-rxf -l --cov=./ --cov-report=xml" filterwarnings = [ "ignore::DeprecationWarning", "ignore:It is recommended to use web.AppKey instances for keys" ] log_format = "%(asctime)s.%(msecs)03d %(levelname)-8s %(threadName)s %(name)s:%(filename)s:%(lineno)s %(message)s" log_date_format = "%Y-%m-%d %H:%M:%S" testpaths = [ "tests", ] python_files = [ "test_*.py", ] norecursedirs = [ ".git", ] [tool.ruff] fix = true line-length = 100 show-fixes = true target-version = "py312" [tool.ruff.lint] select = ["ALL"] ignore = [ "ANN001", "ANN002", "ANN003", "ANN201", "ANN202", "ANN204", "ANN205", "ANN401", "ARG001", "ARG002", "ARG005", "ASYNC110", "ASYNC240", "BLE001", "C901", "COM812", "D100", "D101", "D102", "D103", "D105", "D107", "D202", "D203", "D205", "D213", "D400", "D401", "D415", "E501", "E713", "EM101", "EM102", "F401", "FBT001", "FBT002", "FBT003", "I001", "INP001", "ISC001", "N812", "N818", "PLC0206", "PLC0207", "PLC0415", "PLR0911", "PERF401", "PERF402", "PIE804", "PLR0912", "PLR0913", "PLR0915", "PLR1714", "PLR1722", "PLR2004", "PLR5501", "PTH103", "PTH107", "PTH110", "PTH113", "PTH123", "RET502", "RET503", "RET504", "RET507", "RSE102", "RUF005", "RUF008", "RUF012", "RUF013", "S105", "S110", "SIM102", "SIM103", "SIM105", "SIM108", "SIM110", "SIM114", "SIM117", "SLF001", "TC001", "TC002", "TC003", "TID252", "TRY003", "TRY201", "TRY300", "TRY301", "TRY400", "TRY401", "UP040" ] fixable = ["ALL"] unfixable = [] [tool.ruff.lint.isort] combine-as-imports = true force-sort-within-sections = true known-first-party = [ "custom_components.hacs", ] ================================================ FILE: requirements_action.txt ================================================ aiogithubapi==26.0.0 homeassistant==2025.11.3 # https://github.com/aio-libs/aiodns/issues/214 pycares<5 ================================================ FILE: requirements_base.txt ================================================ aiogithubapi>=21.11.0 aiohttp>=3.8.3,<4.0 aiohttp_cors==0.7.0 async-timeout>=4.0.2 asynctest==0.13.0 colorlog==6.10.1 setuptools==82.0.1 ================================================ FILE: requirements_core_min.txt ================================================ # https://github.com/home-assistant/core/blob/2025.3.0/homeassistant/components/frontend/manifest.json home-assistant-frontend==20250305.0 homeassistant==2025.3.0 ================================================ FILE: requirements_generate_data.txt ================================================ --requirement requirements_base.txt awscli==1.44.58 homeassistant==2025.3.0 # https://github.com/aio-libs/aiodns/issues/214 pycares<5 ================================================ FILE: requirements_lint.txt ================================================ --requirement requirements_base.txt codespell==2.4.2 isort==8.0.1 pre-commit==4.5.1 pre-commit-hooks==6.0.0 pyupgrade==3.21.2 ruff==0.15.6 vulture==2.15 ================================================ FILE: requirements_test.txt ================================================ --requirement requirements_base.txt asynctest==0.13.0 freezegun==1.5.5 josepy<3 # https://github.com/aio-libs/aiodns/issues/214 pycares<5 pytest==8.4.2 pytest-asyncio==0.26.0 pytest-cov==7.0.0 pytest-snapshot==0.9.0 pytest-socket==0.7.0 RestrictedPython==8.1 ================================================ FILE: scripts/__init__.py ================================================ """HACS Script.""" ================================================ FILE: scripts/clear_storage ================================================ #!/usr/bin/env bash set -e cd "$(dirname "$0")/.." rm -rf config/.storage/hacs rm -f config/.storage/hacs* ================================================ FILE: scripts/coverage ================================================ #!/usr/bin/env bash set -e cd "$(dirname "$0")/.." bash scripts/test > /dev/null python3 -m \ coverage \ report \ --skip-covered ================================================ FILE: scripts/data/__init__.py ================================================ """HACS Data script.""" ================================================ FILE: scripts/data/common.py ================================================ """Common helpers for data.""" from __future__ import annotations import sys from typing import Any import voluptuous as vol def expand_and_humanize_error(content: dict[str, Any], error: vol.Invalid) -> list[str] | str: """Expand and humanize error.""" if isinstance(error, vol.MultipleInvalid): return sorted(expand_and_humanize_error(content, sub_error) for sub_error in error.errors) repoid = error.path[0] return f"[{content[repoid].get('full_name', repoid)}] {vol.humanize.humanize_error(content, error)}" def print_error_and_exit(err: str, category: str, target_path: str | None = None): if target_path: print(f"::error::{err} for the {category} category in {target_path}") else: print(f"::error::{err} for the {category} category") sys.exit(1) ================================================ FILE: scripts/data/generate_category_data.py ================================================ """Generate HACS compliant data.""" from __future__ import annotations import asyncio from datetime import datetime import json import logging import os import sys from typing import Any, Literal from aiogithubapi import ( GitHub, GitHubAPI, GitHubException, GitHubNotFoundException, GitHubNotModifiedException, GitHubReleaseModel, ) from aiohttp import ClientSession from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.json import JSONEncoder import voluptuous as vol from custom_components.hacs.base import HacsBase, HacsRepositories from custom_components.hacs.const import HACS_ACTION_GITHUB_API_HEADERS from custom_components.hacs.data_client import HacsDataClient from custom_components.hacs.enums import HacsGitHubRepo from custom_components.hacs.exceptions import HacsExecutionStillInProgress from custom_components.hacs.repositories.base import ( HACS_MANIFEST_KEYS_TO_EXPORT, REPOSITORY_KEYS_TO_EXPORT, HacsRepository, ) from custom_components.hacs.utils.data import HacsData from custom_components.hacs.utils.decode import decode_content from custom_components.hacs.utils.decorator import concurrent from custom_components.hacs.utils.json import json_loads from custom_components.hacs.utils.queue_manager import QueueManager from custom_components.hacs.utils.validate import VALIDATE_GENERATED_V2_REPO_DATA from .common import expand_and_humanize_error, print_error_and_exit logging.addLevelName(logging.DEBUG, "") logging.addLevelName(logging.INFO, "") logging.addLevelName(logging.ERROR, "::error::") logging.addLevelName(logging.WARNING, "::warning::") log_handler = logging.getLogger("custom_components.hacs") log_handler.setLevel(logging.DEBUG) stream_handler = logging.StreamHandler(sys.stdout) stream_handler.setLevel(logging.DEBUG) stream_handler.setFormatter(logging.Formatter("%(levelname)s%(message)s")) log_handler.addHandler(stream_handler) OUTPUT_DIR = os.path.join(os.getcwd(), "outputdata") COMPARE_IGNORE = {"etag_releases", "etag_repository", "last_fetched"} def jsonprint(data: any): print( json.dumps( data, cls=JSONEncoder, sort_keys=True, indent=2, ) ) def dicts_are_equal(a: dict, b: dict, ignore: set[str]) -> bool: def _dumper(obj: dict): return json.dumps( {k: v for k, v in obj.items() if k not in ignore}, sort_keys=True, cls=JSONEncoder, ) return _dumper(a) == _dumper(b) def repository_has_missing_keys( repository: HacsRepository, stage: Literal["update", "store"], ) -> bool: """Check if repository has missing keys.""" retval = False def _do_log(msg: str) -> None: repository.logger.log( logging.WARNING if stage == "update" else logging.ERROR, "%s[%s] %s", repository.string, stage, msg, ) if repository.data.last_commit is None and repository.data.last_version is None: retval = True _do_log("Missing version data") if repository.data.category == "integration" and repository.data.domain is None: retval = True _do_log("Missing domain") return retval class AdjustedHacsData(HacsData): """Extended HACS data.""" async def register_base_data( self, category: str, repositories: dict[str, dict[str, Any]], removed: list[str], ): """Restore saved data.""" await self.register_unknown_repositories(repositories, category) for entry, repo_data in repositories.items(): if repo_data["full_name"] in removed: self.hacs.log.warning( "Skipping %s as it's removed from HACS", repo_data["full_name"] ) continue self.async_restore_repository(entry, repo_data) @callback def async_store_repository_data(self, repository: HacsRepository) -> dict: """Store the repository data.""" data = {"manifest": {}} for key, default in HACS_MANIFEST_KEYS_TO_EXPORT: if ( value := getattr(repository.repository_manifest, key, default) ) != default: data["manifest"][key] = value for key, default in REPOSITORY_KEYS_TO_EXPORT: if (value := getattr(repository.data, key, default)) != default: data[key] = value data["last_fetched"] = ( repository.data.last_fetched.timestamp() if repository.data.last_fetched else datetime.utcnow().timestamp() ) if not repository_has_missing_keys(repository, "store"): self.content[str(repository.data.id)] = data class AdjustedHacs(HacsBase): """Extended HACS class.""" data: AdjustedHacsData def __init__(self, session: ClientSession, *, token: str | None = None): """Initialize.""" super().__init__() self.hass = HomeAssistant("") # pylint: disable=too-many-function-args self.queue = QueueManager(self.hass) self.repositories = HacsRepositories() self.system.generator = True self.session = session self.core.config_path = None self.configuration.token = token self.data = AdjustedHacsData(hacs=self) self.data_client = HacsDataClient( session=session, client_name="HACS/Generator") self.github = GitHub( token, session, headers=HACS_ACTION_GITHUB_API_HEADERS, ) self.githubapi = GitHubAPI( token=token, session=session, **{"client_name": "HACS/Generator"}, ) async def async_can_update(self) -> int: """Helper to calculate the number of repositories we can fetch data for.""" if not os.getenv("DATA_GENERATOR_TOKEN"): return 10 return await super().async_can_update() @concurrent(concurrenttasks=10) async def concurrent_register_repository( self, repository_full_name: str, category: str, ) -> None: """Register a repository.""" await self.async_register_repository( repository_full_name=repository_full_name, category=category, default=True ) @concurrent(concurrenttasks=10, backoff_time=0.1) async def concurrent_update_repository(self, repository: HacsRepository) -> None: """Update a repository.""" if repository_has_missing_keys(repository, "update"): # If we have missing keys, force a full update by setting the etag to None repository.data.etag_repository = None if repository.data.last_version not in (None, ""): releases: list[GitHubReleaseModel] = [] try: repository.logger.info( "%s Fetching repository releases", repository.string, ) response = await self.githubapi.generic( endpoint=f"/repos/{repository.data.full_name}/releases", etag=repository.data.etag_releases, kwargs={"per_page": 30}, ) releases = [GitHubReleaseModel(rel) for rel in response.data] release_count = len(releases) repository.data.etag_releases = response.etag repository.data.prerelease = None if release_count != 0: for release in releases: if release.draft: repository.logger.warning( "%s Found draft %s", repository.string, release.tag_name) elif release.prerelease: repository.logger.info( "%s Found prerelease %s", repository.string, release.tag_name) if repository.data.prerelease is None: repository.data.prerelease = release.tag_name else: repository.logger.info( "%s Found release %s", repository.string, release.tag_name) repository.data.releases = True repository.releases.objects = releases repository.data.published_tags = [ x.tag_name for x in repository.releases.objects ] if repository.data.last_version != release.tag_name: repository.data.last_version = release.tag_name repository.data.etag_repository = None break if release_count >= 30 and not repository.data.releases: repository.logger.warning( "%s Found 30 releases but no release, falling back to fetching latest", repository.string, ) response = await self.githubapi.generic( endpoint=f"/repos/{repository.data.full_name}/releases/latest", etag=repository.data.etag_releases, ) response.data = GitHubReleaseModel( response.data) if response.data else None if (releases := response.data) is not None: repository.data.releases = True repository.releases.objects = [releases] repository.data.published_tags = [ x.tag_name for x in repository.releases.objects ] if ( next_version := next(iter(repository.data.published_tags), None) ) != repository.data.last_version: repository.data.last_version = next_version repository.data.etag_repository = None if ( repository.data.prerelease and repository.data.prerelease == repository.data.last_version ): repository.data.prerelease = None except GitHubNotModifiedException: repository.data.releases = True repository.logger.info( "%s Release data is up to date", repository.string, ) except GitHubNotFoundException: repository.data.releases = False repository.logger.info( "%s No releases found", repository.string) except GitHubException as exception: repository.data.releases = False repository.logger.error("%s %s", repository.string, exception) await repository.common_update( force=repository.data.etag_repository is None, skip_releases=repository.data.releases, ) async def generate_data_for_category( self, category: str, repository_name: str | None, current_data: dict[str, dict[str, Any]], force: bool, ) -> dict[str, dict[str, Any]]: """Generate data for category.""" removed = ( [] if repository_name is not None else await self.data_client.get_repositories("removed") ) await self.data.register_base_data( category, {} if force else current_data, removed, ) self.queue.clear() await self.get_category_repositories(category, repository_name, removed) async def _handle_queue(): if not self.queue.pending_tasks: return can_update = await self.async_can_update() self.log.debug( "Can update %s repositories, %s items in queue", can_update, self.queue.pending_tasks, ) if can_update == 0: self.log.info("Can't do anything, sleeping for 1 min.") await asyncio.sleep(60) await _handle_queue() try: await self.queue.execute(round(can_update / (6 if force else 3)) or 1) except HacsExecutionStillInProgress: return await _handle_queue() await _handle_queue() self.data.content = {} for repository in self.repositories.list_all: if repository.data.category != category: continue if repository.data.archived: continue self.data.async_store_repository_data(repository) return self.data.content async def get_category_repositories( self, category: str, repository_name: str | None, removed: list[str], ) -> None: """Get repositories from category.""" repositories = ( await self.async_github_get_hacs_default_file(category) if repository_name is None else [] ) if repository_name is not None: repositories = [repository_name] elif category == "integration": # hacs/integration i not in the default file, but it's still needed repositories.append("hacs/integration") for repo in repositories: if repo in removed: self.log.warning("Skipping %s as it's removed from HACS", repo) continue repository = self.repositories.get_by_full_name(repo) if repository is not None: self.queue.add(self.concurrent_update_repository( repository=repository)) continue self.queue.add( self.concurrent_register_repository( repository_full_name=repo, category=category, ) ) async def summarize_data( self, current_data: dict[str, dict[str, Any]], updated_data: dict[str, dict[str, Any]], ) -> dict[str, Any]: """Summarize data.""" changed = 0 current_count = len(current_data.keys()) new_count = len(updated_data.keys()) for repo_id, repo_data in updated_data.items(): if not dicts_are_equal( a=repo_data, b=current_data.get(repo_id, {}), ignore=COMPARE_IGNORE, ): changed += 1 async def _rate_limit() -> dict[str, Any]: res = await self.async_github_api_method( method=self.githubapi.rate_limit, ) return { "core": { "used": res.data.resources.core.used, "limit": res.data.resources.core.limit, "reset": res.data.resources.core.reset, }, "graphql": { "used": res.data.resources.graphql.used, "limit": res.data.resources.graphql.limit, "reset": res.data.resources.graphql.reset, }, } summary = { "changed_pct": round((changed / new_count) * 100), "changed": changed, "current_count": current_count, "diff": abs(new_count - current_count), "new_count": new_count, "rate_limit": await _rate_limit(), } jsonprint(summary) if len(updated_data) == 1: jsonprint(updated_data) return summary async def async_github_get_hacs_default_file(self, filename: str) -> list: """Get the content of a default file.""" response = await self.async_github_api_method( method=self.githubapi.repos.contents.get, repository=HacsGitHubRepo.DEFAULT, path=filename, ) if response is None: return [] return json_loads(decode_content(response.data.content)) async def generate_category_data(category: str, repository_name: str = None): """Generate data.""" async with ClientSession() as session: hacs = AdjustedHacs( session=session, token=os.getenv("DATA_GENERATOR_TOKEN")) os.makedirs(os.path.join(OUTPUT_DIR, category), exist_ok=True) os.makedirs(os.path.join(OUTPUT_DIR, "diff"), exist_ok=True) force = os.environ.get("FORCE_REPOSITORY_UPDATE") == "True" stored_data = await hacs.data_client.get_data(category, validate=False) current_data = ( next( ( {key: value} for key, value in stored_data.items() if value["full_name"] == repository_name ), {}, ) if repository_name is not None else stored_data ) updated_data = await hacs.generate_data_for_category( category, repository_name, current_data, force=force, ) summary = await hacs.summarize_data(current_data, updated_data) with open( os.path.join(OUTPUT_DIR, "summary.json"), mode="w", encoding="utf-8", ) as data_file: json.dump( summary, data_file, cls=JSONEncoder, sort_keys=True, indent=2, ) did_raise = False if ( not updated_data or len(updated_data) == 0 or not isinstance(updated_data, dict) ): print_error_and_exit("Updated data is empty", category) did_raise = True try: VALIDATE_GENERATED_V2_REPO_DATA[category](updated_data) except vol.Invalid as error: did_raise = True errors = expand_and_humanize_error(updated_data, error) if isinstance(errors, list): for err in errors: print(f"::error::{err}") sys.exit(1) print_error_and_exit(f"Invalid data: {errors}", category) if did_raise: print_error_and_exit( "Validation did raise but did not exit!", category) sys.exit(1) # Fallback, should not be reached with open( os.path.join(OUTPUT_DIR, category, "stored.json"), mode="w", encoding="utf-8", ) as data_file: json.dump( stored_data, data_file, cls=JSONEncoder, separators=(",", ":"), ) with open( os.path.join(OUTPUT_DIR, category, "data.json"), mode="w", encoding="utf-8", ) as data_file: json.dump( updated_data, data_file, cls=JSONEncoder, separators=(",", ":"), ) with open( os.path.join(OUTPUT_DIR, category, "repositories.json"), mode="w", encoding="utf-8", ) as repositories_file: json.dump( [v["full_name"] for v in updated_data.values()], repositories_file, separators=(",", ":"), sort_keys=True, ) with open( os.path.join(OUTPUT_DIR, "diff", f"{category}_before.json"), mode="w", encoding="utf-8", ) as data_file: json.dump( { i: { k: v for k, v in d.items() if k not in COMPARE_IGNORE } for i, d in current_data.items() }, data_file, cls=JSONEncoder, sort_keys=True, indent=2, ) with open( os.path.join(OUTPUT_DIR, "diff", f"{category}_after.json"), mode="w", encoding="utf-8", ) as data_file: json.dump( { i: { k: v for k, v in d.items() if k not in COMPARE_IGNORE } for i, d in updated_data.items() }, data_file, cls=JSONEncoder, sort_keys=True, indent=2, ) if __name__ == "__main__": asyncio.run( generate_category_data( sys.argv[1], # category sys.argv[2] if len(sys.argv) > 2 else None, # repository_name ) ) ================================================ FILE: scripts/data/validate_category_data.py ================================================ """Validate HACS V2 data.""" from __future__ import annotations import asyncio import json import os import sys from typing import Any import voluptuous as vol from custom_components.hacs.const import HACS_REPOSITORY_ID from custom_components.hacs.utils.validate import VALIDATE_GENERATED_V2_REPO_DATA from .common import expand_and_humanize_error, print_error_and_exit async def validate_category_data(category: str, file_path: str) -> None: """Validate category data.""" target_path = os.path.join(os.getcwd(), file_path) if not os.path.isfile(target_path): print_error_and_exit(f"File {target_path} does not exist", category, file_path) if category not in VALIDATE_GENERATED_V2_REPO_DATA: print_error_and_exit(f"Category {category} is not supported", category, file_path) with open( target_path, encoding="utf-8", ) as data_file: contents: dict[str, dict[str, Any]] = json.loads(data_file.read()) did_raise = False if not contents or len(contents) == 0 or not isinstance(contents, dict): print_error_and_exit(f"File {target_path} is empty", category, file_path) try: VALIDATE_GENERATED_V2_REPO_DATA[category](contents) except vol.Invalid as error: did_raise = True errors = expand_and_humanize_error(contents, error) if isinstance(errors, list): for err in errors: print(f"::error::{err}") sys.exit(1) print_error_and_exit(f"Invalid data: {errors}", category, file_path) if category == "integration" and HACS_REPOSITORY_ID not in contents: did_raise = True print_error_and_exit( "HACS is missing...", category, file_path ) if did_raise: print_error_and_exit("Validation did raise but did not exit!", category, file_path) sys.exit(1) # Fallback, should not be reached print( f"All {len(contents)} entries for the " f"{category} category in {target_path} are valid." ) if __name__ == "__main__": if len(sys.argv) != 3: print("Usage: python3 -m scripts.data.validate_category_data ") sys.exit(1) asyncio.run(validate_category_data(sys.argv[1], sys.argv[2])) ================================================ FILE: scripts/develop ================================================ #!/usr/bin/env bash declare frontend_dir set -e cd "$(dirname "$0")/.." if [ ! -f "${PWD}/config/configuration.yaml" ]; then mkdir -p "${PWD}/config" hass --config "${PWD}/config" --script ensure_config echo "Creating default configuration." echo " default_config: frontend: themes: !include_dir_merge_named themes logger: default: info logs: custom_components.hacs: debug # aiogithubapi: debug # awesomeversion: debug " >> "${PWD}/config/configuration.yaml" fi while getopts u:a:f: flag do case "${flag}" in f) frontend_dir=${OPTARG};; esac done if [[ -z "${frontend_dir}" ]]; then echo "Installing HACS frontend" bash "scripts/install/frontend" fi # Set the python path to include our custom_components directory export PYTHONPATH="${PYTHONPATH}:${PWD}/custom_components" # Start Home Assistant HACS_FRONTEND_DIR="$(readlink -f ${frontend_dir})" hass --config "${PWD}/config" --debug ================================================ FILE: scripts/install/core ================================================ #!/usr/bin/env bash set -e cd "$(dirname "$0")/../.." bash scripts/install/pip_packages --requirement requirements_core_min.txt ================================================ FILE: scripts/install/core_dev ================================================ #!/usr/bin/env bash set -e cd "$(dirname "$0")/../.." bash scripts/install/pip_packages \ "git+https://github.com/home-assistant/core.git@dev" \ home-assistant-frontend ================================================ FILE: scripts/install/frontend ================================================ #!/usr/bin/env bash set -e cd "$(dirname "$0")/../.." FRONTEND_VERSION="20250128065759" function installFrontendFromGitHub() { # Temporarily disable exit on error set +e # Attempt to install the specified frontend version from GitHub scripts/install/pip_packages \ --target=./custom_components/hacs \ "https://github.com/hacs/frontend/releases/download/${FRONTEND_VERSION}/hacs_frontend-${FRONTEND_VERSION}-py3-none-any.whl" # Re-enable exit on error set -e } function installFrontend() { # Remove existing frontend installation rm -rf ./custom_components/hacs/hacs_frontend installFrontendFromGitHub # Check if the installation from GitHub was successful if [[ ! -f "./custom_components/hacs/hacs_frontend/version.py" ]]; then echo "Failed to install from GitHub, trying PyPI" # If not, install from PyPI scripts/install/pip_packages \ --target=./custom_components/hacs \ "hacs_frontend==${FRONTEND_VERSION}" fi # Clean up any leftover metadata files rm -rf ./custom_components/hacs/*.dist-info } # Get current version if any CURRENT_VERSION=$(grep "VERSION" ./custom_components/hacs/hacs_frontend/version.py -s | cut -d '"' -f 2) # Install the frontend if the current version is different from the desired version if [[ "${CURRENT_VERSION}" != "${FRONTEND_VERSION}" ]]; then installFrontend else echo "Frontend version is the same (${FRONTEND_VERSION}), skipping download" fi ================================================ FILE: scripts/install/pip_packages ================================================ #!/usr/bin/env bash set -e python3 -m pip \ install \ --upgrade \ --disable-pip-version-check \ --constraint constraints.txt \ "${@}" ================================================ FILE: scripts/install/uv_packages ================================================ #!/usr/bin/env bash set -e uv pip \ install \ --constraint constraints.txt \ "${@}" ================================================ FILE: scripts/lgtm.js ================================================ console.log("Dummy file to make LGTM happy...") ================================================ FILE: scripts/lint ================================================ #!/usr/bin/env bash set -e cd "$(dirname "$0")/.." pre-commit install-hooks --config .github/pre-commit-config.yaml; pre-commit run --hook-stage manual --all-files --config .github/pre-commit-config.yaml; vulture . --min-confidence 75 --ignore-names policy ================================================ FILE: scripts/setup ================================================ #!/usr/bin/env bash set -e cd "$(dirname "$0")/.." scripts/install/pip_packages "pip<23.2,>=21.3.1" scripts/install/pip_packages setuptools wheel scripts/install/pip_packages \ --requirement requirements_lint.txt \ --requirement requirements_core_min.txt \ --requirement requirements_test.txt scripts/install/frontend pre-commit install --config .github/pre-commit-config.yaml ================================================ FILE: scripts/snapshot-update ================================================ #!/usr/bin/env bash set -e cd "$(dirname "$0")/.." python3 -m \ pytest \ tests \ --snapshot-update ================================================ FILE: scripts/test ================================================ #!/usr/bin/env bash set -e cd "$(dirname "$0")/.." python3 -m pytest -x tests ================================================ FILE: scripts/update/__init__.py ================================================ """HACS update script.""" ================================================ FILE: scripts/update/default_repositories.py ================================================ """Update the shipped default repositories data file.""" import json import os import sys def update(): """Update the shipped default repositories data file.""" storage, to_store, old = None, {}, {} updated = 0 with open(f"{os.getcwd()}/.storage/hacs.repositories", encoding="utf-8") as storage_file: storage = json.load(storage_file) with open( f"{os.getcwd()}/custom_components/hacs/utils/default.repositories", encoding="utf-8" ) as old_file: old = json.load(old_file) if storage is None: sys.exit("No storage file") for repo in storage["data"]: storage["data"][repo]["first_install"] = True for key in ("installed", "show_beta", "new"): storage["data"][repo][key] = False for key in ("installed_commit", "selected_tag", "version_installed"): storage["data"][repo][key] = None if old.get(repo, {}).get("etag_repository") != storage["data"][repo].get("etag_repository"): updated += 1 to_store[repo] = storage["data"][repo] with open( f"{os.getcwd()}/custom_components/hacs/utils/default.repositories", mode="w", encoding="utf-8", ) as to_store_file: to_store_file.write(json.dumps(to_store)) print(f"{updated} was updated") if __name__ == "__main__": update() ================================================ FILE: scripts/update/manifest.py ================================================ """Update the manifest file.""" import json import os from pathlib import Path import sys MANIFEST_FILE = Path(f"{os.getcwd()}/custom_components/hacs/manifest.json") def update_manifest(): """Update the manifest file.""" version = "0.0.0" for index, value in enumerate(sys.argv): if value in ["--version", "-V"]: version = sys.argv[index + 1] with open(MANIFEST_FILE, encoding="utf-8") as manifestfile: base: dict = json.load(manifestfile) base["version"] = version with open(MANIFEST_FILE, "w", encoding="utf-8") as manifestfile: manifestfile.write( json.dumps( { "domain": base["domain"], "name": base["name"], **{k: v for k, v in sorted(base.items()) if k not in ("domain", "name")}, }, indent=4, ) ) update_manifest() ================================================ FILE: tests/__init__.py ================================================ import json from awesomeversion import AwesomeVersion from homeassistant import const, core, loader _async_suggest_report_issue_mock_call_tracker = [] _orig_async_suggest_report_issue = loader.async_suggest_report_issue @core.callback def async_suggest_report_issue_mock(*args, **kwargs): result = _orig_async_suggest_report_issue(*args, **kwargs) _async_suggest_report_issue_mock_call_tracker.append(result) return result loader.async_suggest_report_issue = async_suggest_report_issue_mock ================================================ FILE: tests/action/test_hacs_action_integration.py ================================================ """Tests for the HACS action.""" import json import os from unittest import mock import pytest from tests.common import TOKEN, MockedResponse, ResponseMocker, current_function_name from tests.conftest import SnapshotFixture @pytest.mark.parametrize( "test_case", [ pytest.param( { "manifest": {"documentation": None}, "succeed": False, "releases": None, }, id="bad_documentation" ), pytest.param( { "manifest": {"issue_tracker": None}, "succeed": False, "releases": None, }, id="bad_issue_tracker" ), pytest.param( { "manifest": {}, "succeed": True, "releases": None, }, id="valid_manifest" ), pytest.param( { "manifest": {}, "succeed": True, "releases": [ { "tag_name": "v1.0.0", "assets": [] } ], }, id="releases_without_assets" ), pytest.param( { "manifest": {}, "succeed": True, "releases": [], }, id="no_releases" ), ], ) async def test_hacs_action_integration( test_case: dict, request: pytest.FixtureRequest, caplog: pytest.LogCaptureFixture, response_mocker: ResponseMocker, snapshots: SnapshotFixture, capsys: pytest.CaptureFixture[str], ): """Test the action.""" basemanifest = { "domain": "example", "version": "1.0.0", "documentation": "https://example.com", "codeowners": ["hacs-test-org"], "issue_tracker": "https://example.com", "name": "Example", } envpatch = { "INPUT_GITHUB_TOKEN": TOKEN, "INPUT_REPOSITORY": "hacs-test-org/integration-basic", "INPUT_CATEGORY": "integration", } response_mocker.add( "https://brands.home-assistant.io/domains.json", response=MockedResponse(status=200, content={"custom": ["example"]}), ) response_mocker.add( "https://raw.githubusercontent.com/hacs-test-org/integration-basic/main/custom_components/example/manifest.json", response=MockedResponse( status=200, content=json.dumps({**basemanifest, **test_case["manifest"]}), keep=True, ), ) if (releases := test_case["releases"]) is not None: response_mocker.add( "https://api.github.com/repos/hacs-test-org/integration-basic/releases", response=MockedResponse( status=200, content=releases ), ) with mock.patch.dict(os.environ, envpatch), mock.patch("builtins.exit", mock.MagicMock()): from action.action import preflight await preflight() assert ( "All (8) checks passed" if test_case["succeed"] else "1/8 checks failed") in caplog.text splitlines = [f"<{line.rsplit(' <')[1]}" for line in caplog.text.split( "\n") if " <" in line] snapshots.assert_match( "\n".join( splitlines[0:2] + sorted(splitlines[2:-2]) + splitlines[-2:] + [capsys.readouterr().out] ), f"action/{current_function_name()}/{request.node.callspec.id}.log", ) ================================================ FILE: tests/common.py ================================================ # pylint: disable=missing-docstring,invalid-name from __future__ import annotations from collections.abc import Iterable from contextlib import contextmanager from contextvars import ContextVar from inspect import currentframe import json as json_func import os from types import NoneType from typing import Any, TypedDict from unittest.mock import AsyncMock, patch from aiohttp import ClientError, ClientSession, ClientWebSocketResponse from aiohttp.typedefs import StrOrURL from awesomeversion import AwesomeVersion from homeassistant import config_entries, core as ha from homeassistant.auth import models as auth_models from homeassistant.const import EVENT_HOMEASSISTANT_STOP, __version__ as HA_VERSION from homeassistant.helpers import storage from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.json import ExtendedJSONEncoder import homeassistant.util.uuid as uuid_util import pytest from yarl import URL from custom_components.hacs.base import HacsBase from custom_components.hacs.const import DOMAIN from custom_components.hacs.enums import HacsCategory from custom_components.hacs.repositories.base import HacsManifest, HacsRepository from custom_components.hacs.utils.logger import LOGGER TOKEN = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" REQUEST_CONTEXT: ContextVar[pytest.FixtureRequest] = ContextVar( "request_context", default=None) IGNORED_BASE_FILES = { "/config/automations.yaml", "/config/configuration.yaml", "/config/scenes.yaml", "/config/scripts.yaml", "/config/secrets.yaml", } FIXTURES_PATH = os.path.join(os.path.dirname(__file__), "fixtures") class CategoryTestData(TypedDict): id: str repository: str category: str files: list[str] version_base: str version_update: str prerelease: str _CATEGORY_TEST_DATA: tuple[CategoryTestData] = ( CategoryTestData( id="1296265", category=HacsCategory.APPDAEMON, repository="hacs-test-org/appdaemon-basic", files=["__init__.py", "example.py"], version_base="1.0.0", version_update="2.0.0", prerelease="3.0.0", ), CategoryTestData( id="1296269", category=HacsCategory.INTEGRATION, repository="hacs-test-org/integration-basic", files=["__init__.py", "manifest.json", "module/__init__.py"], version_base="1.0.0", version_update="2.0.0", prerelease="3.0.0", ), CategoryTestData( id="1296267", category=HacsCategory.PLUGIN, repository="hacs-test-org/plugin-basic", files=["example.js", "example.js.gz"], version_base="1.0.0", version_update="2.0.0", prerelease="3.0.0", ), CategoryTestData( id="1296262", category=HacsCategory.PYTHON_SCRIPT, repository="hacs-test-org/python_script-basic", files=["example.py"], version_base="1.0.0", version_update="2.0.0", prerelease="3.0.0", ), CategoryTestData( id="1296268", category=HacsCategory.TEMPLATE, repository="hacs-test-org/template-basic", files=["example.jinja"], version_base="1.0.0", version_update="2.0.0", prerelease="3.0.0", ), CategoryTestData( id="1296266", category=HacsCategory.THEME, repository="hacs-test-org/theme-basic", files=["example.yaml"], version_base="1.0.0", version_update="2.0.0", prerelease="3.0.0", ), ) def category_test_data_parametrized( *, xfail_categories: list[HacsCategory] | None = None, categories: Iterable[HacsCategory] = [entry["category"] for entry in _CATEGORY_TEST_DATA], **kwargs, ): return ( pytest.param( entry, marks=[pytest.mark.xfail] if xfail_categories and entry["category"] in xfail_categories else [], id=entry["repository"], ) for entry in _CATEGORY_TEST_DATA if entry["category"] in categories ) def current_function_name(): """Return the name of the current function.""" return currentframe().f_back.f_code.co_name def safe_json_dumps(data: dict | list) -> str: return json_func.dumps( data, indent=4, sort_keys=True, cls=ExtendedJSONEncoder, ) def recursive_remove_key(data: dict[str, Any], to_remove: Iterable[str]) -> dict[str, Any]: def _sort_list(entry): if isinstance(entry, list): if len(entry) == 0: return entry if isinstance(entry[0], str): return sorted(entry) if isinstance(entry[0], list): return [_sort_list(item) for item in entry] return sorted( entry, key=lambda obj: (getattr(obj, "id", None) or getattr(obj, "name", None) or 0) if isinstance(obj, dict) else obj, ) if not isinstance(data, (dict, set, list)): return data if isinstance(data, list): return [recursive_remove_key(item, to_remove) for item in _sort_list(data)] returndata = {} for key in sorted(data.keys()): value = data[key] if key in to_remove: continue elif isinstance(value, (str, bool, int, float, NoneType)): returndata[key] = value elif isinstance(value, dict): returndata[key] = recursive_remove_key( {k: value[k] for k in sorted(value.keys())}, to_remove, ) elif isinstance(value, (list, set)): returndata[key] = [recursive_remove_key( item, to_remove) for item in _sort_list(value)] else: returndata[key] = type(value) return returndata def fixture(filename, asjson=True): """Load a fixture.""" filename = f"{filename}.json" if "." not in filename else filename path = os.path.join( os.path.dirname(__file__), "fixtures", filename.lower().replace("/", "_"), ) try: with open(path, encoding="utf-8") as fptr: if asjson: return json_func.loads(fptr.read()) return fptr.read() except OSError as err: raise OSError(f"Missing fixture for { path.split('fixtures/')[1]}") from err def dummy_repository_base(hacs, repository=None): if repository is None: repository = HacsRepository(hacs) repository.data.full_name = "test/test" repository.data.full_name_lower = "test/test" repository.hacs = hacs repository.hacs.hass = hacs.hass repository.hacs.core.config_path = hacs.hass.config.path() repository.logger = LOGGER repository.data.domain = "test" repository.data.last_version = "3" repository.data.selected_tag = "3" repository.ref = repository.version_to_download() repository.integration_manifest = {"config_flow": False, "domain": "test"} repository.data.published_tags = ["1", "2", "3"] repository.data.update_data(fixture("repository_data.json", asjson=True)) repository.hacs_manifest = HacsManifest.from_dict({}) async def update_repository(*args, **kwargs): pass repository.update_repository = update_repository return repository @ha.callback def ensure_auth_manager_loaded(auth_mgr): """Ensure an auth manager is considered loaded.""" store = auth_mgr._store if store._users is None: store._set_defaults() @contextmanager def mock_storage(data=None): """Mock storage. Data is a dict {'key': {'version': version, 'data': data}} Written data will be converted to JSON to ensure JSON parsing works. """ if data is None: data = {} orig_load = storage.Store._async_load async def mock_async_load(store): """Mock version of load.""" if store._data is None: # No data to load if store.key not in data: return None mock_data = data.get(store.key) if "data" not in mock_data or "version" not in mock_data: raise ValueError('Mock data needs "version" and "data"') store._data = mock_data # Route through original load so that we trigger migration loaded = await orig_load(store) return loaded def mock_write_data(store, path, data_to_write): """Mock version of write data.""" # To ensure that the data can be serialized data[store.key] = json_func.loads( json_func.dumps(data_to_write, cls=store._encoder)) async def mock_remove(store): """Remove data.""" data.pop(store.key, None) with ( patch( "homeassistant.helpers.storage.Store._async_load", side_effect=mock_async_load, autospec=True, ), patch( "homeassistant.helpers.storage.Store._write_data", side_effect=mock_write_data, autospec=True, ), patch( "homeassistant.helpers.storage.Store.async_remove", side_effect=mock_remove, autospec=True, ), ): yield data class MockOwner(auth_models.User): """Mock a user in Home Assistant.""" def __init__(self): """Initialize mock user.""" super().__init__( **{ "is_owner": True, "is_active": True, "name": "Mocked Owner User", "system_generated": False, "groups": [], "perm_lookup": None, }, ) @staticmethod def create(hass: ha.HomeAssistant): """Create a mock user.""" user = MockOwner() ensure_auth_manager_loaded(hass.auth) hass.auth._store._users[user.id] = user return user class MockConfigEntry(config_entries.ConfigEntry): entry_id = uuid_util.random_uuid_hex() def add_to_hass(self, hass: ha.HomeAssistant) -> None: """Test helper to add entry to hass.""" hass.config_entries._entries[self.entry_id] = self class WSClient: """WS Client to be used in testing.""" client: ClientWebSocketResponse | None = None def __init__(self, hass: ha.HomeAssistant, token: str) -> None: self.hass = hass self.token = token self.id = 0 async def _create_client(self) -> None: if self.client is not None: return clientsession = async_get_clientsession(self.hass) async def _async_close_websession(event: ha.Event) -> None: """Close websession.""" await self.send_json("close", {}) await self.client.close() clientsession.detach() self.hass.bus.async_listen_once( EVENT_HOMEASSISTANT_STOP, _async_close_websession) self.client = await clientsession.ws_connect( "ws://localhost:8123/api/websocket", timeout=1, autoclose=True, ) auth_response = await self.client.receive_json() assert auth_response["type"] == "auth_required" await self.client.send_json({"type": "auth", "access_token": self.token}) auth_response = await self.client.receive_json() assert auth_response["type"] == "auth_ok" async def send_json(self, type: str, payload: dict[str, Any]) -> dict[str, Any]: self.id += 1 await self._create_client() await self.client.send_json({"id": self.id, "type": type, **payload}) async def receive_json(self) -> dict[str, Any]: return await self.client.receive_json() async def send_and_receive_json(self, type: str, payload: dict[str, Any]) -> dict[str, Any]: await self.send_json(type=type, payload=payload) return await self.client.receive_json() class MockedResponse: def __init__(self, **kwargs) -> None: self.kwargs = kwargs self.exception = kwargs.get("exception") self.keep = kwargs.get("keep", False) @property def status(self): return self.kwargs.get("status", 200) @property def url(self): return self.kwargs.get("url", "http://127.0.0.1") @property def headers(self): return self.kwargs.get("headers", {}) async def read(self, **kwargs): if (content := self.kwargs.get("content")) is not None: return content return await self.kwargs.get("read", AsyncMock())() async def json(self, **kwargs): if (content := self.kwargs.get("content")) is not None: return content return await self.kwargs.get("json", AsyncMock())() async def text(self, **kwargs): if (content := self.kwargs.get("content")) is not None: return content return await self.kwargs.get("text", AsyncMock())() def raise_for_status(self) -> None: if self.status >= 300: raise ClientError(self.status) class ResponseMocker: calls: list[dict[str, Any]] = [] responses: dict[str, MockedResponse] = {} def add(self, url: str, response: MockedResponse) -> None: self.responses[url] = response def get(self, url: str, *args, **kwargs) -> MockedResponse: data = {"url": url, "args": list(args), "kwargs": kwargs} if (request := REQUEST_CONTEXT.get()) is not None: data["_test_caller"] = f"{ request.node.location[0]}::{request.node.name}" data["_uses_setup_integration"] = request.node.name != "test_integration_setup" and ( "setup_integration" in request.fixturenames or "hacs" in request.fixturenames ) self.calls.append(data) response = self.responses.get(url, None) if response is not None and response.keep: return response return self.responses.pop(url, None) class ProxyClientSession(ClientSession): response_mocker = ResponseMocker() async def _request(self, method: str, str_or_url: StrOrURL, *args, **kwargs): if str_or_url.startswith("ws://"): return await super()._request(method, str_or_url, *args, **kwargs) if (resp := self.response_mocker.get(str_or_url, args, kwargs)) is not None: LOGGER.info("Using mocked response for %s", str_or_url) if resp.exception: raise resp.exception return resp url = URL(str_or_url) fixture_file = f"fixtures/proxy/{url.host}{url.path}{'.json' if url.host in ( 'api.github.com', 'data-v2.hacs.xyz') and not url.path.endswith('.json') else ''}" fp = os.path.join( os.path.dirname(__file__), fixture_file, ) LOGGER.info("Using mocked response from %s", fixture_file) if not os.path.exists(fp): raise Exception(f"Missing fixture for proxy/{url.host}{url.path}") async def read(**kwargs): if url.path.endswith(".zip"): with open(fp, mode="rb") as fptr: return fptr.read() with open(fp, encoding="utf-8") as fptr: return fptr.read().encode("utf-8") async def json(**kwargs): with open(fp, encoding="utf-8") as fptr: return json_func.loads(fptr.read()) return MockedResponse( url=url, read=read, json=json, headers={ "X-RateLimit-Limit": "999", "X-RateLimit-Remaining": "999", "X-RateLimit-Reset": "999", "Content-Type": "application/json", "Etag": "321", }, ) async def client_session_proxy(hass: ha.HomeAssistant) -> ClientSession: """Create a mocked client session.""" base = async_get_clientsession(hass) base_request = base._request response_mocker = ResponseMocker() async def _request(method: str, str_or_url: StrOrURL, *args, **kwargs): if str_or_url.startswith("ws://"): return await base_request(method, str_or_url, *args, **kwargs) if (resp := response_mocker.get(str_or_url, args, kwargs)) is not None: LOGGER.info("Using mocked response for %s", str_or_url) if resp.exception: raise resp.exception return resp url = URL(str_or_url) fixture_file = f"fixtures/proxy/{url.host}{url.path}{'.json' if url.host in ( 'api.github.com', 'data-v2.hacs.xyz') and not url.path.endswith('.json') else ''}" fp = os.path.join( os.path.dirname(__file__), fixture_file, ) if not os.path.exists(fp): raise Exception(f"Missing fixture for proxy/{url.host}{url.path}") async def read(**kwargs): if url.path.endswith(".zip"): with open(fp, mode="rb") as fptr: return fptr.read() with open(fp, encoding="utf-8") as fptr: return fptr.read().encode("utf-8") async def json(**kwargs): with open(fp, encoding="utf-8") as fptr: return json_func.loads(fptr.read()) return MockedResponse( url=url, read=read, json=json, headers={ "X-RateLimit-Limit": "999", "X-RateLimit-Remaining": "999", "X-RateLimit-Reset": "999", "Content-Type": "application/json", }, ) base._request = _request return base def create_config_entry( data: dict[str, Any] = None, options: dict[str, Any] = None, ) -> MockConfigEntry: config_entry_data = { "version": 1, "minor_version": 0, "domain": DOMAIN, "discovery_keys": {}, "title": "", "data": {"token": TOKEN, **(data or {})}, "source": "user", "subentries_data": None, "options": {**(options or {})}, "unique_id": "12345", } return MockConfigEntry(**config_entry_data) async def setup_integration(hass: ha.HomeAssistant, config_entry: MockConfigEntry) -> None: mock_session = await client_session_proxy(hass) with patch( "homeassistant.helpers.aiohttp_client.async_get_clientsession", return_value=mock_session, ): hass.data.pop("custom_components", None) config_entry.add_to_hass(hass) assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() hacs: HacsBase = hass.data.get(DOMAIN) for repository in hacs.repositories.list_all: if repository.data.full_name != "hacs/integration": repository.data.installed = False repository.data.installed_version = None repository.data.installed_commit = None assert not hacs.system.disabled def get_hacs(hass: ha.HomeAssistant) -> HacsBase: return hass.data[DOMAIN] ================================================ FILE: tests/conftest.py ================================================ """Set up some common test helper things.""" from . import patch_time # isort:skip import asyncio from collections.abc import Generator from dataclasses import asdict from glob import iglob import json import logging import os import shutil from typing import Any from unittest.mock import MagicMock, _patch, patch from aiohttp import AsyncResolver from awesomeversion import AwesomeVersion import freezegun from homeassistant import loader from homeassistant.auth.models import Credentials from homeassistant.auth.providers.homeassistant import HassAuthProvider from homeassistant.components.lovelace.const import DOMAIN as LOVELACE_DOMAIN from homeassistant.components.lovelace.resources import ResourceStorageCollection from homeassistant.config_entries import ConfigEntryState from homeassistant.const import __version__ as HA_VERSION from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er from homeassistant.runner import HassEventLoopPolicy from homeassistant.setup import async_setup_component from homeassistant.util.async_ import create_eager_task import pytest import pytest_asyncio from pytest_snapshot.plugin import Snapshot from slugify import slugify from custom_components.hacs.base import HacsBase from custom_components.hacs.const import DOMAIN from custom_components.hacs.repositories import ( HacsAppdaemonRepository, HacsIntegrationRepository, HacsPluginRepository, HacsPythonScriptRepository, HacsTemplateRepository, HacsThemeRepository, ) from custom_components.hacs.utils.store import async_load_from_store from tests import _async_suggest_report_issue_mock_call_tracker from tests.common import ( IGNORED_BASE_FILES, REQUEST_CONTEXT, MockOwner, ProxyClientSession, ResponseMocker, WSClient, client_session_proxy, create_config_entry, dummy_repository_base, get_hacs, mock_storage as mock_storage, recursive_remove_key, safe_json_dumps, setup_integration as common_setup_integration, ) from tests.homeassistantfixtures.dev import ( async_test_home_assistant as async_test_home_assistant_dev, ) from tests.homeassistantfixtures.min import ( async_test_home_assistant as async_test_home_assistant_min_version, ) # Set default logger logging.basicConfig(level=logging.INFO) if "GITHUB_ACTION" in os.environ: logging.basicConfig( format="::%(levelname)s:: %(message)s", level=logging.DEBUG, ) asyncio.set_event_loop_policy(HassEventLoopPolicy(False)) asyncio.set_event_loop_policy = lambda policy: None # Disable sleep in tests _sleep = asyncio.sleep asyncio.sleep = lambda _: _sleep(0) @pytest.fixture(autouse=True) def time_freezer() -> Generator[freezegun.api.FrozenDateTimeFactory, None, None]: with freezegun.freeze_time("2019-02-26T15:02:39Z") as frozen_time: yield frozen_time @pytest.fixture(autouse=True) def set_request_context(request: pytest.FixtureRequest): """Set request context for every test.""" REQUEST_CONTEXT.set(request) @pytest.fixture def connection(): """Mock fixture for connection.""" return MagicMock() @pytest.fixture def hass_storage(): """Fixture to mock storage.""" with mock_storage() as stored_data: yield stored_data @pytest.fixture(autouse=True) def mock_zeroconf_resolver(event_loop) -> Generator[_patch]: """Mock out the zeroconf resolver.""" if AwesomeVersion(HA_VERSION) < "2025.2.0dev0": yield None else: resolver = AsyncResolver(event_loop) resolver.real_close = resolver.close patcher = patch( "homeassistant.helpers.aiohttp_client._async_make_resolver", return_value=resolver, ) patcher.start() try: yield patcher finally: patcher.stop() @pytest.fixture async def hass(time_freezer, event_loop, tmpdir, check_report_issue: None): """Fixture to provide a test instance of Home Assistant.""" def exc_handle(loop, context): """Handle exceptions by rethrowing them, which will fail the test.""" if exception := context.get("exception"): exceptions.append(exception) else: exceptions.append( Exception( "Received exception handler without exception, " f"but with message: {context["message"]}", ), ) orig_exception_handler(loop, context) exceptions: list[Exception] = [] if AwesomeVersion(HA_VERSION) > "2025.3.0": context_manager = async_test_home_assistant_dev( event_loop, config_dir=tmpdir.strpath) else: context_manager = async_test_home_assistant_min_version( event_loop, config_dir=tmpdir.strpath, ) async with context_manager as hass: await async_setup_component(hass, "homeassistant", {}) with patch("homeassistant.components.python_script.setup", return_value=True): assert await async_setup_component(hass, "python_script", {}) orig_exception_handler = event_loop.get_exception_handler() event_loop.set_exception_handler(exc_handle) yield hass # Config entries are not normally unloaded on HA shutdown. They are unloaded here # to ensure that they could, and to help track lingering tasks and timers. loaded_entries = [ entry for entry in hass.config_entries.async_entries() if entry.state is ConfigEntryState.LOADED ] if loaded_entries: await asyncio.gather( *( create_eager_task( hass.config_entries.async_unload( config_entry.entry_id), loop=hass.loop, ) for config_entry in loaded_entries ), ) await hass.async_stop(force=True) for ex in exceptions: raise ex shutil.rmtree(hass.config.config_dir) @pytest.fixture def hacs(hass: HomeAssistant, setup_integration: None) -> HacsBase: """Fixture to provide a HACS object.""" return get_hacs(hass) @pytest.fixture def repository(hacs): """Fixtrue for HACS repository object""" return dummy_repository_base(hacs) @pytest.fixture def repository_integration(hacs): """Fixtrue for HACS integration repository object""" repository_obj = HacsIntegrationRepository(hacs, "test/test") return dummy_repository_base(hacs, repository_obj) @pytest.fixture def repository_theme(hacs): """Fixtrue for HACS theme repository object""" repository_obj = HacsThemeRepository(hacs, "test/test") return dummy_repository_base(hacs, repository_obj) @pytest.fixture def repository_plugin(hacs): """Fixtrue for HACS plugin repository object""" repository_obj = HacsPluginRepository(hacs, "test/test") return dummy_repository_base(hacs, repository_obj) @pytest.fixture def repository_python_script(hacs): """Fixtrue for HACS python_script repository object""" repository_obj = HacsPythonScriptRepository(hacs, "test/test") return dummy_repository_base(hacs, repository_obj) @pytest.fixture def repository_template(hacs): """Fixtrue for HACS template repository object""" repository_obj = HacsTemplateRepository(hacs, "test/test") return dummy_repository_base(hacs, repository_obj) @pytest.fixture def repository_appdaemon(hacs): """Fixtrue for HACS appdaemon repository object""" repository_obj = HacsAppdaemonRepository(hacs, "test/test") return dummy_repository_base(hacs, repository_obj) class SnapshotFixture(Snapshot): async def assert_hacs_data( self, hacs: HacsBase, filename: str, additional: dict[str, Any] | None = None, ): pass @pytest.fixture def snapshots(snapshot: Snapshot) -> SnapshotFixture: """Fixture for a snapshot.""" snapshot.snapshot_dir = "tests/snapshots" async def assert_hacs_data( hacs: HacsBase, filename: str, additional: dict[str, Any] | None = None, ): await hacs.data.async_force_write() downloaded = [ f.replace(f"{hacs.core.config_path}", "/config") for f in iglob(f"{hacs.core.config_path}/**", recursive=True) if os.path.isfile(f) ] data = {} stored_data = await async_load_from_store(hacs.hass, "data") for key, value in stored_data["repositories"].items(): data[key] = {} for entry in value: data[key][entry["id"]] = entry dashboard_resources: ResourceStorageCollection try: # Changed to 2025.2.0 # Changed in https://github.com/home-assistant/core/pull/136313 dashboard_resources = hacs.hass.data[LOVELACE_DOMAIN].resources except AttributeError: dashboard_resources = hacs.hass.data[LOVELACE_DOMAIN][ "resources" ] def _entity_state(entity: er.RegistryEntry) -> dict[str, Any]: state = hacs.hass.states.get(entity.entity_id) return { "state": state.state if state else None, "attributes": recursive_remove_key(state.attributes, ("display_precision", "update_percentage")) if state else None, } snapshot.assert_match( safe_json_dumps( recursive_remove_key( { "_dashboard_resources": recursive_remove_key( data=dashboard_resources.async_items(), to_remove=("id",), ), "_data": data, "_directory": sorted(f for f in downloaded if f not in IGNORED_BASE_FILES), "_hacs": { "system": asdict(hacs.system), "status": asdict(hacs.status), "stage": hacs.stage, "configuration": { "debug": hacs.configuration.debug, "dev": hacs.configuration.dev, }, }, "_entities": sorted( ( { "entity_id": entity.entity_id, **_entity_state(entity), **recursive_remove_key( entity.as_partial_dict, ( "id", "created_at", "modified_at", # This can be re-enabled again when min version is > 2026.2 "original_name", ), ), } for entity in er.async_entries_for_config_entry( er.async_get(hacs.hass), hacs.configuration.config_entry.entry_id, ) ), key=lambda x: x["unique_id"], ), **(additional or {}), }, ("categories", "config_entry_id", "device_id", "labels", "config_subentry_id"), ), ), filename, ) snapshot.assert_hacs_data = assert_hacs_data return snapshot @pytest_asyncio.fixture(autouse=True) async def proxy_session(hass: HomeAssistant) -> Generator: """Fixture for a proxy_session.""" mock_session = await client_session_proxy(hass) with patch( "homeassistant.helpers.aiohttp_client.async_get_clientsession", return_value=mock_session, ), patch("scripts.data.generate_category_data.ClientSession", ProxyClientSession), patch( "aiohttp.ClientSession", ProxyClientSession, ): yield @pytest_asyncio.fixture async def ws_client(hass: HomeAssistant) -> WSClient: """Owner authenticated Websocket client fixture.""" auth_provider = HassAuthProvider(hass, hass.auth._store, { "type": "homeassistant"}) hass.auth._providers[(auth_provider.type, auth_provider.id)] = auth_provider owner = MockOwner.create(hass) credentials = Credentials( auth_provider_type=auth_provider.type, auth_provider_id=auth_provider.id, data={"username": "testadmin"}, ) await auth_provider.async_initialize() await hass.auth.async_link_user(owner, credentials) refresh_token = await hass.auth.async_create_refresh_token( owner, "https://hacs.xyz/testing", credential=credentials, ) return WSClient(hass, hass.auth.async_create_access_token(refresh_token)) @pytest.fixture def response_mocker() -> ResponseMocker: """Mock fixture for responses.""" mocker = ResponseMocker() yield mocker mocker.responses.clear() @pytest_asyncio.fixture() async def setup_integration(hass: HomeAssistant, check_report_issue: None) -> None: # Assert the string to ensure the format did not change assert not len(_async_suggest_report_issue_mock_call_tracker) _async_suggest_report_issue_mock_call_tracker.clear() assert ( loader.async_suggest_report_issue( hass, integration_domain=DOMAIN, module="custom_components.hacs", ) == "report it to the author of the 'hacs' custom integration" ) assert len(_async_suggest_report_issue_mock_call_tracker) == 1 _async_suggest_report_issue_mock_call_tracker.clear() assert len(_async_suggest_report_issue_mock_call_tracker) == 0 config_entry = create_config_entry( options={ "appdaemon": True, }, ) await common_setup_integration(hass, config_entry) yield await hass.config_entries.async_remove(config_entry.entry_id) @pytest_asyncio.fixture() async def check_report_issue() -> None: """Finish things up.""" yield if times := len(_async_suggest_report_issue_mock_call_tracker): raise AssertionError( f"homeassistant.loader.async_suggest_report_issue has been called { times} times", ) @pytest.fixture(autouse=True) def track_api_usage(snapshots: SnapshotFixture): """Track API usage.""" yield if (request := REQUEST_CONTEXT.get()) is None: return response_mocker = ResponseMocker() calls = {} for call in response_mocker.calls: if (_test_caller := call.pop("_test_caller", None)) is None: continue if _test_caller not in calls: if call.get("_uses_setup_integration"): calls[_test_caller] = dict.fromkeys([ "https://data-v2.hacs.xyz/appdaemon/data.json", "https://data-v2.hacs.xyz/critical/data.json", "https://data-v2.hacs.xyz/integration/data.json", "https://data-v2.hacs.xyz/plugin/data.json", "https://data-v2.hacs.xyz/python_script/data.json", "https://data-v2.hacs.xyz/removed/data.json", "https://data-v2.hacs.xyz/template/data.json", "https://data-v2.hacs.xyz/theme/data.json", ], -1 ) else: calls[_test_caller] = {} if (url := call.get("url")) not in calls[_test_caller]: calls[_test_caller][url] = 0 calls[_test_caller][url] += 1 filtered_calls = { k: v for k, v in {t: {k: v for k, v in c.items() if v != 0} for t, c in calls.items()}.items() if v } snapshotfile = f"api-usage/{request.node.location[0].replace(".py", "")}{ slugify(f"::{request.node.name}")}.json" if not filtered_calls: assert not os.path.exists(f"tests/snapshots/{snapshotfile}") return response_mocker.calls = [] snapshots.assert_match( safe_json_dumps(filtered_calls), snapshotfile ) ================================================ FILE: tests/fixtures/proxy/api.github.com/rate_limit.json ================================================ { "resources": { "core": { "limit": 5000, "used": 1, "remaining": 4999, "reset": 1691591363 }, "search": { "limit": 30, "used": 12, "remaining": 18, "reset": 1691591091 }, "graphql": { "limit": 5000, "used": 7, "remaining": 4993, "reset": 1691593228 }, "integration_manifest": { "limit": 5000, "used": 1, "remaining": 4999, "reset": 1691594631 }, "source_import": { "limit": 100, "used": 1, "remaining": 99, "reset": 1691591091 }, "code_scanning_upload": { "limit": 500, "used": 1, "remaining": 499, "reset": 1691594631 }, "actions_runner_registration": { "limit": 10000, "used": 0, "remaining": 10000, "reset": 1691594631 }, "scim": { "limit": 15000, "used": 0, "remaining": 15000, "reset": 1691594631 }, "code_search": { "limit": 10, "used": 0, "remaining": 10, "reset": 1691591091 } }, "rate": { "limit": 5000, "used": 1, "remaining": 4999, "reset": 1372700873 } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs/default/contents/appdaemon.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "appdaemon", "path": "appdaemon", "content": "WyJoYWNzLXRlc3Qtb3JnL2FwcGRhZW1vbi1iYXNpYyJd", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs/default/contents/appdaemon", "git_url": "https://api.github.com/repos/hacs/default/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs/default/blob/main/appdaemon", "download_url": "https://raw.githubusercontent.com/hacs/default/main/appdaemon", "_links": { "git": "https://api.github.com/repos/hacs/default/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs/default/contents/appdaemon", "html": "https://github.com/hacs/default/blob/main/appdaemon" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs/default/contents/integration.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "integration", "path": "integration", "content": "WyJoYWNzLXRlc3Qtb3JnL2ludGVncmF0aW9uLWJhc2ljIiwgImhhY3MtdGVzdC1vcmcvcmVtb3ZlZC1yZXBvc2l0b3J5IiwgImhhY3MtdGVzdC1vcmcvaW50ZWdyYXRpb24tYmFzaWMtY3VzdG9tIl0=", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs/default/contents/integration", "git_url": "https://api.github.com/repos/hacs/default/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs/default/blob/main/integration", "download_url": "https://raw.githubusercontent.com/hacs/default/main/integration", "_links": { "git": "https://api.github.com/repos/hacs/default/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs/default/contents/integration", "html": "https://github.com/hacs/default/blob/main/integration" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs/default/contents/plugin.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "plugin", "path": "plugin", "content": "WyJoYWNzLXRlc3Qtb3JnL3BsdWdpbi1iYXNpYyJd", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs/default/contents/plugin", "git_url": "https://api.github.com/repos/hacs/default/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs/default/blob/main/plugin", "download_url": "https://raw.githubusercontent.com/hacs/default/main/plugin", "_links": { "git": "https://api.github.com/repos/hacs/default/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs/default/contents/plugin", "html": "https://github.com/hacs/default/blob/main/plugin" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs/default/contents/python_script.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "python_script", "path": "python_script", "content": "WyJoYWNzLXRlc3Qtb3JnL3B5dGhvbl9zY3JpcHQtYmFzaWMiXQ==", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs/default/contents/python_script", "git_url": "https://api.github.com/repos/hacs/default/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs/default/blob/main/python_script", "download_url": "https://raw.githubusercontent.com/hacs/default/main/python_script", "_links": { "git": "https://api.github.com/repos/hacs/default/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs/default/contents/python_script", "html": "https://github.com/hacs/default/blob/main/python_script" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs/default/contents/template.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "template", "path": "template", "content": "WyJoYWNzLXRlc3Qtb3JnL3RlbXBsYXRlLWJhc2ljIl0=", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs/default/contents/template", "git_url": "https://api.github.com/repos/hacs/default/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs/default/blob/main/template", "download_url": "https://raw.githubusercontent.com/hacs/default/main/template", "_links": { "git": "https://api.github.com/repos/hacs/default/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs/default/contents/template", "html": "https://github.com/hacs/default/blob/main/template" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs/default/contents/theme.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "theme", "path": "theme", "content": "WyJoYWNzLXRlc3Qtb3JnL3RoZW1lLWJhc2ljIl0=", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs/default/contents/theme", "git_url": "https://api.github.com/repos/hacs/default/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs/default/blob/main/theme", "download_url": "https://raw.githubusercontent.com/hacs/default/main/theme", "_links": { "git": "https://api.github.com/repos/hacs/default/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs/default/contents/theme", "html": "https://github.com/hacs/default/blob/main/theme" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "manifest.json", "path": "custom_components/hacs/manifest.json", "content": "ewogICJuYW1lIjogIkhBQ1MiLAogICJkb21haW4iOiAiaGFjcyIKfQ==", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json", "git_url": "https://api.github.com/repos/hacs/integration/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs/integration/blob/maincustom_components/hacs/manifest.json", "download_url": "https://raw.githubusercontent.com/hacs/integration/main/custom_components/hacs/manifest.json", "_links": { "git": "https://api.github.com/repos/hacs/integration/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json", "html": "https://github.com/hacs/integration/blob/main/custom_components/hacs/manifest.json" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs/integration/contents/hacs.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "hacs.json", "path": "hacs.json", "content": "ewogICAgIm5hbWUiOiAiSEFDUyIKfQ==", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/contents/hacs.json", "git_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs-test-org/integration-basic/blob/master/hacs.json", "download_url": "https://raw.githubusercontent.com/hacs-test-org/integration-basic/master/hacs.json", "_links": { "git": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs-test-org/integration-basic/contents/hacs.json", "html": "https://github.com/hacs-test-org/integration-basic/blob/master/hacs.json" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs/integration/git/trees/main.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "custom_components", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs/integration/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "custom_components/hacs", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs/integration/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "custom_components/hacs/__init__.py", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs/integration/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "custom_components/hacs/manifest.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs/integration/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs/integration/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs/integration.json ================================================ { "id": 172733314, "node_id": "MDEwOlJlcG9zaXRvcnkxNzI3MzMzMTQ=", "name": "integration", "full_name": "hacs/integration", "private": false, "owner": { "login": "hacs", "id": 56713226, "node_id": "MDEyOk9yZ2FuaXphdGlvbjU2NzEzMjI2", "avatar_url": "https://avatars.githubusercontent.com/u/56713226?v=4", "gravatar_id": "", "url": "https://api.github.com/users/hacs", "html_url": "https://github.com/hacs", "followers_url": "https://api.github.com/users/hacs/followers", "following_url": "https://api.github.com/users/hacs/following{/other_user}", "gists_url": "https://api.github.com/users/hacs/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs/subscriptions", "organizations_url": "https://api.github.com/users/hacs/orgs", "repos_url": "https://api.github.com/users/hacs/repos", "events_url": "https://api.github.com/users/hacs/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs/received_events", "type": "Organization", "site_admin": false }, "html_url": "https://github.com/hacs/integration", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "fork": false, "url": "https://api.github.com/repos/hacs/integration", "forks_url": "https://api.github.com/repos/hacs/integration/forks", "keys_url": "https://api.github.com/repos/hacs/integration/keys{/key_id}", "collaborators_url": "https://api.github.com/repos/hacs/integration/collaborators{/collaborator}", "teams_url": "https://api.github.com/repos/hacs/integration/teams", "hooks_url": "https://api.github.com/repos/hacs/integration/hooks", "issue_events_url": "https://api.github.com/repos/hacs/integration/issues/events{/number}", "events_url": "https://api.github.com/repos/hacs/integration/events", "assignees_url": "https://api.github.com/repos/hacs/integration/assignees{/user}", "branches_url": "https://api.github.com/repos/hacs/integration/branches{/branch}", "tags_url": "https://api.github.com/repos/hacs/integration/tags", "blobs_url": "https://api.github.com/repos/hacs/integration/git/blobs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs/integration/git/tags{/sha}", "git_refs_url": "https://api.github.com/repos/hacs/integration/git/refs{/sha}", "trees_url": "https://api.github.com/repos/hacs/integration/git/trees{/sha}", "statuses_url": "https://api.github.com/repos/hacs/integration/statuses/{sha}", "languages_url": "https://api.github.com/repos/hacs/integration/languages", "stargazers_url": "https://api.github.com/repos/hacs/integration/stargazers", "contributors_url": "https://api.github.com/repos/hacs/integration/contributors", "subscribers_url": "https://api.github.com/repos/hacs/integration/subscribers", "subscription_url": "https://api.github.com/repos/hacs/integration/subscription", "commits_url": "https://api.github.com/repos/hacs/integration/commits{/sha}", "git_commits_url": "https://api.github.com/repos/hacs/integration/git/commits{/sha}", "comments_url": "https://api.github.com/repos/hacs/integration/comments{/number}", "issue_comment_url": "https://api.github.com/repos/hacs/integration/issues/comments{/number}", "contents_url": "https://api.github.com/repos/hacs/integration/contents/{+path}", "compare_url": "https://api.github.com/repos/hacs/integration/compare/{base}...{head}", "merges_url": "https://api.github.com/repos/hacs/integration/merges", "archive_url": "https://api.github.com/repos/hacs/integration/{archive_format}{/ref}", "downloads_url": "https://api.github.com/repos/hacs/integration/downloads", "issues_url": "https://api.github.com/repos/hacs/integration/issues{/number}", "pulls_url": "https://api.github.com/repos/hacs/integration/pulls{/number}", "milestones_url": "https://api.github.com/repos/hacs/integration/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs/integration/notifications{?since,all,participating}", "labels_url": "https://api.github.com/repos/hacs/integration/labels{/name}", "releases_url": "https://api.github.com/repos/hacs/integration/releases{/id}", "deployments_url": "https://api.github.com/repos/hacs/integration/deployments", "created_at": "2019-02-26T15:01:10Z", "updated_at": "2023-11-19T03:16:34Z", "pushed_at": "2023-11-18T21:22:03Z", "git_url": "git://github.com/hacs/integration.git", "ssh_url": "git@github.com:hacs/integration.git", "clone_url": "https://github.com/hacs/integration.git", "svn_url": "https://github.com/hacs/integration", "homepage": "https://hacs.xyz", "size": 12343, "stargazers_count": 4065, "watchers_count": 4065, "language": "Python", "has_issues": true, "has_projects": false, "has_downloads": false, "has_wiki": false, "has_pages": false, "has_discussions": false, "forks_count": 1067, "mirror_url": null, "archived": false, "disabled": false, "open_issues_count": 2, "license": { "key": "mit", "name": "MIT License", "spdx_id": "MIT", "url": "https://api.github.com/licenses/mit", "node_id": "MDc6TGljZW5zZTEz" }, "allow_forking": true, "is_template": false, "web_commit_signoff_required": false, "topics": [ "community", "hacktoberfest", "hacs", "home-assistant", "integration", "package-manager", "python" ], "visibility": "public", "forks": 1067, "open_issues": 2, "watchers": 4065, "default_branch": "main", "temp_clone_token": null, "organization": { "login": "hacs", "id": 56713226, "node_id": "MDEyOk9yZ2FuaXphdGlvbjU2NzEzMjI2", "avatar_url": "https://avatars.githubusercontent.com/u/56713226?v=4", "gravatar_id": "", "url": "https://api.github.com/users/hacs", "html_url": "https://github.com/hacs", "followers_url": "https://api.github.com/users/hacs/followers", "following_url": "https://api.github.com/users/hacs/following{/other_user}", "gists_url": "https://api.github.com/users/hacs/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs/subscriptions", "organizations_url": "https://api.github.com/users/hacs/orgs", "repos_url": "https://api.github.com/users/hacs/repos", "events_url": "https://api.github.com/users/hacs/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs/received_events", "type": "Organization", "site_admin": false }, "network_count": 1067, "subscribers_count": 97 } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/addon-basic/git/trees/main.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org//trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org//git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "repository.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org//git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/addon-basic/releases.json ================================================ [] ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/addon-basic.json ================================================ { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "addon", "full_name": "hacs-test-org/addon-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/addon-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/addon-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/addon-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/addon-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/addon-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/addon-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/addon-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/addon-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/addon-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/addon-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/addon-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/addon-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/addon-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/addon-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/addon-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/addon-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/addon-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/addon-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/addon-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/addon-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/addon-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/addon-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/addon-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/addon-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/addon-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/addon-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/addon-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/addon-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/addon-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/addon-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/addon-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/addon-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/addon-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/addon-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/addon-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/addon-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/addon-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/addon-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/addon-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/addon-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/addon-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/addon-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/addon-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "forks": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "open_issues": 0, "is_template": false, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "has_discussions": false, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "pull": true, "push": false, "admin": false }, "allow_rebase_merge": true, "template_repository": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "addon-Template", "full_name": "hacs-test-org/addon-basic-Template", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/addon-basic-Template", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template", "archive_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/events", "forks_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/addon-basic-Template.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/addon-basic-Template.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/addon-basic-Template.git", "mirror_url": "git:git.example.com/hacs-test-org/addon-basic-Template", "hooks_url": "https://api.github.com/repos/hacs-test-org/addon-basic-Template/hooks", "svn_url": "https://svn.github.com/hacs-test-org/addon-basic-Template", "homepage": "https://github.com", "language": null, "forks": 9, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues": 0, "open_issues_count": 0, "is_template": true, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0 }, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "spdx_id": "MIT", "url": "https://api.github.com/licenses/mit", "node_id": "MDc6TGljZW5zZW1pdA==" }, "organization": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "Organization", "site_admin": false }, "parent": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "addon", "full_name": "hacs-test-org/addon-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/addon-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/addon-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/addon-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/addon-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/addon-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/addon-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/addon-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/addon-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/addon-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/addon-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/addon-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/addon-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/addon-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/addon-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/addon-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/addon-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/addon-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/addon-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/addon-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/addon-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/addon-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/addon-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/addon-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/addon-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/addon-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/addon-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/addon-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/addon-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/addon-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/addon-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/addon-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/addon-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/addon-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/addon-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/addon-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/addon-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/addon-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/addon-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/addon-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/addon-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/addon-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/addon-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/addon-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_template": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1 }, "source": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "addon", "full_name": "hacs-test-org/addon-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/addon-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/addon-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/addon-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/addon-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/addon-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/addon-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/addon-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/addon-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/addon-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/addon-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/addon-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/addon-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/addon-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/addon-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/addon-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/addon-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/addon-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/addon-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/addon-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/addon-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/addon-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/addon-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/addon-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/addon-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/addon-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/addon-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/addon-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/addon-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/addon-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/addon-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/addon-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/addon-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/addon-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/addon-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/addon-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/addon-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/addon-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/addon-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/addon-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/addon-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/addon-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/addon-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/addon-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_template": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1, "security_and_analysis": { "advanced_security": { "status": "enabled" }, "secret_scanning": { "status": "enabled" }, "secret_scanning_push_protection": { "status": "disabled" } } } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/branches/main.json ================================================ { "name": "main", "commit": { "sha": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "node_id": "MDY6Q29tbWl0MTI5NjI2OTo3ZmQxYTYwYjAxZjkxYjMxNGY1OTk1NWE0ZTRkNGU4MGQ4ZWRmMTFk", "commit": { "author": { "name": "The Octocat", "email": "octocat@nowhere.com", "date": "2012-03-06T23:06:50Z" }, "committer": { "name": "The Octocat", "email": "octocat@nowhere.com", "date": "2012-03-06T23:06:50Z" }, "message": "Merge pull request #6 from Spaceghost/patch-1\n\nNew line at end of file.", "tree": { "sha": "b4eecafa9be2f2006ce1b709d6857b07069b4608", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/b4eecafa9be2f2006ce1b709d6857b07069b4608" }, "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "comment_count": 77, "verification": { "verified": false, "reason": "unsigned", "signature": null, "payload": null } }, "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d/comments", "author": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "committer": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "parents": [ { "sha": "553c2077f0edc3d5dc5d17262f6aa498e69d6f8e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/553c2077f0edc3d5dc5d17262f6aa498e69d6f8e", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/553c2077f0edc3d5dc5d17262f6aa498e69d6f8e" }, { "sha": "762941318ee16e59dabbacb1b4049eec22f0d303", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/762941318ee16e59dabbacb1b4049eec22f0d303", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/762941318ee16e59dabbacb1b4049eec22f0d303" } ] }, "_links": { "self": "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main", "html": "https://github.com/hacs-test-org/integration-basic/tree/main" }, "protected": false, "protection": { "enabled": false, "required_status_checks": { "enforcement_level": "off", "contexts": [], "checks": [] } }, "protection_url": "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main/protection" } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps/example.json ================================================ [ { "type": "file", "size": 0, "name": "__init__.py", "path": "apps/example/__init__.py", "sha": "a84d88e7554fc1fa21bcbc4efae3c782a70d2b9d", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps/example/__init__.py", "git_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/a84d88e7554fc1fa21bcbc4efae3c782a70d2b9d", "html_url": "https://github.com/hacs-test-org/appdaemon-basic/tree/master/apps/example/__init__.py", "download_url": null, "_links": { "self": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps/example/__init__.py", "git": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/a84d88e7554fc1fa21bcbc4efae3c782a70d2b9d", "html": "https://github.com/hacs-test-org/appdaemon-basic/tree/master/apps/example/__init__.py" } } ] ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps.json ================================================ [ { "type": "dir", "size": 0, "name": "example", "path": "apps/example", "sha": "a84d88e7554fc1fa21bcbc4efae3c782a70d2b9d", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps/example", "git_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/a84d88e7554fc1fa21bcbc4efae3c782a70d2b9d", "html_url": "https://github.com/hacs-test-org/appdaemon-basic/tree/master/apps/example", "download_url": null, "_links": { "self": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps/example", "git": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/a84d88e7554fc1fa21bcbc4efae3c782a70d2b9d", "html": "https://github.com/hacs-test-org/appdaemon-basic/tree/master/apps/example" } } ] ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/contents/hacs.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "hacs.json", "path": "hacs.json", "content": "ewogICAgIm5hbWUiOiAiRXhhbXBsZSBhcHAiCn0=", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/hacs.json", "git_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs-test-org/appdaemon-basic/blob/master/hacs.json", "download_url": "https://raw.githubusercontent.com/hacs-test-org/appdaemon-basic/master/hacs.json", "_links": { "git": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/hacs.json", "html": "https://github.com/hacs-test-org/appdaemon-basic/blob/master/hacs.json" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "appdaemons", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "appdaemons/example.yaml", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/2.0.0.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "appdaemons", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "appdaemons/example.yaml", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/main.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "appdaemons", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "appdaemons/example.yaml", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic/releases.json ================================================ [ { "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases/1", "html_url": "https://github.com/hacs-test-org/appdaemon-basic/releases/1.0.0", "assets_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases/1/assets", "upload_url": "https://uploads.github.com/repos/hacs-test-org/appdaemon-basic/releases/1/assets{?name,label}", "tarball_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/tarball/1.0.0", "zipball_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/zipball/1.0.0", "id": 1, "node_id": "MDc6UmVsZWFzZTE=", "tag_name": "1.0.0", "target_commitish": "master", "name": "1.0.0", "body": "Description of the release", "draft": false, "prerelease": false, "created_at": "2013-02-27T19:35:32Z", "published_at": "2013-02-27T19:35:32Z", "author": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "assets": [] } ] ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/appdaemon-basic.json ================================================ { "id": 1296265, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "appdaemon", "full_name": "hacs-test-org/appdaemon-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/appdaemon-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/appdaemon-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/appdaemon-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/appdaemon-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/appdaemon-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/appdaemon-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "forks": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "open_issues": 0, "is_appdaemon": false, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "has_discussions": false, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "pull": true, "push": false, "admin": false }, "allow_rebase_merge": true, "appdaemon_repository": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "appdaemon-appdaemon", "full_name": "hacs-test-org/appdaemon-basic-appdaemon", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/appdaemon-basic-appdaemon", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon", "archive_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/events", "forks_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/appdaemon-basic-appdaemon.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/appdaemon-basic-appdaemon.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/appdaemon-basic-appdaemon.git", "mirror_url": "git:git.example.com/hacs-test-org/appdaemon-basic-appdaemon", "hooks_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic-appdaemon/hooks", "svn_url": "https://svn.github.com/hacs-test-org/appdaemon-basic-appdaemon", "homepage": "https://github.com", "language": null, "forks": 9, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues": 0, "open_issues_count": 0, "is_appdaemon": true, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0 }, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "spdx_id": "MIT", "url": "https://api.github.com/licenses/mit", "node_id": "MDc6TGljZW5zZW1pdA==" }, "organization": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "Organization", "site_admin": false }, "parent": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "appdaemon", "full_name": "hacs-test-org/appdaemon-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/appdaemon-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/appdaemon-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/appdaemon-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/appdaemon-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/appdaemon-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/appdaemon-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_appdaemon": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1 }, "source": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "appdaemon", "full_name": "hacs-test-org/appdaemon-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/appdaemon-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/appdaemon-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/appdaemon-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/appdaemon-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/appdaemon-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/appdaemon-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/appdaemon-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_appdaemon": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1, "security_and_analysis": { "advanced_security": { "status": "enabled" }, "secret_scanning": { "status": "enabled" }, "secret_scanning_push_protection": { "status": "disabled" } } } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-basic/branches/main.json ================================================ { "name": "main", "commit": { "sha": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "node_id": "MDY6Q29tbWl0MTI5NjI2OTo3ZmQxYTYwYjAxZjkxYjMxNGY1OTk1NWE0ZTRkNGU4MGQ4ZWRmMTFk", "commit": { "author": { "name": "The Octocat", "email": "octocat@nowhere.com", "date": "2012-03-06T23:06:50Z" }, "committer": { "name": "The Octocat", "email": "octocat@nowhere.com", "date": "2012-03-06T23:06:50Z" }, "message": "Merge pull request #6 from Spaceghost/patch-1\n\nNew line at end of file.", "tree": { "sha": "b4eecafa9be2f2006ce1b709d6857b07069b4608", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/b4eecafa9be2f2006ce1b709d6857b07069b4608" }, "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "comment_count": 77, "verification": { "verified": false, "reason": "unsigned", "signature": null, "payload": null } }, "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d/comments", "author": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "committer": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "parents": [ { "sha": "553c2077f0edc3d5dc5d17262f6aa498e69d6f8e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/553c2077f0edc3d5dc5d17262f6aa498e69d6f8e", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/553c2077f0edc3d5dc5d17262f6aa498e69d6f8e" }, { "sha": "762941318ee16e59dabbacb1b4049eec22f0d303", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/762941318ee16e59dabbacb1b4049eec22f0d303", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/762941318ee16e59dabbacb1b4049eec22f0d303" } ] }, "_links": { "self": "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main", "html": "https://github.com/hacs-test-org/integration-basic/tree/main" }, "protected": false, "protection": { "enabled": false, "required_status_checks": { "enforcement_level": "off", "contexts": [], "checks": [] } }, "protection_url": "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main/protection" } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-basic/contents/custom_components/example/manifest.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "manifest.json", "path": "custom_components/example/manifest.json", "content": "ewogICAgIm5hbWUiOiAiUHJveHkgbWFuaWZlc3QiLAogICAgImRvbWFpbiI6ICJleGFtcGxlIiwKICAgICJjb25maWdfZmxvdyI6IHRydWUKfQ==", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/contents/custom_components/example/manifest.json", "git_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs-test-org/integration-basic/blob/maincustom_components/example//manifest.json", "download_url": "https://raw.githubusercontent.com/hacs-test-org/integration-basic/main/custom_components/example/manifest.json", "_links": { "git": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs-test-org/integration-basic/contents/custom_components/example/manifest.json", "html": "https://github.com/hacs-test-org/integration-basic/blob/main/custom_components/example/manifest.json" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-basic/contents/hacs.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "hacs.json", "path": "hacs.json", "content": "ewogICAgIm5hbWUiOiAiUHJveHkgbWFuaWZlc3QiCn0=", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/contents/hacs.json", "git_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs-test-org/integration-basic/blob/master/hacs.json", "download_url": "https://raw.githubusercontent.com/hacs-test-org/integration-basic/master/hacs.json", "_links": { "git": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs-test-org/integration-basic/contents/hacs.json", "html": "https://github.com/hacs-test-org/integration-basic/blob/master/hacs.json" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-basic/git/trees/1.0.0.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "custom_components", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "custom_components/example", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "custom_components/example/manifest.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-basic/git/trees/2.0.0.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "custom_components", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "custom_components/example", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "custom_components/example/manifest.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "custom_components/example/__init__.py", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-basic/git/trees/main.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "custom_components", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "custom_components/example", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "custom_components/example/manifest.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-basic/releases/latest.json ================================================ { "url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases/1", "html_url": "https://github.com/hacs-test-org/integration-basic/releases/1.0.0", "assets_url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases/1/assets", "upload_url": "https://uploads.github.com/repos/hacs-test-org/integration-basic/releases/1/assets{?name,label}", "tarball_url": "https://api.github.com/repos/hacs-test-org/integration-basic/tarball/1.0.0", "zipball_url": "https://api.github.com/repos/hacs-test-org/integration-basic/zipball/1.0.0", "id": 1, "node_id": "MDc6UmVsZWFzZTE=", "tag_name": "1.0.0", "target_commitish": "master", "name": "1.0.0", "body": "Description of the release", "draft": false, "prerelease": false, "created_at": "2013-02-27T19:35:32Z", "published_at": "2013-02-27T19:35:32Z", "author": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "assets": [ { "url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases/assets/1", "browser_download_url": "https://github.com/hacs-test-org/integration-basic/releases/download/1.0.0/example.zip", "id": 1, "node_id": "MDEyOlJlbGVhc2VBc3NldDE=", "name": "example.zip", "label": "short description", "state": "uploaded", "content_type": "application/zip", "size": 1024, "download_count": 42, "created_at": "2013-02-27T19:35:32Z", "updated_at": "2013-02-27T19:35:32Z", "uploader": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false } } ] } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-basic/releases.json ================================================ [ { "url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases/4", "html_url": "https://github.com/hacs-test-org/integration-basic/releases/3.0.0", "assets_url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases/4/assets", "upload_url": "https://uploads.github.com/repos/hacs-test-org/integration-basic/releases/4/assets{?name,label}", "tarball_url": "https://api.github.com/repos/hacs-test-org/integration-basic/tarball/3.0.0", "zipball_url": "https://api.github.com/repos/hacs-test-org/integration-basic/zipball/3.0.0", "id": 4, "node_id": "MDc6UmVsZWFzZTE=", "tag_name": "3.0.0", "target_commitish": "master", "name": "3.0.0", "body": "Description of the release", "draft": false, "prerelease": true, "created_at": "2013-02-27T19:35:32Z", "published_at": "2013-02-27T19:35:32Z", "author": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "assets": [ { "url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases/assets/4", "browser_download_url": "https://github.com/hacs-test-org/integration-basic/releases/download/3.0.0/example.zip", "id": 1, "node_id": "MDEyOlJlbGVhc2VBc3NldDE=", "name": "example.zip", "label": "short description", "state": "uploaded", "content_type": "application/zip", "size": 321024, "download_count": 3242, "created_at": "2013-02-27T19:35:32Z", "updated_at": "2013-02-27T19:35:32Z", "uploader": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false } } ] }, { "url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases/3", "html_url": "https://github.com/hacs-test-org/integration-basic/releases/2.5.0", "assets_url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases/3/assets", "upload_url": "https://uploads.github.com/repos/hacs-test-org/integration-basic/releases/3/assets{?name,label}", "tarball_url": "https://api.github.com/repos/hacs-test-org/integration-basic/tarball/2.5.0", "zipball_url": "https://api.github.com/repos/hacs-test-org/integration-basic/zipball/2.5.0", "id": 3, "node_id": "MDc6UmVsZWFzZTE=", "tag_name": "2.5.0", "target_commitish": "master", "name": "2.5.0", "body": "Description of the release", "draft": false, "prerelease": true, "created_at": "2013-02-27T19:35:32Z", "published_at": "2013-02-27T19:35:32Z", "author": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "assets": [ { "url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases/assets/3", "browser_download_url": "https://github.com/hacs-test-org/integration-basic/releases/download/2.5.0/example.zip", "id": 1, "node_id": "MDEyOlJlbGVhc2VBc3NldDE=", "name": "example.zip", "label": "short description", "state": "uploaded", "content_type": "application/zip", "size": 321024, "download_count": 32425, "created_at": "2013-02-27T19:35:32Z", "updated_at": "2013-02-27T19:35:32Z", "uploader": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false } } ] }, { "url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases/2", "html_url": "https://github.com/hacs-test-org/integration-basic/releases/2.0.0", "assets_url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases/2/assets", "upload_url": "https://uploads.github.com/repos/hacs-test-org/integration-basic/releases/2/assets{?name,label}", "tarball_url": "https://api.github.com/repos/hacs-test-org/integration-basic/tarball/2.0.0", "zipball_url": "https://api.github.com/repos/hacs-test-org/integration-basic/zipball/2.0.0", "id": 2, "node_id": "MDc6UmVsZWFzZTE=", "tag_name": "2.0.0", "target_commitish": "master", "name": "2.0.0", "body": "Description of the release", "draft": true, "prerelease": false, "created_at": "2013-02-27T19:35:32Z", "published_at": "2013-02-27T19:35:32Z", "author": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "assets": [ { "url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases/assets/2", "browser_download_url": "https://github.com/hacs-test-org/integration-basic/releases/download/2.0.0/example.zip", "id": 1, "node_id": "MDEyOlJlbGVhc2VBc3NldDE=", "name": "example.zip", "label": "short description", "state": "uploaded", "content_type": "application/zip", "size": 21024, "download_count": 242, "created_at": "2013-02-27T19:35:32Z", "updated_at": "2013-02-27T19:35:32Z", "uploader": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false } } ] }, { "url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases/1", "html_url": "https://github.com/hacs-test-org/integration-basic/releases/1.0.0", "assets_url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases/1/assets", "upload_url": "https://uploads.github.com/repos/hacs-test-org/integration-basic/releases/1/assets{?name,label}", "tarball_url": "https://api.github.com/repos/hacs-test-org/integration-basic/tarball/1.0.0", "zipball_url": "https://api.github.com/repos/hacs-test-org/integration-basic/zipball/1.0.0", "id": 1, "node_id": "MDc6UmVsZWFzZTE=", "tag_name": "1.0.0", "target_commitish": "master", "name": "1.0.0", "body": "Description of the release", "draft": false, "prerelease": false, "created_at": "2013-02-27T19:35:32Z", "published_at": "2013-02-27T19:35:32Z", "author": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "assets": [ { "url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases/assets/1", "browser_download_url": "https://github.com/hacs-test-org/integration-basic/releases/download/1.0.0/example.zip", "id": 1, "node_id": "MDEyOlJlbGVhc2VBc3NldDE=", "name": "example.zip", "label": "short description", "state": "uploaded", "content_type": "application/zip", "size": 1024, "download_count": 42, "created_at": "2013-02-27T19:35:32Z", "updated_at": "2013-02-27T19:35:32Z", "uploader": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false } } ] } ] ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-basic-custom/branches/main.json ================================================ { "name": "main", "commit": { "sha": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "node_id": "MDY6Q29tbWl0MTI5NjI2OTo3ZmQxYTYwYjAxZjkxYjMxNGY1OTk1NWE0ZTRkNGU4MGQ4ZWRmMTFk", "commit": { "author": { "name": "The Octocat", "email": "octocat@nowhere.com", "date": "2012-03-06T23:06:50Z" }, "committer": { "name": "The Octocat", "email": "octocat@nowhere.com", "date": "2012-03-06T23:06:50Z" }, "message": "Merge pull request #6 from Spaceghost/patch-1\n\nNew line at end of file.", "tree": { "sha": "b4eecafa9be2f2006ce1b709d6857b07069b4608", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/trees/b4eecafa9be2f2006ce1b709d6857b07069b4608" }, "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "comment_count": 77, "verification": { "verified": false, "reason": "unsigned", "signature": null, "payload": null } }, "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "html_url": "https://github.com/hacs-test-org/integration-basic-custom/commit/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d/comments", "author": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "committer": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "parents": [ { "sha": "553c2077f0edc3d5dc5d17262f6aa498e69d6f8e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/commits/553c2077f0edc3d5dc5d17262f6aa498e69d6f8e", "html_url": "https://github.com/hacs-test-org/integration-basic-custom/commit/553c2077f0edc3d5dc5d17262f6aa498e69d6f8e" }, { "sha": "762941318ee16e59dabbacb1b4049eec22f0d303", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/commits/762941318ee16e59dabbacb1b4049eec22f0d303", "html_url": "https://github.com/hacs-test-org/integration-basic-custom/commit/762941318ee16e59dabbacb1b4049eec22f0d303" } ] }, "_links": { "self": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/branches/main", "html": "https://github.com/hacs-test-org/integration-basic-custom/tree/main" }, "protected": false, "protection": { "enabled": false, "required_status_checks": { "enforcement_level": "off", "contexts": [], "checks": [] } }, "protection_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/branches/main/protection" } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-basic-custom/contents/custom_components/example/manifest.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "manifest.json", "path": "custom_components/example/manifest.json", "content": "ewogICAgIm5hbWUiOiAiUHJveHkgbWFuaWZlc3QiLAogICAgImRvbWFpbiI6ICJleGFtcGxlIgp9", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/custom_components/example/manifest.json", "git_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs-test-org/integration-basic-custom/blob/maincustom_components/example//manifest.json", "download_url": "https://raw.githubusercontent.com/hacs-test-org/integration-basic-custom/main/custom_components/example/manifest.json", "_links": { "git": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/custom_components/example/manifest.json", "html": "https://github.com/hacs-test-org/integration-basic-custom/blob/main/custom_components/example/manifest.json" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-basic-custom/contents/hacs.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "hacs.json", "path": "hacs.json", "content": "ewogICAgIm5hbWUiOiAiUHJveHkgbWFuaWZlc3QiCn0=", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/hacs.json", "git_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs-test-org/integration-basic-custom/blob/master/hacs.json", "download_url": "https://raw.githubusercontent.com/hacs-test-org/integration-basic-custom/master/hacs.json", "_links": { "git": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/hacs.json", "html": "https://github.com/hacs-test-org/integration-basic-custom/blob/master/hacs.json" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-basic-custom/git/trees/1.0.0.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "custom_components", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "custom_components/example", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "custom_components/example/manifest.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-basic-custom/git/trees/2.0.0.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "custom_components", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "custom_components/example", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "custom_components/example/manifest.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "custom_components/example/__init__.py", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-basic-custom/git/trees/main.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "custom_components", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "custom_components/example", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "custom_components/example/manifest.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-basic-custom/releases.json ================================================ [ { "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/releases/1", "html_url": "https://github.com/hacs-test-org/integration-basic-custom/releases/1.0.0", "assets_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/releases/1/assets", "upload_url": "https://uploads.github.com/repos/hacs-test-org/integration-basic-custom/releases/1/assets{?name,label}", "tarball_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/tarball/1.0.0", "zipball_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/zipball/1.0.0", "id": 1, "node_id": "MDc6UmVsZWFzZTE=", "tag_name": "1.0.0", "target_commitish": "master", "name": "1.0.0", "body": "Description of the release", "draft": false, "prerelease": false, "created_at": "2013-02-27T19:35:32Z", "published_at": "2013-02-27T19:35:32Z", "author": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "assets": [ { "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/releases/assets/1", "browser_download_url": "https://github.com/hacs-test-org/integration-basic-custom/releases/download/1.0.0/example.zip", "id": 1, "node_id": "MDEyOlJlbGVhc2VBc3NldDE=", "name": "example.zip", "label": "short description", "state": "uploaded", "content_type": "application/zip", "size": 1024, "download_count": 42, "created_at": "2013-02-27T19:35:32Z", "updated_at": "2013-02-27T19:35:32Z", "uploader": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false } } ] } ] ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-basic-custom.json ================================================ { "id": 91296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "integration", "full_name": "hacs-test-org/integration-basic-custom", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/integration-basic-custom", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom", "archive_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/events", "forks_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/integration-basic-custom.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/integration-basic-custom.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/integration-basic-custom.git", "mirror_url": "git:git.example.com/hacs-test-org/integration-basic-custom", "hooks_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/hooks", "svn_url": "https://svn.github.com/hacs-test-org/integration-basic-custom", "homepage": "https://github.com", "language": null, "forks_count": 9, "forks": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "open_issues": 0, "is_template": false, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "has_discussions": false, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "pull": true, "push": false, "admin": false }, "allow_rebase_merge": true, "template_repository": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "integration-Template", "full_name": "hacs-test-org/integration-basic-custom-Template", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/integration-basic-custom-Template", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template", "archive_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/events", "forks_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/integration-basic-custom-Template.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/integration-basic-custom-Template.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/integration-basic-custom-Template.git", "mirror_url": "git:git.example.com/hacs-test-org/integration-basic-custom-Template", "hooks_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom-Template/hooks", "svn_url": "https://svn.github.com/hacs-test-org/integration-basic-custom-Template", "homepage": "https://github.com", "language": null, "forks": 9, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues": 0, "open_issues_count": 0, "is_template": true, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0 }, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "spdx_id": "MIT", "url": "https://api.github.com/licenses/mit", "node_id": "MDc6TGljZW5zZW1pdA==" }, "organization": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "Organization", "site_admin": false }, "parent": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "integration", "full_name": "hacs-test-org/integration-basic-custom", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/integration-basic-custom", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom", "archive_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/events", "forks_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/integration-basic-custom.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/integration-basic-custom.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/integration-basic-custom.git", "mirror_url": "git:git.example.com/hacs-test-org/integration-basic-custom", "hooks_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/hooks", "svn_url": "https://svn.github.com/hacs-test-org/integration-basic-custom", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_template": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1 }, "source": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "integration", "full_name": "hacs-test-org/integration-basic-custom", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/integration-basic-custom", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom", "archive_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/events", "forks_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/integration-basic-custom.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/integration-basic-custom.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/integration-basic-custom.git", "mirror_url": "git:git.example.com/hacs-test-org/integration-basic-custom", "hooks_url": "https://api.github.com/repos/hacs-test-org/integration-basic-custom/hooks", "svn_url": "https://svn.github.com/hacs-test-org/integration-basic-custom", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_template": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1, "security_and_analysis": { "advanced_security": { "status": "enabled" }, "secret_scanning": { "status": "enabled" }, "secret_scanning_push_protection": { "status": "disabled" } } } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-basic.json ================================================ { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "integration", "full_name": "hacs-test-org/integration-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/integration-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/integration-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/integration-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/integration-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/integration-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/integration-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/integration-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/integration-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/integration-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/integration-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/integration-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/integration-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/integration-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/integration-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/integration-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/integration-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/integration-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/integration-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/integration-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/integration-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/integration-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/integration-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/integration-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/integration-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/integration-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/integration-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/integration-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/integration-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/integration-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/integration-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/integration-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/integration-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/integration-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/integration-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/integration-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "forks": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "open_issues": 0, "is_template": false, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "has_discussions": false, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "pull": true, "push": false, "admin": false }, "allow_rebase_merge": true, "template_repository": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "integration-Template", "full_name": "hacs-test-org/integration-basic-Template", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/integration-basic-Template", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template", "archive_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/events", "forks_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/integration-basic-Template.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/integration-basic-Template.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/integration-basic-Template.git", "mirror_url": "git:git.example.com/hacs-test-org/integration-basic-Template", "hooks_url": "https://api.github.com/repos/hacs-test-org/integration-basic-Template/hooks", "svn_url": "https://svn.github.com/hacs-test-org/integration-basic-Template", "homepage": "https://github.com", "language": null, "forks": 9, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues": 0, "open_issues_count": 0, "is_template": true, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0 }, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "spdx_id": "MIT", "url": "https://api.github.com/licenses/mit", "node_id": "MDc6TGljZW5zZW1pdA==" }, "organization": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "Organization", "site_admin": false }, "parent": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "integration", "full_name": "hacs-test-org/integration-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/integration-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/integration-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/integration-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/integration-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/integration-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/integration-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/integration-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/integration-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/integration-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/integration-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/integration-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/integration-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/integration-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/integration-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/integration-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/integration-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/integration-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/integration-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/integration-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/integration-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/integration-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/integration-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/integration-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/integration-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/integration-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/integration-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/integration-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/integration-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/integration-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/integration-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/integration-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/integration-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/integration-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/integration-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/integration-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_template": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1 }, "source": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "integration", "full_name": "hacs-test-org/integration-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/integration-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/integration-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/integration-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/integration-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/integration-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/integration-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/integration-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/integration-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/integration-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/integration-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/integration-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/integration-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/integration-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/integration-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/integration-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/integration-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/integration-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/integration-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/integration-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/integration-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/integration-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/integration-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/integration-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/integration-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/integration-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/integration-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/integration-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/integration-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/integration-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/integration-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/integration-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/integration-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/integration-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/integration-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/integration-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/integration-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_template": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1, "security_and_analysis": { "advanced_security": { "status": "enabled" }, "secret_scanning": { "status": "enabled" }, "secret_scanning_push_protection": { "status": "disabled" } } } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-invalid/git/trees/main.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/integration-invalid/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "custom_components", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "custom_components/manfest.json", "mode": "040000", "type": "blob", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/blobs/f484d249c660418515fb01c2b9662073663c242e" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-invalid/releases.json ================================================ [] ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/integration-invalid.json ================================================ { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "addon", "full_name": "hacs-test-org/integration-invalid", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/integration-invalid", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/integration-invalid", "archive_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/events", "forks_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/integration-invalid.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/integration-invalid.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/integration-invalid.git", "mirror_url": "git:git.example.com/hacs-test-org/integration-invalid", "hooks_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/hooks", "svn_url": "https://svn.github.com/hacs-test-org/integration-invalid", "homepage": "https://github.com", "language": null, "forks_count": 9, "forks": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "open_issues": 0, "is_template": false, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "has_discussions": false, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "pull": true, "push": false, "admin": false }, "allow_rebase_merge": true, "template_repository": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "addon-Template", "full_name": "hacs-test-org/integration-invalid-Template", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/integration-invalid-Template", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template", "archive_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/events", "forks_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/integration-invalid-Template.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/integration-invalid-Template.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/integration-invalid-Template.git", "mirror_url": "git:git.example.com/hacs-test-org/integration-invalid-Template", "hooks_url": "https://api.github.com/repos/hacs-test-org/integration-invalid-Template/hooks", "svn_url": "https://svn.github.com/hacs-test-org/integration-invalid-Template", "homepage": "https://github.com", "language": null, "forks": 9, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues": 0, "open_issues_count": 0, "is_template": true, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0 }, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "spdx_id": "MIT", "url": "https://api.github.com/licenses/mit", "node_id": "MDc6TGljZW5zZW1pdA==" }, "organization": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "Organization", "site_admin": false }, "parent": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "addon", "full_name": "hacs-test-org/integration-invalid", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/integration-invalid", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/integration-invalid", "archive_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/events", "forks_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/integration-invalid.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/integration-invalid.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/integration-invalid.git", "mirror_url": "git:git.example.com/hacs-test-org/integration-invalid", "hooks_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/hooks", "svn_url": "https://svn.github.com/hacs-test-org/integration-invalid", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_template": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1 }, "source": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "addon", "full_name": "hacs-test-org/integration-invalid", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/integration-invalid", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/integration-invalid", "archive_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/events", "forks_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/integration-invalid.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/integration-invalid.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/integration-invalid.git", "mirror_url": "git:git.example.com/hacs-test-org/integration-invalid", "hooks_url": "https://api.github.com/repos/hacs-test-org/integration-invalid/hooks", "svn_url": "https://svn.github.com/hacs-test-org/integration-invalid", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_template": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1, "security_and_analysis": { "advanced_security": { "status": "enabled" }, "secret_scanning": { "status": "enabled" }, "secret_scanning_push_protection": { "status": "disabled" } } } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/plugin-basic/branches/main.json ================================================ { "name": "main", "commit": { "sha": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "node_id": "MDY6Q29tbWl0MTI5NjI2OTo3ZmQxYTYwYjAxZjkxYjMxNGY1OTk1NWE0ZTRkNGU4MGQ4ZWRmMTFk", "commit": { "author": { "name": "The Octocat", "email": "octocat@nowhere.com", "date": "2012-03-06T23:06:50Z" }, "committer": { "name": "The Octocat", "email": "octocat@nowhere.com", "date": "2012-03-06T23:06:50Z" }, "message": "Merge pull request #6 from Spaceghost/patch-1\n\nNew line at end of file.", "tree": { "sha": "b4eecafa9be2f2006ce1b709d6857b07069b4608", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/b4eecafa9be2f2006ce1b709d6857b07069b4608" }, "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "comment_count": 77, "verification": { "verified": false, "reason": "unsigned", "signature": null, "payload": null } }, "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d/comments", "author": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "committer": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "parents": [ { "sha": "553c2077f0edc3d5dc5d17262f6aa498e69d6f8e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/553c2077f0edc3d5dc5d17262f6aa498e69d6f8e", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/553c2077f0edc3d5dc5d17262f6aa498e69d6f8e" }, { "sha": "762941318ee16e59dabbacb1b4049eec22f0d303", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/762941318ee16e59dabbacb1b4049eec22f0d303", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/762941318ee16e59dabbacb1b4049eec22f0d303" } ] }, "_links": { "self": "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main", "html": "https://github.com/hacs-test-org/integration-basic/tree/main" }, "protected": false, "protection": { "enabled": false, "required_status_checks": { "enforcement_level": "off", "contexts": [], "checks": [] } }, "protection_url": "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main/protection" } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "hacs.json", "path": "hacs.json", "content": "ewogICAgIm5hbWUiOiAiUHJveHkgbWFuaWZlc3QiCn0=", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json", "git_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs-test-org/plugin-basic/blob/master/hacs.json", "download_url": "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/master/hacs.json", "_links": { "git": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json", "html": "https://github.com/hacs-test-org/plugin-basic/blob/master/hacs.json" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/plugin-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "plugin-basic.js", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/plugin-basic/git/trees/2.0.0.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/plugin-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "plugin-basic.js", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/plugin-basic/git/trees/main.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/plugin-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "plugin-basic.js", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/plugin-basic/releases.json ================================================ [ { "url": "https://api.github.com/repos/hacs-test-org/plugin-basic/releases/1", "html_url": "https://github.com/hacs-test-org/plugin-basic/releases/1.0.0", "assets_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/releases/1/assets", "upload_url": "https://uploads.github.com/repos/hacs-test-org/plugin-basic/releases/1/assets{?name,label}", "tarball_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/tarball/1.0.0", "zipball_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/zipball/1.0.0", "id": 1, "node_id": "MDc6UmVsZWFzZTE=", "tag_name": "1.0.0", "target_commitish": "master", "name": "1.0.0", "body": "Description of the release", "draft": false, "prerelease": false, "created_at": "2013-02-27T19:35:32Z", "published_at": "2013-02-27T19:35:32Z", "author": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "assets": [] } ] ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/plugin-basic.json ================================================ { "id": 1296267, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "plugin", "full_name": "hacs-test-org/plugin-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/plugin-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/plugin-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/plugin-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/plugin-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/plugin-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/plugin-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/plugin-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "forks": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "open_issues": 0, "is_template": false, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "has_discussions": false, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "pull": true, "push": false, "admin": false }, "allow_rebase_merge": true, "template_repository": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "plugin-plugin", "full_name": "hacs-test-org/plugin-basic-plugin", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/plugin-basic-plugin", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin", "archive_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/events", "forks_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/plugin-basic-plugin.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/plugin-basic-plugin.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/plugin-basic-plugin.git", "mirror_url": "git:git.example.com/hacs-test-org/plugin-basic-plugin", "hooks_url": "https://api.github.com/repos/hacs-test-org/plugin-basic-plugin/hooks", "svn_url": "https://svn.github.com/hacs-test-org/plugin-basic-plugin", "homepage": "https://github.com", "language": null, "forks": 9, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues": 0, "open_issues_count": 0, "is_template": true, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0 }, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "spdx_id": "MIT", "url": "https://api.github.com/licenses/mit", "node_id": "MDc6TGljZW5zZW1pdA==" }, "organization": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "Organization", "site_admin": false }, "parent": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "plugin", "full_name": "hacs-test-org/plugin-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/plugin-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/plugin-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/plugin-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/plugin-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/plugin-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/plugin-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/plugin-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_template": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1 }, "source": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "plugin", "full_name": "hacs-test-org/plugin-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/plugin-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/plugin-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/plugin-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/plugin-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/plugin-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/plugin-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/plugin-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/plugin-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_template": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1, "security_and_analysis": { "advanced_security": { "status": "enabled" }, "secret_scanning": { "status": "enabled" }, "secret_scanning_push_protection": { "status": "disabled" } } } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/plugin-custom-dist/branches/main.json ================================================ { "name": "main", "commit": { "sha": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "node_id": "MDY6Q29tbWl0MTI5NjI2OTo3ZmQxYTYwYjAxZjkxYjMxNGY1OTk1NWE0ZTRkNGU4MGQ4ZWRmMTFk", "commit": { "author": { "name": "The Octocat", "email": "octocat@nowhere.com", "date": "2012-03-06T23:06:50Z" }, "committer": { "name": "The Octocat", "email": "octocat@nowhere.com", "date": "2012-03-06T23:06:50Z" }, "message": "Merge pull request #6 from Spaceghost/patch-1\n\nNew line at end of file.", "tree": { "sha": "b4eecafa9be2f2006ce1b709d6857b07069b4608", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/b4eecafa9be2f2006ce1b709d6857b07069b4608" }, "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "comment_count": 77, "verification": { "verified": false, "reason": "unsigned", "signature": null, "payload": null } }, "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d/comments", "author": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "committer": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "parents": [ { "sha": "553c2077f0edc3d5dc5d17262f6aa498e69d6f8e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/553c2077f0edc3d5dc5d17262f6aa498e69d6f8e", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/553c2077f0edc3d5dc5d17262f6aa498e69d6f8e" }, { "sha": "762941318ee16e59dabbacb1b4049eec22f0d303", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/762941318ee16e59dabbacb1b4049eec22f0d303", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/762941318ee16e59dabbacb1b4049eec22f0d303" } ] }, "_links": { "self": "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main", "html": "https://github.com/hacs-test-org/integration-basic/tree/main" }, "protected": false, "protection": { "enabled": false, "required_status_checks": { "enforcement_level": "off", "contexts": [], "checks": [] } }, "protection_url": "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main/protection" } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/plugin-custom-dist/contents/hacs.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "hacs.json", "path": "hacs.json", "content": "ewogICAgIm5hbWUiOiAiUHJveHkgbWFuaWZlc3QiCn0=", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/contents/hacs.json", "git_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs-test-org/plugin-custom-dist/blob/master/hacs.json", "download_url": "https://raw.githubusercontent.com/hacs-test-org/plugin-custom-dist/master/hacs.json", "_links": { "git": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/contents/hacs.json", "html": "https://github.com/hacs-test-org/plugin-custom-dist/blob/master/hacs.json" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/plugin-custom-dist/git/trees/1.0.0.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "dist", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "dist/plugin-custom-dist.js", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/plugin-custom-dist/git/trees/2.0.0.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "dist", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "dist/plugin-custom-dist.js", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/plugin-custom-dist/git/trees/main.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "dist", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "dist/plugin-custom-dist.js", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/plugin-custom-dist/releases.json ================================================ [ { "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/releases/1", "html_url": "https://github.com/hacs-test-org/plugin-custom-dist/releases/1.0.0", "assets_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/releases/1/assets", "upload_url": "https://uploads.github.com/repos/hacs-test-org/plugin-custom-dist/releases/1/assets{?name,label}", "tarball_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/tarball/1.0.0", "zipball_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/zipball/1.0.0", "id": 1, "node_id": "MDc6UmVsZWFzZTE=", "tag_name": "1.0.0", "target_commitish": "master", "name": "1.0.0", "body": "Description of the release", "draft": false, "prerelease": false, "created_at": "2013-02-27T19:35:32Z", "published_at": "2013-02-27T19:35:32Z", "author": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "assets": [] } ] ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/plugin-custom-dist.json ================================================ { "id": 12962674, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "plugin", "full_name": "hacs-test-org/plugin-custom-dist", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/plugin-custom-dist", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist", "archive_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/events", "forks_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/plugin-custom-dist.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/plugin-custom-dist.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/plugin-custom-dist.git", "mirror_url": "git:git.example.com/hacs-test-org/plugin-custom-dist", "hooks_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/hooks", "svn_url": "https://svn.github.com/hacs-test-org/plugin-custom-dist", "homepage": "https://github.com", "language": null, "forks_count": 9, "forks": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "open_issues": 0, "is_template": false, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "has_discussions": false, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "pull": true, "push": false, "admin": false }, "allow_rebase_merge": true, "template_repository": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "plugin-plugin", "full_name": "hacs-test-org/plugin-custom-dist-plugin", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/plugin-custom-dist-plugin", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin", "archive_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/events", "forks_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/plugin-custom-dist-plugin.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/plugin-custom-dist-plugin.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/plugin-custom-dist-plugin.git", "mirror_url": "git:git.example.com/hacs-test-org/plugin-custom-dist-plugin", "hooks_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist-plugin/hooks", "svn_url": "https://svn.github.com/hacs-test-org/plugin-custom-dist-plugin", "homepage": "https://github.com", "language": null, "forks": 9, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues": 0, "open_issues_count": 0, "is_template": true, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0 }, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "spdx_id": "MIT", "url": "https://api.github.com/licenses/mit", "node_id": "MDc6TGljZW5zZW1pdA==" }, "organization": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "Organization", "site_admin": false }, "parent": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "plugin", "full_name": "hacs-test-org/plugin-custom-dist", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/plugin-custom-dist", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist", "archive_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/events", "forks_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/plugin-custom-dist.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/plugin-custom-dist.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/plugin-custom-dist.git", "mirror_url": "git:git.example.com/hacs-test-org/plugin-custom-dist", "hooks_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/hooks", "svn_url": "https://svn.github.com/hacs-test-org/plugin-custom-dist", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_template": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1 }, "source": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "plugin", "full_name": "hacs-test-org/plugin-custom-dist", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/plugin-custom-dist", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist", "archive_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/events", "forks_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/plugin-custom-dist.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/plugin-custom-dist.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/plugin-custom-dist.git", "mirror_url": "git:git.example.com/hacs-test-org/plugin-custom-dist", "hooks_url": "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/hooks", "svn_url": "https://svn.github.com/hacs-test-org/plugin-custom-dist", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_template": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1, "security_and_analysis": { "advanced_security": { "status": "enabled" }, "secret_scanning": { "status": "enabled" }, "secret_scanning_push_protection": { "status": "disabled" } } } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/python_script-basic/branches/main.json ================================================ { "name": "main", "commit": { "sha": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "node_id": "MDY6Q29tbWl0MTI5NjI2OTo3ZmQxYTYwYjAxZjkxYjMxNGY1OTk1NWE0ZTRkNGU4MGQ4ZWRmMTFk", "commit": { "author": { "name": "The Octocat", "email": "octocat@nowhere.com", "date": "2012-03-06T23:06:50Z" }, "committer": { "name": "The Octocat", "email": "octocat@nowhere.com", "date": "2012-03-06T23:06:50Z" }, "message": "Merge pull request #6 from Spaceghost/patch-1\n\nNew line at end of file.", "tree": { "sha": "b4eecafa9be2f2006ce1b709d6857b07069b4608", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/b4eecafa9be2f2006ce1b709d6857b07069b4608" }, "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "comment_count": 77, "verification": { "verified": false, "reason": "unsigned", "signature": null, "payload": null } }, "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d/comments", "author": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "committer": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "parents": [ { "sha": "553c2077f0edc3d5dc5d17262f6aa498e69d6f8e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/553c2077f0edc3d5dc5d17262f6aa498e69d6f8e", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/553c2077f0edc3d5dc5d17262f6aa498e69d6f8e" }, { "sha": "762941318ee16e59dabbacb1b4049eec22f0d303", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/762941318ee16e59dabbacb1b4049eec22f0d303", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/762941318ee16e59dabbacb1b4049eec22f0d303" } ] }, "_links": { "self": "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main", "html": "https://github.com/hacs-test-org/integration-basic/tree/main" }, "protected": false, "protection": { "enabled": false, "required_status_checks": { "enforcement_level": "off", "contexts": [], "checks": [] } }, "protection_url": "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main/protection" } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/python_script-basic/contents/hacs.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "hacs.json", "path": "hacs.json", "content": "ewogICAgIm5hbWUiOiAiRXhhbXBsZSBhcHAiCn0=", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs-test-org/python_script-basic/contents/hacs.json", "git_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs-test-org/python_script-basic/blob/master/hacs.json", "download_url": "https://raw.githubusercontent.com/hacs-test-org/python_script-basic/master/hacs.json", "_links": { "git": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs-test-org/python_script-basic/contents/hacs.json", "html": "https://github.com/hacs-test-org/python_script-basic/blob/master/hacs.json" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/python_script-basic/git/trees/1.0.0.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/python_script-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "python_scripts", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "python_scripts/example.py", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/python_script-basic/git/trees/2.0.0.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/python_script-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "python_scripts", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "python_scripts/example.py", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/python_script-basic/git/trees/main.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/python_script-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "python_scripts", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "python_scripts/example.py", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/python_script-basic/releases.json ================================================ [ { "url": "https://api.github.com/repos/hacs-test-org/python_script-basic/releases/1", "html_url": "https://github.com/hacs-test-org/python_script-basic/releases/1.0.0", "assets_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/releases/1/assets", "upload_url": "https://uploads.github.com/repos/hacs-test-org/python_script-basic/releases/1/assets{?name,label}", "tarball_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/tarball/1.0.0", "zipball_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/zipball/1.0.0", "id": 1, "node_id": "MDc6UmVsZWFzZTE=", "tag_name": "1.0.0", "target_commitish": "master", "name": "1.0.0", "body": "Description of the release", "draft": false, "prerelease": false, "created_at": "2013-02-27T19:35:32Z", "published_at": "2013-02-27T19:35:32Z", "author": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "assets": [] } ] ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/python_script-basic.json ================================================ { "id": 1296262, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "python_script", "full_name": "hacs-test-org/python_script-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/python_script-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/python_script-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/python_script-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/python_script-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/python_script-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/python_script-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/python_script-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "forks": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "open_issues": 0, "is_python_script": false, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "has_discussions": false, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "pull": true, "push": false, "admin": false }, "allow_rebase_merge": true, "python_script_repository": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "python_script-python_script", "full_name": "hacs-test-org/python_script-basic-python_script", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/python_script-basic-python_script", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script", "archive_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/events", "forks_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/python_script-basic-python_script.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/python_script-basic-python_script.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/python_script-basic-python_script.git", "mirror_url": "git:git.example.com/hacs-test-org/python_script-basic-python_script", "hooks_url": "https://api.github.com/repos/hacs-test-org/python_script-basic-python_script/hooks", "svn_url": "https://svn.github.com/hacs-test-org/python_script-basic-python_script", "homepage": "https://github.com", "language": null, "forks": 9, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues": 0, "open_issues_count": 0, "is_python_script": true, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0 }, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "spdx_id": "MIT", "url": "https://api.github.com/licenses/mit", "node_id": "MDc6TGljZW5zZW1pdA==" }, "organization": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "Organization", "site_admin": false }, "parent": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "python_script", "full_name": "hacs-test-org/python_script-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/python_script-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/python_script-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/python_script-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/python_script-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/python_script-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/python_script-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/python_script-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_python_script": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1 }, "source": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "python_script", "full_name": "hacs-test-org/python_script-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/python_script-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/python_script-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/python_script-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/python_script-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/python_script-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/python_script-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/python_script-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/python_script-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_python_script": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1, "security_and_analysis": { "advanced_security": { "status": "enabled" }, "secret_scanning": { "status": "enabled" }, "secret_scanning_push_protection": { "status": "disabled" } } } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/template-basic/branches/main.json ================================================ { "name": "main", "commit": { "sha": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "node_id": "MDY6Q29tbWl0MTI5NjI2OTo3ZmQxYTYwYjAxZjkxYjMxNGY1OTk1NWE0ZTRkNGU4MGQ4ZWRmMTFk", "commit": { "author": { "name": "The Octocat", "email": "octocat@nowhere.com", "date": "2012-03-06T23:06:50Z" }, "committer": { "name": "The Octocat", "email": "octocat@nowhere.com", "date": "2012-03-06T23:06:50Z" }, "message": "Merge pull request #6 from Spaceghost/patch-1\n\nNew line at end of file.", "tree": { "sha": "b4eecafa9be2f2006ce1b709d6857b07069b4608", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/b4eecafa9be2f2006ce1b709d6857b07069b4608" }, "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "comment_count": 77, "verification": { "verified": false, "reason": "unsigned", "signature": null, "payload": null } }, "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d/comments", "author": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "committer": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "parents": [ { "sha": "553c2077f0edc3d5dc5d17262f6aa498e69d6f8e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/553c2077f0edc3d5dc5d17262f6aa498e69d6f8e", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/553c2077f0edc3d5dc5d17262f6aa498e69d6f8e" }, { "sha": "762941318ee16e59dabbacb1b4049eec22f0d303", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/762941318ee16e59dabbacb1b4049eec22f0d303", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/762941318ee16e59dabbacb1b4049eec22f0d303" } ] }, "_links": { "self": "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main", "html": "https://github.com/hacs-test-org/integration-basic/tree/main" }, "protected": false, "protection": { "enabled": false, "required_status_checks": { "enforcement_level": "off", "contexts": [], "checks": [] } }, "protection_url": "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main/protection" } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/template-basic/contents/hacs.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "hacs.json", "path": "hacs.json", "content": "ewogICAgIm5hbWUiOiAiUHJveHkgbWFuaWZlc3QiLAogICAgImZpbGVuYW1lIjogImV4YW1wbGUuamluamEiCn0=", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs-test-org/template-basic/contents/hacs.json", "git_url": "https://api.github.com/repos/hacs-test-org/template-basic/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs-test-org/template-basic/blob/master/hacs.json", "download_url": "https://raw.githubusercontent.com/hacs-test-org/template-basic/master/hacs.json", "_links": { "git": "https://api.github.com/repos/hacs-test-org/template-basic/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs-test-org/template-basic/contents/hacs.json", "html": "https://github.com/hacs-test-org/template-basic/blob/master/hacs.json" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/template-basic/git/trees/1.0.0.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/template-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/template-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "example.jinja", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/template-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/template-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/template-basic/git/trees/2.0.0.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/template-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/template-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "example.jinja", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/template-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/template-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/template-basic/git/trees/main.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/template-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/template-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "example.jinja", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/template-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/template-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/template-basic/releases.json ================================================ [ { "url": "https://api.github.com/repos/hacs-test-org/template-basic/releases/1", "html_url": "https://github.com/hacs-test-org/template-basic/releases/1.0.0", "assets_url": "https://api.github.com/repos/hacs-test-org/template-basic/releases/1/assets", "upload_url": "https://uploads.github.com/repos/hacs-test-org/template-basic/releases/1/assets{?name,label}", "tarball_url": "https://api.github.com/repos/hacs-test-org/template-basic/tarball/1.0.0", "zipball_url": "https://api.github.com/repos/hacs-test-org/template-basic/zipball/1.0.0", "id": 1, "node_id": "MDc6UmVsZWFzZTE=", "tag_name": "1.0.0", "target_commitish": "master", "name": "1.0.0", "body": "Description of the release", "draft": false, "prerelease": false, "created_at": "2013-02-27T19:35:32Z", "published_at": "2013-02-27T19:35:32Z", "author": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "assets": [ { "url": "https://api.github.com/repos/hacs-test-org/template-basic/releases/assets/1", "browser_download_url": "https://github.com/hacs-test-org/template-basic/releases/download/1.0.0/example.zip", "id": 1, "node_id": "MDEyOlJlbGVhc2VBc3NldDE=", "name": "example.zip", "label": "short description", "state": "uploaded", "content_type": "application/zip", "size": 1024, "download_count": 42, "created_at": "2013-02-27T19:35:32Z", "updated_at": "2013-02-27T19:35:32Z", "uploader": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false } } ] } ] ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/template-basic.json ================================================ { "id": 1296268, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "template", "full_name": "hacs-test-org/template-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/template-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/template-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/template-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/template-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/template-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/template-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/template-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/template-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/template-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/template-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/template-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/template-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/template-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/template-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/template-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/template-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/template-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/template-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/template-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/template-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/template-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/template-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/template-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/template-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/template-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/template-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/template-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/template-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/template-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/template-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/template-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/template-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/template-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/template-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/template-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/template-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/template-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/template-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/template-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/template-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/template-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/template-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/template-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "forks": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "open_issues": 0, "is_template": false, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "has_discussions": false, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "pull": true, "push": false, "admin": false }, "allow_rebase_merge": true, "template_repository": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "template-Template", "full_name": "hacs-test-org/template-basic-Template", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/template-basic-Template", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/template-basic-Template", "archive_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/events", "forks_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/template-basic-Template.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/template-basic-Template.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/template-basic-Template.git", "mirror_url": "git:git.example.com/hacs-test-org/template-basic-Template", "hooks_url": "https://api.github.com/repos/hacs-test-org/template-basic-Template/hooks", "svn_url": "https://svn.github.com/hacs-test-org/template-basic-Template", "homepage": "https://github.com", "language": null, "forks": 9, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues": 0, "open_issues_count": 0, "is_template": true, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0 }, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "spdx_id": "MIT", "url": "https://api.github.com/licenses/mit", "node_id": "MDc6TGljZW5zZW1pdA==" }, "organization": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "Organization", "site_admin": false }, "parent": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "template", "full_name": "hacs-test-org/template-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/template-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/template-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/template-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/template-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/template-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/template-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/template-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/template-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/template-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/template-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/template-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/template-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/template-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/template-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/template-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/template-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/template-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/template-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/template-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/template-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/template-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/template-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/template-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/template-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/template-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/template-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/template-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/template-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/template-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/template-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/template-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/template-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/template-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/template-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/template-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/template-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/template-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/template-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/template-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/template-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/template-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/template-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/template-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_template": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1 }, "source": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "template", "full_name": "hacs-test-org/template-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/template-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/template-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/template-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/template-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/template-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/template-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/template-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/template-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/template-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/template-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/template-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/template-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/template-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/template-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/template-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/template-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/template-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/template-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/template-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/template-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/template-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/template-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/template-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/template-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/template-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/template-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/template-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/template-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/template-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/template-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/template-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/template-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/template-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/template-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/template-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/template-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/template-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/template-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/template-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/template-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/template-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/template-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/template-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_template": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1, "security_and_analysis": { "advanced_security": { "status": "enabled" }, "secret_scanning": { "status": "enabled" }, "secret_scanning_push_protection": { "status": "disabled" } } } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/theme-basic/branches/main.json ================================================ { "name": "main", "commit": { "sha": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "node_id": "MDY6Q29tbWl0MTI5NjI2OTo3ZmQxYTYwYjAxZjkxYjMxNGY1OTk1NWE0ZTRkNGU4MGQ4ZWRmMTFk", "commit": { "author": { "name": "The Octocat", "email": "octocat@nowhere.com", "date": "2012-03-06T23:06:50Z" }, "committer": { "name": "The Octocat", "email": "octocat@nowhere.com", "date": "2012-03-06T23:06:50Z" }, "message": "Merge pull request #6 from Spaceghost/patch-1\n\nNew line at end of file.", "tree": { "sha": "b4eecafa9be2f2006ce1b709d6857b07069b4608", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/b4eecafa9be2f2006ce1b709d6857b07069b4608" }, "url": "https://api.github.com/repos/hacs-test-org/integration-basic/git/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "comment_count": 77, "verification": { "verified": false, "reason": "unsigned", "signature": null, "payload": null } }, "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d", "comments_url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d/comments", "author": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "committer": { "login": "octocat", "id": 583231, "node_id": "MDQ6VXNlcjU4MzIzMQ==", "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "parents": [ { "sha": "553c2077f0edc3d5dc5d17262f6aa498e69d6f8e", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/553c2077f0edc3d5dc5d17262f6aa498e69d6f8e", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/553c2077f0edc3d5dc5d17262f6aa498e69d6f8e" }, { "sha": "762941318ee16e59dabbacb1b4049eec22f0d303", "url": "https://api.github.com/repos/hacs-test-org/integration-basic/commits/762941318ee16e59dabbacb1b4049eec22f0d303", "html_url": "https://github.com/hacs-test-org/integration-basic/commit/762941318ee16e59dabbacb1b4049eec22f0d303" } ] }, "_links": { "self": "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main", "html": "https://github.com/hacs-test-org/integration-basic/tree/main" }, "protected": false, "protection": { "enabled": false, "required_status_checks": { "enforcement_level": "off", "contexts": [], "checks": [] } }, "protection_url": "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main/protection" } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/theme-basic/contents/hacs.json ================================================ { "type": "file", "encoding": "base64", "size": 5362, "name": "hacs.json", "path": "hacs.json", "content": "ewogICAgIm5hbWUiOiAiUHJveHkgbWFuaWZlc3QiLAogICAgImZpbGVuYW1lIjogImV4YW1wbGUuamluamEiCn0=", "sha": "3d21ec53a331a6f037a91c368710b99387d012c1", "url": "https://api.github.com/repos/hacs-test-org/theme-basic/contents/hacs.json", "git_url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "html_url": "https://github.com/hacs-test-org/theme-basic/blob/master/hacs.json", "download_url": "https://raw.githubusercontent.com/hacs-test-org/theme-basic/master/hacs.json", "_links": { "git": "https://api.github.com/repos/hacs-test-org/theme-basic/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1", "self": "https://api.github.com/repos/hacs-test-org/theme-basic/contents/hacs.json", "html": "https://github.com/hacs-test-org/theme-basic/blob/master/hacs.json" } } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/theme-basic/git/trees/1.0.0.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/theme-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "themes", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "themes/example.yaml", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/theme-basic/git/trees/2.0.0.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/theme-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "themes", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "themes/example.yaml", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/theme-basic/git/trees/main.json ================================================ { "sha": "9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "url": "https://api.github.com/repos/hacs-test-org/theme-basic/trees/9fb037999f264ba9a7fc6274d15fa3ae2ab98312", "tree": [ { "path": "README.md", "mode": "100644", "type": "blob", "size": 30, "sha": "44b4fc6d56897b048c772eb4087f854f46256132", "url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/blobs/44b4fc6d56897b048c772eb4087f854f46256132" }, { "path": "themes", "mode": "040000", "type": "tree", "sha": "f484d249c660418515fb01c2b9662073663c242e", "url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/blobs/f484d249c660418515fb01c2b9662073663c242e" }, { "path": "themes/example.yaml", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" }, { "path": "hacs.json", "mode": "100755", "type": "blob", "size": 75, "sha": "45b983be36b73c0788dc9cbcb76cbb80fc7bb057", "url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/blobs/45b983be36b73c0788dc9cbcb76cbb80fc7bb057" } ], "truncated": false } ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/theme-basic/releases.json ================================================ [ { "url": "https://api.github.com/repos/hacs-test-org/theme-basic/releases/1", "html_url": "https://github.com/hacs-test-org/theme-basic/releases/1.0.0", "assets_url": "https://api.github.com/repos/hacs-test-org/theme-basic/releases/1/assets", "upload_url": "https://uploads.github.com/repos/hacs-test-org/theme-basic/releases/1/assets{?name,label}", "tarball_url": "https://api.github.com/repos/hacs-test-org/theme-basic/tarball/1.0.0", "zipball_url": "https://api.github.com/repos/hacs-test-org/theme-basic/zipball/1.0.0", "id": 1, "node_id": "MDc6UmVsZWFzZTE=", "tag_name": "1.0.0", "target_commitish": "master", "name": "1.0.0", "body": "Description of the release", "draft": false, "prerelease": false, "created_at": "2013-02-27T19:35:32Z", "published_at": "2013-02-27T19:35:32Z", "author": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "assets": [] } ] ================================================ FILE: tests/fixtures/proxy/api.github.com/repos/hacs-test-org/theme-basic.json ================================================ { "id": 1296266, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "theme", "full_name": "hacs-test-org/theme-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/theme-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/theme-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/theme-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/theme-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/theme-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/theme-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/theme-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/theme-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/theme-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/theme-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/theme-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/theme-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/theme-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/theme-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/theme-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/theme-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/theme-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/theme-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/theme-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/theme-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/theme-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/theme-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/theme-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/theme-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/theme-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/theme-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/theme-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/theme-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/theme-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/theme-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/theme-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/theme-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/theme-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/theme-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/theme-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/theme-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/theme-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/theme-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "forks": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "open_issues": 0, "is_theme": false, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "has_discussions": false, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "pull": true, "push": false, "admin": false }, "allow_rebase_merge": true, "theme_repository": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "theme-theme", "full_name": "hacs-test-org/theme-basic-theme", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/theme-basic-theme", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme", "archive_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/events", "forks_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/theme-basic-theme.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/theme-basic-theme.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/theme-basic-theme.git", "mirror_url": "git:git.example.com/hacs-test-org/theme-basic-theme", "hooks_url": "https://api.github.com/repos/hacs-test-org/theme-basic-theme/hooks", "svn_url": "https://svn.github.com/hacs-test-org/theme-basic-theme", "homepage": "https://github.com", "language": null, "forks": 9, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "watchers": 80, "size": 108, "default_branch": "main", "open_issues": 0, "open_issues_count": 0, "is_theme": true, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0 }, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "spdx_id": "MIT", "url": "https://api.github.com/licenses/mit", "node_id": "MDc6TGljZW5zZW1pdA==" }, "organization": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "Organization", "site_admin": false }, "parent": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "theme", "full_name": "hacs-test-org/theme-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/theme-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/theme-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/theme-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/theme-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/theme-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/theme-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/theme-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/theme-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/theme-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/theme-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/theme-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/theme-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/theme-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/theme-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/theme-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/theme-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/theme-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/theme-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/theme-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/theme-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/theme-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/theme-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/theme-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/theme-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/theme-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/theme-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/theme-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/theme-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/theme-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/theme-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/theme-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/theme-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/theme-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/theme-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/theme-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/theme-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/theme-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/theme-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_theme": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1 }, "source": { "id": 1296269, "node_id": "MDEwOlJlcG9zaXRvcnkxMjk2MjY5", "name": "theme", "full_name": "hacs-test-org/theme-basic", "owner": { "login": "octocat", "id": 1, "node_id": "MDQ6VXNlcjE=", "avatar_url": "https://github.com/images/error/octocat_happy.gif", "gravatar_id": "", "url": "https://api.github.com/users/octocat", "html_url": "https://github.com/octocat", "followers_url": "https://api.github.com/users/hacs-test-org/followers", "following_url": "https://api.github.com/users/hacs-test-org/following{/other_user}", "gists_url": "https://api.github.com/users/hacs-test-org/gists{/gist_id}", "starred_url": "https://api.github.com/users/hacs-test-org/starred{/owner}{/repo}", "subscriptions_url": "https://api.github.com/users/hacs-test-org/subscriptions", "organizations_url": "https://api.github.com/users/hacs-test-org/orgs", "repos_url": "https://api.github.com/users/hacs-test-org/repos", "events_url": "https://api.github.com/users/hacs-test-org/events{/privacy}", "received_events_url": "https://api.github.com/users/hacs-test-org/received_events", "type": "User", "site_admin": false }, "private": false, "html_url": "https://github.com/hacs-test-org/theme-basic", "description": "This your first repo!", "fork": false, "url": "https://api.github.com/repos/hacs-test-org/theme-basic", "archive_url": "https://api.github.com/repos/hacs-test-org/theme-basic/{archive_format}{/ref}", "assignees_url": "https://api.github.com/repos/hacs-test-org/theme-basic/assignees{/user}", "blobs_url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/blobs{/sha}", "branches_url": "https://api.github.com/repos/hacs-test-org/theme-basic/branches{/branch}", "collaborators_url": "https://api.github.com/repos/hacs-test-org/theme-basic/collaborators{/collaborator}", "comments_url": "https://api.github.com/repos/hacs-test-org/theme-basic/comments{/number}", "commits_url": "https://api.github.com/repos/hacs-test-org/theme-basic/commits{/sha}", "compare_url": "https://api.github.com/repos/hacs-test-org/theme-basic/compare/{base}...{head}", "contents_url": "https://api.github.com/repos/hacs-test-org/theme-basic/contents/{+path}", "contributors_url": "https://api.github.com/repos/hacs-test-org/theme-basic/contributors", "deployments_url": "https://api.github.com/repos/hacs-test-org/theme-basic/deployments", "downloads_url": "https://api.github.com/repos/hacs-test-org/theme-basic/downloads", "events_url": "https://api.github.com/repos/hacs-test-org/theme-basic/events", "forks_url": "https://api.github.com/repos/hacs-test-org/theme-basic/forks", "git_commits_url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/commits{/sha}", "git_refs_url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/refs{/sha}", "git_tags_url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/tags{/sha}", "git_url": "git:github.com/hacs-test-org/theme-basic.git", "issue_comment_url": "https://api.github.com/repos/hacs-test-org/theme-basic/issues/comments{/number}", "issue_events_url": "https://api.github.com/repos/hacs-test-org/theme-basic/issues/events{/number}", "issues_url": "https://api.github.com/repos/hacs-test-org/theme-basic/issues{/number}", "keys_url": "https://api.github.com/repos/hacs-test-org/theme-basic/keys{/key_id}", "labels_url": "https://api.github.com/repos/hacs-test-org/theme-basic/labels{/name}", "languages_url": "https://api.github.com/repos/hacs-test-org/theme-basic/languages", "merges_url": "https://api.github.com/repos/hacs-test-org/theme-basic/merges", "milestones_url": "https://api.github.com/repos/hacs-test-org/theme-basic/milestones{/number}", "notifications_url": "https://api.github.com/repos/hacs-test-org/theme-basic/notifications{?since,all,participating}", "pulls_url": "https://api.github.com/repos/hacs-test-org/theme-basic/pulls{/number}", "releases_url": "https://api.github.com/repos/hacs-test-org/theme-basic/releases{/id}", "ssh_url": "git@github.com:hacs-test-org/theme-basic.git", "stargazers_url": "https://api.github.com/repos/hacs-test-org/theme-basic/stargazers", "statuses_url": "https://api.github.com/repos/hacs-test-org/theme-basic/statuses/{sha}", "subscribers_url": "https://api.github.com/repos/hacs-test-org/theme-basic/subscribers", "subscription_url": "https://api.github.com/repos/hacs-test-org/theme-basic/subscription", "tags_url": "https://api.github.com/repos/hacs-test-org/theme-basic/tags", "teams_url": "https://api.github.com/repos/hacs-test-org/theme-basic/teams", "trees_url": "https://api.github.com/repos/hacs-test-org/theme-basic/git/trees{/sha}", "clone_url": "https://github.com/hacs-test-org/theme-basic.git", "mirror_url": "git:git.example.com/hacs-test-org/theme-basic", "hooks_url": "https://api.github.com/repos/hacs-test-org/theme-basic/hooks", "svn_url": "https://svn.github.com/hacs-test-org/theme-basic", "homepage": "https://github.com", "language": null, "forks_count": 9, "stargazers_count": 80, "watchers_count": 80, "size": 108, "default_branch": "main", "open_issues_count": 0, "is_theme": true, "topics": [ "octocat", "atom", "electron", "api" ], "has_issues": true, "has_projects": true, "has_wiki": true, "has_pages": false, "has_downloads": true, "archived": false, "disabled": false, "visibility": "public", "pushed_at": "2011-01-26T19:06:43Z", "created_at": "2011-01-26T19:01:12Z", "updated_at": "2011-01-26T19:14:43Z", "permissions": { "admin": false, "push": false, "pull": true }, "allow_rebase_merge": true, "temp_clone_token": "ABTLWHOULUVAXGTRYU7OC2876QJ2O", "allow_squash_merge": true, "allow_auto_merge": false, "delete_branch_on_merge": true, "allow_merge_commit": true, "subscribers_count": 42, "network_count": 0, "license": { "key": "mit", "name": "MIT License", "url": "https://api.github.com/licenses/mit", "spdx_id": "MIT", "node_id": "MDc6TGljZW5zZW1pdA==", "html_url": "https://api.github.com/licenses/mit" }, "forks": 1, "open_issues": 1, "watchers": 1, "security_and_analysis": { "advanced_security": { "status": "enabled" }, "secret_scanning": { "status": "enabled" }, "secret_scanning_push_protection": { "status": "disabled" } } } } ================================================ FILE: tests/fixtures/proxy/brands.home-assistant.io/domains.json ================================================ { "brands": [], "core": [], "custom": [] } ================================================ FILE: tests/fixtures/proxy/data-v2.hacs.xyz/appdaemon/data.json ================================================ { "1296265": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/appdaemon-basic", "last_fetched": 0.0, "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "manifest": {} } } ================================================ FILE: tests/fixtures/proxy/data-v2.hacs.xyz/appdaemon/repositories.json ================================================ [ "hacs-test-org/appdaemon-basic" ] ================================================ FILE: tests/fixtures/proxy/data-v2.hacs.xyz/critical/data.json ================================================ [] ================================================ FILE: tests/fixtures/proxy/data-v2.hacs.xyz/integration/data.json ================================================ { "1296269": { "description": "This your first repo!", "domain": "example", "etag_repository": "321", "full_name": "hacs-test-org/integration-basic", "last_fetched": 0.0, "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "manifest": {}, "manifest_name": "Basic integration" } } ================================================ FILE: tests/fixtures/proxy/data-v2.hacs.xyz/integration/repositories.json ================================================ [ "hacs-test-org/integration-basic" ] ================================================ FILE: tests/fixtures/proxy/data-v2.hacs.xyz/netdaemon/data.json ================================================ { "1296263": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/python_script-basic", "last_fetched": 0.0, "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "manifest": {} } } ================================================ FILE: tests/fixtures/proxy/data-v2.hacs.xyz/netdaemon/repositories.json ================================================ [] ================================================ FILE: tests/fixtures/proxy/data-v2.hacs.xyz/plugin/data.json ================================================ { "1296267": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/plugin-basic", "last_fetched": 0.0, "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "manifest": {} } } ================================================ FILE: tests/fixtures/proxy/data-v2.hacs.xyz/plugin/repositories.json ================================================ [ "hacs-test-org/plugin-basic" ] ================================================ FILE: tests/fixtures/proxy/data-v2.hacs.xyz/python_script/data.json ================================================ { "1296262": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/python_script-basic", "last_fetched": 0.0, "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "manifest": {} } } ================================================ FILE: tests/fixtures/proxy/data-v2.hacs.xyz/python_script/repositories.json ================================================ [ "hacs-test-org/python_script-basic" ] ================================================ FILE: tests/fixtures/proxy/data-v2.hacs.xyz/removed/data.json ================================================ [ { "repository": "hacs-test-org/removed-repository", "removal_type": "removed", "link": "https://github.com/hacs-test-org/removed-repository", "reason": "Repository removed from GitHub" } ] ================================================ FILE: tests/fixtures/proxy/data-v2.hacs.xyz/removed/repositories.json ================================================ [ "hacs-test-org/removed-repository" ] ================================================ FILE: tests/fixtures/proxy/data-v2.hacs.xyz/template/data.json ================================================ { "1296268": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/template-basic", "last_fetched": 0.0, "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "manifest": {} } } ================================================ FILE: tests/fixtures/proxy/data-v2.hacs.xyz/template/repositories.json ================================================ [ "hacs-test-org/template-basic" ] ================================================ FILE: tests/fixtures/proxy/data-v2.hacs.xyz/theme/data.json ================================================ { "1296266": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/theme-basic", "last_fetched": 0.0, "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "manifest": {} } } ================================================ FILE: tests/fixtures/proxy/data-v2.hacs.xyz/theme/repositories.json ================================================ [ "hacs-test-org/theme-basic" ] ================================================ FILE: tests/fixtures/proxy/github.com/hacs-test-org/appdaemon-basic/_base/README.md ================================================ ## Example readme file (x.0.0) ================================================ FILE: tests/fixtures/proxy/github.com/hacs-test-org/appdaemon-basic/_base/apps/example/__init__.py ================================================ ================================================ FILE: tests/fixtures/proxy/github.com/hacs-test-org/integration-basic/_base/README.md ================================================ ## Example readme file (x.0.0) ================================================ FILE: tests/fixtures/proxy/github.com/hacs-test-org/integration-basic/_base/custom_components/example/manifest.json ================================================ { "name": "Proxy integration", "domain": "example" } ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/appdaemon-basic/1.0.0/README.md ================================================ ## Example readme file (1.0.0) ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/appdaemon-basic/1.0.0/hacs.json ================================================ { "name": "Appdaemon basic 1.0.0" } ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/appdaemon-basic/2.0.0/README.md ================================================ ## Example readme file (2.0.0) ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/appdaemon-basic/2.0.0/hacs.json ================================================ { "name": "Appdaemon basic 2.0.0" } ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/integration-basic/1.0.0/README.md ================================================ ## Example readme file (1.0.0) Sorry, your browser does not support inline SVG. ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/integration-basic/1.0.0/hacs.json ================================================ { "name": "Integration basic 1.0.0" } ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/integration-basic/2.0.0/README.md ================================================ ## Example readme file (2.0.0) ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/integration-basic/2.0.0/hacs.json ================================================ { "name": "Integration basic 2.0.0" } ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/integration-basic/main/hacs.json ================================================ { "name": "integration-basic" } ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/hacs.json ================================================ { "name": "Plugin basic 1.0.0" } ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js ================================================ ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/plugin-basic/2.0.0/hacs.json ================================================ { "name": "Plugin basic 2.0.0" } ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/plugin-basic/2.0.0/plugin-basic.js ================================================ ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/python_script-basic/1.0.0/README.md ================================================ ## Example readme file (1.0.0) ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/python_script-basic/1.0.0/hacs.json ================================================ { "name": "Python script basic 1.0.0" } ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/python_script-basic/1.0.0/python_scripts/example.py ================================================ ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/python_script-basic/2.0.0/README.md ================================================ ## Example readme file (2.0.0) ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/python_script-basic/2.0.0/hacs.json ================================================ { "name": "Python script basic 2.0.0" } ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/python_script-basic/2.0.0/python_scripts/example.py ================================================ ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/template-basic/1.0.0/example.jinja ================================================ ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/template-basic/1.0.0/hacs.json ================================================ { "name": "Template basic 1.0.0" } ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/template-basic/2.0.0/example.jinja ================================================ ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/template-basic/2.0.0/hacs.json ================================================ { "name": "Template basic 2.0.0" } ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/theme-basic/1.0.0/hacs.json ================================================ { "name": "Theme basic 1.0.0" } ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/theme-basic/1.0.0/themes/example.yaml ================================================ ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/theme-basic/2.0.0/hacs.json ================================================ { "name": "Theme basic 2.0.0" } ================================================ FILE: tests/fixtures/proxy/raw.githubusercontent.com/hacs-test-org/theme-basic/2.0.0/themes/example.yaml ================================================ ================================================ FILE: tests/fixtures/repository_data.json ================================================ { "id": 999999999, "full_name": "test/test", "fork": false, "description": "Sample description for repository.", "stargazers_count": 999, "archived": false, "topics": [ "topic1", "topic2" ], "default_branch": "main", "last_commit": "12345678" } ================================================ FILE: tests/fixtures/stored_repositories.json ================================================ { "999999": { "name": "test1" }, "888888": { "name": "test2" } } ================================================ FILE: tests/fixtures/v2-appdaemon-data.json ================================================ {"236119263":{"manifest":{"name":"Convert Media Player Volume"},"description":"Appdaemon App that converts Home Assistants volume into a sensor that matches your devices volume.","etag_releases":"W/\"19941beba19e532652680de7c3fedfed936fcde9a1a1eb24faf2129341f3a5ac\"","etag_repository":"W/\"12e847be26db8f649af9c0b6313ff36adcba85e5272c70a38072d85c87122fce\"","full_name":"Petro31/ad_convert_media_volume","last_commit":"f65d955","last_updated":"2020-01-25T03:41:16Z","last_version":"1.0","stargazers_count":4,"last_fetched":1690402344.13716},"234527343":{"manifest":{"name":"Sonos Alarm Automation"},"description":"App that brings alarm snoozing to SONOS using the custom component SonosAlarm","etag_releases":"W/\"7e9aa96427eeb00e3157828b8bebdf2caa7bd42d9aeccf9a3bb2202bb7d9fe7c\"","etag_repository":"W/\"252f376c746512f155f201c19ca31e3d6f8834149772668d3c755c529c6a8f02\"","full_name":"AaronDavidSchneider/SonosAlarmAutomation","last_commit":"aaae52b","last_updated":"2020-01-20T09:34:52Z","last_version":"v1.0","stargazers_count":3,"last_fetched":1711296845.210078},"237800470":{"manifest":{"name":"Seasonal Lights"},"description":"Creates a binary_sensor that represents a season between 2 dates. Turns on/off entities at specific times inside the season.","etag_releases":"W/\"e9264cddd5107e95ff97e727e58ea042228352b97d7a5662c49aae8e27d6048f\"","etag_repository":"W/\"40446104c7689487d158dbe279407341205242b29ff51edb56d71d388cf6f33f\"","full_name":"Petro31/ad_seasonal_lights","last_commit":"eb5e856","last_updated":"2023-07-08T10:15:37Z","last_version":"1.0","stargazers_count":2,"last_fetched":1688819097.510595},"267325736":{"manifest":{"name":"Home Assistant entity state cache"},"description":"AppDaemon based entity cache application for Home Assistant","etag_releases":"W/\"11cdaffe19cbbe2c9cce6544d5f2463fbdfa424d34845ea3bc6dbd31e4d7d75f\"","etag_repository":"W/\"0ab23540289cfdcd314aa3eaa281cc23d09b8a531be06838604abd6314abe60c\"","full_name":"jbouwh/ha-entity-cache","last_commit":"e96e4c9","last_updated":"2021-08-03T07:42:28Z","last_version":"v1.1","stargazers_count":1,"topics":["chache","helper-tool","input-select","states"],"last_fetched":1678386257.985583},"237294804":{"manifest":{"name":"Simple Door Bell Automation"},"description":"Doorbell automation that notifies you and announces via TTS","etag_releases":"W/\"897faea13c4222170fd6c30304ffe0af97073284607be7dbe5e9e1457e3c2f20\"","etag_repository":"W/\"bfe5104a2a6d3d7d547ccc725b6fa958b16ff5e7a8fa2a03bab107773fd5ff80\"","full_name":"Petro31/ad_simple_door_bell","last_commit":"02f5b4f","last_updated":"2020-01-30T22:00:02Z","last_version":"1.0","stargazers_count":2,"last_fetched":1678386259.343479},"284749777":{"manifest":{"name":"Aqara Motion Sensors"},"description":"An AppDaemon app to reset Xiaomi Aqara motion sensors after a given timeout.","etag_releases":"W/\"7c45a27eea3c9af64565b54a666aaa7160f4a339e2c3d28bc651541afb6fa139\"","etag_repository":"W/\"b712b89a5a6d6250ca80a185f128eb634941c1d662d095b0c4410c20bf2e9437\"","full_name":"wernerhp/ha.appdaemon.aqara_motion_sensors","last_commit":"75893e6","last_updated":"2023-06-29T13:45:14Z","last_version":"v1.2.0","open_issues":2,"stargazers_count":39,"last_fetched":1700355678.830914},"354149479":{"manifest":{"name":"AppDaemon Client for Qolsys"},"description":"AppDaemon app for Qolsys IQ Panel 2","etag_releases":"W/\"b328d53bbe3aca755422244dcc7476a462b2dd0955426ae7f0e50886c6208f89\"","etag_repository":"W/\"a1bea4afaa4673e49a8e29fa6a7575ed3cd6239bf5dc9191c6f2f70046cc31f3\"","full_name":"roopesh/ad-qolsys","last_commit":"9cd9f6e","last_updated":"2022-05-16T20:36:31Z","last_version":"1.8.2","open_issues":7,"stargazers_count":20,"topics":["alarm","alarm-control","alarm-control-panel","alarm-panel","qolsys"],"last_fetched":1706403439.899274},"267943249":{"manifest":{"name":"Auto 'Fan Speed' Controller \ud83d\udc14"},"description":"Automatically control a room fan's speed based on a temperature sensor. Please :star: if you like this app :)","etag_releases":"W/\"4ba466a8add85bded12f11f831a344d1c4c47e177013c631422bc9f160dc73c2\"","etag_repository":"W/\"f6c42198dbd918c98330ded32ff95ee7bfb765daf16f57357a2a2ad2dc9c8717\"","full_name":"UbhiTS/ad-autofanspeed","last_commit":"79c720d","last_updated":"2022-06-02T14:54:48Z","last_version":"v1.0.4","open_issues":4,"stargazers_count":17,"topics":["apps","assistant","automated","automation","fan","fan-speed","fan-speed-control","sunrise"],"last_fetched":1707877109.388678},"331696949":{"manifest":{"name":"Spotify Mood Lights Sync"},"description":"AppDaemon app that synchronizes rgb lights to the mood of the currently playing spotify song in Home Assistant.","etag_releases":"W/\"7c837353d5c0186ee752ad14d38dc381685825768826f536e4d447fb9fdf9288\"","etag_repository":"W/\"3407f9d1f4c8db627d10a884319e178d727b3450eaa8ac7c3f156ebccff1fe05\"","full_name":"NiklasReiche/ad-spotify-mood-lights-sync","last_commit":"4ad7323","last_updated":"2024-03-04T13:06:11Z","last_version":"v1.3.1","open_issues":1,"stargazers_count":34,"topics":["rgb-lights","spotify"],"last_fetched":1712045757.146218},"338827116":{"manifest":{"name":"appdaemon-climate"},"description":"appdaemon app to control your home's climate","etag_repository":"W/\"8fb31818a20b46b558295dfc84176f368defc6b985581a399dd1a1728759f1be\"","full_name":"kprestel/appdaemon-climate","last_commit":"a72554a","last_updated":"2022-07-17T13:55:31Z","open_issues":3,"stargazers_count":8,"last_fetched":1711296845.754654},"233389688":{"manifest":{"name":"Illuminate Door"},"description":"Appdaemon App to Illuminate a door entrance when the door has opened.","etag_releases":"W/\"718e4b056a8caa77c8d241f1cd6d331d343b72172d9766165ac570882e846fb6\"","etag_repository":"W/\"c4d12ebf28cc81496451036a824d31d93976a84fa110cc51d1469f555b6ee9d2\"","full_name":"Petro31/IlluminateDoor","last_commit":"899a6d2","last_updated":"2020-01-30T22:22:45Z","last_version":"1.1","stargazers_count":2,"last_fetched":1678386259.371853},"237328349":{"manifest":{"name":"Lights On at Sundown Automation"},"description":"Automation to turn lights on at sunset","etag_releases":"W/\"5dec35f9605c54d4da3a6fcc4b87ac4b97e357e1413f2a71e2e1fbb77dfc7dbc\"","etag_repository":"W/\"2d03b6cfdba5c950ccc3ae9614427de699b5f2224d194ad36d29d13e84e59c8f\"","full_name":"Petro31/ad_sunset_lights","last_commit":"6db61cd","last_updated":"2020-01-31T00:34:20Z","last_version":"1.0","stargazers_count":2,"last_fetched":1678386259.294564},"262519869":{"manifest":{"country":["AU"],"name":"act_garbage"},"description":"HA Sensors for the ACT next bin pickup date information for suburbs","etag_repository":"W/\"f674c80c0e6dbbcf7e59e70fab9cbbd06732b84d0daa8d67a28d1c2d0f495225\"","full_name":"simonhq/act_garbage","last_commit":"03fdc1b","last_updated":"2020-05-26T22:01:45Z","open_issues":2,"stargazers_count":5,"topics":["creates-sensors","entity","garbage","suburb"],"last_fetched":1708769594.016417},"245704242":{"manifest":{"name":"Octoblock \ud83d\udc19"},"description":"Octoblock is an app which works under AppDaemon within Home Assistant which finds the cheapest \u201cn\u201d hour block for import or the most expensive \u201cn\u201d hour block for export, and works out the price of that block, for the Octopus Energy, Agile Octopus / Agile Outgoing Octopus tariffs.","etag_releases":"W/\"60a8a0460600e3c8e153a80fb8eb94d1903216f3295d771939695256a93dcbe0\"","etag_repository":"W/\"82732b888bb4f373ec2834e76fe55fafffc023995d29fb971b90bbdf6ddea0cb\"","full_name":"badguy99/octoblock","last_commit":"d67e6c0","last_updated":"2023-12-06T22:06:01Z","last_version":"v0.3.0","open_issues":1,"stargazers_count":28,"topics":["energy","octopus","octopus-energy"],"last_fetched":1708618552.05154},"234988006":{"manifest":{"name":"NetHassmo"},"description":"Automate Welcome Camera presence and monitoring.","etag_releases":"W/\"191f9d41ccdab556339a060ee382a735f63812ee9be461a548547a2a92017117\"","etag_repository":"W/\"ddd6fdd22408b280aaede4e2a8eeec5c19006572ea5c5b1e433afddc3fe86850\"","full_name":"vash3d/nethassmo","last_commit":"3e52f48","last_updated":"2022-01-07T15:20:40Z","last_version":"v1.1.0","stargazers_count":1,"last_fetched":1703736915.114151},"258858024":{"manifest":{"name":"Alexa (& Friends) Door Announce \ud83d\udc14"},"description":"Announce your doors/windows opening and closing through your Smart Speaker. Handy for garage/side/main exits for homes and shops. Please :star: if you like this app :)","etag_releases":"W/\"4d7e3aef26aa06c27e0b18551b4e23610c30f1f83909fc71d455f7a5822b5b39\"","etag_repository":"W/\"1a42bbd7446c9feacb7ecbecf63b1ca148dcc624c7cf59f3ea9c984ed98c4bfc\"","full_name":"UbhiTS/ad-alexadoorwindowannounce","last_commit":"7a121ba","last_updated":"2021-03-11T22:21:18Z","last_version":"v1.1.0","open_issues":2,"stargazers_count":9,"topics":["alexa","alexa-media-player","alexa-voice-service","amazon-alexa","apps","assistant","doorbell","python3"],"last_fetched":1708265443.424457},"558550898":{"manifest":{"country":["GB"],"name":"\ud83d\udd25 Hive TRV Boost Mode"},"description":"AppDaemon script for Hive's TRV Boost Mode","etag_releases":"W/\"c94b66298d52bde0bc4241f5961cfe0879b27173c0c56b6daba5b9c4dec018d7\"","etag_repository":"W/\"aa67a4c99bc6fc9d83be55d7fa6b56a3ddb7fb35158e88428323d15a229b8dc7\"","full_name":"dwardu89/hive-trv-appdaemon","last_commit":"d0834dd","last_updated":"2024-04-02T19:20:44Z","last_version":"v0.1.9","open_issues":1,"stargazers_count":1,"topics":["hive-heating","zigbee2mqtt"],"last_fetched":1712088772.424049},"627074407":{"manifest":{"name":"\ud83c\udfe6\ufe0f MINT Api Scraper \ud83d\udcb8\ufe0f"},"description":"AppDaemon script for scraping financial data from MINT to display in home assistant","etag_releases":"W/\"6241c3ceabaa23620114a2b5683f405d2c673d6f66660925d3ef836a448df2e7\"","etag_repository":"W/\"4f487641fcc3a89c186dae454ef5983232168f7969254e8f3853dd7bae7082b4\"","full_name":"jeeftor/mint-scraper-for-homeassistant","last_commit":"ec50ae1","last_updated":"2023-10-25T12:47:36Z","last_version":"v1.0.3","open_issues":2,"stargazers_count":4,"topics":["mint"],"last_fetched":1705270317.998722},"211308341":{"manifest":{"name":"\ud83d\udc69\u200d\u2695\ufe0f EnCh - Entity Checker"},"description":"\ud83d\udc69\u200d\u2695\ufe0f\ud83d\udd0b AppDaemon entity check app. Currently supports battery level, unknown/unavailable states, stale entities","etag_releases":"W/\"1ad3bd0d953806b1e66d70b8fc8cf36d65d806e342422b2c67e39a2cf11fabe1\"","etag_repository":"W/\"5e3e5a79e1b8dae2382aec6bd59e3518b811f72a51c39ba64c8bb85b99321018\"","full_name":"benleb/ad-ench","last_commit":"a9d5abf","last_updated":"2021-07-24T05:43:36Z","last_version":"v0.9.0","stargazers_count":36,"topics":["assistant-entities","battery-levels","ench","entity-check","stale-entities"],"last_fetched":1706343275.271093},"293521853":{"manifest":{"name":"Hue Dimmer Switch ZHA"},"description":"Customize the buttons on a ZHA controlled Hue Dimmer Switch","etag_repository":"W/\"00a908efe805a4f13517a2aefdedc1b352e79f94eb5138587a4b7d031b0ed4d9\"","full_name":"nickneos/Appdaemon-ZHA-Hue-Dimmer-Switch","last_commit":"9a8ecf2","last_updated":"2021-07-18T13:23:58Z","open_issues":1,"stargazers_count":7,"topics":["dimmer","hue"],"last_fetched":1690222618.171011},"445477700":{"manifest":{"name":"NSPanel Lovelace UI Backend"},"description":"Custom Firmware for NsPanel with the design of HomeAssistant's lovelace UI in mind, works with Tasmota.","etag_releases":"W/\"1a7921e8c9d480389472be1a619c56de4b8cd1ef84fed8b1a6e88a1ba7fb5d42\"","etag_repository":"W/\"e9c9d6d387a31d9caa2c322dab4982ce5ff852368f1aaf60d3bb64e4cfe97238\"","full_name":"joBr99/nspanel-lovelace-ui","last_commit":"19b0fe4","last_updated":"2024-04-02T16:14:04Z","last_version":"v4.4.0","open_issues":48,"stargazers_count":820,"topics":["appdeamon","iobroker","mqtt","nspanel","sonoff","tasmota"],"last_fetched":1712175277.84613},"432938956":{"manifest":{"name":"Qolsys Gateway"},"description":"Qolsys IQ Panel 2+ gateway to an Home Assistant Alarm Control Panel","etag_releases":"W/\"797a49e8dce2bdeede45edc881191b54fc87ba149f2ce16b65fae309e77d9341\"","etag_repository":"W/\"d70e4c8e0679be4359d72e576972f56e40978a2dbb09e8306006178221825e96\"","full_name":"XaF/qolsysgw","last_commit":"3f7c4d1","last_updated":"2024-03-27T06:00:43Z","last_version":"v1.6.0","open_issues":22,"stargazers_count":91,"topics":["automation","qolsys"],"last_fetched":1711520167.293929},"717712705":{"manifest":{"country":["NO"],"name":"Lightwand"},"description":"Extensive control of lights based on time of day with mode event in addition to motion, presence, lux, rain, and media player sensors","etag_releases":"W/\"5235c11f38bd6c03ef34f80ccf588fa3f6d4c46c3e6098a827db5a83e026dc43\"","etag_repository":"W/\"afef254f0a4ba543d9bcf61b07f00cf81f7c8253f22fde62e3162238164f247c\"","full_name":"Pythm/ad-Lightwand","last_commit":"c5614b2","last_updated":"2024-02-25T13:54:46Z","last_version":"v1.1.4","stargazers_count":7,"topics":["automated-lights","hue-lights","lightcontrol","lights","lux-sensor","motion-sensor","mqtt","toggle-leds","zigbee2mqtt"],"last_fetched":1711923116.866918},"237324626":{"manifest":{"name":"Toggle Light Automation"},"description":"Simply toggles a light based on another light.","etag_releases":"W/\"dafe54eed982ed81acadcd34a225e8a0c24162911773f4ce6514e43886d62dcb\"","etag_repository":"W/\"31cb61fa736d09b7f41348ead0fc56600f4531066bc607caf8d3fd22146be429\"","full_name":"Petro31/ad_toggle_light","last_commit":"988883b","last_updated":"2020-01-31T00:54:10Z","last_version":"1.1","stargazers_count":9,"last_fetched":1689797537.753827},"234938282":{"manifest":{"name":"Add Domain Group (group.all_*)"},"description":"Adds all legacy group.all_* groups that were removed in Home Asisstant 0.104.","etag_releases":"W/\"50c1ee925cb313cd7458c63667dae6878eb8161bf8fcf0332f69a258200fbeb3\"","etag_repository":"W/\"8354170837bbb7e9ae2cf2b35baf89d2bb226c72fe982737e639d151a26200c6\"","full_name":"Petro31/ad_group_all","last_commit":"9d4c560","last_updated":"2023-06-28T21:47:26Z","last_version":"1.11","stargazers_count":16,"last_fetched":1689470807.42217},"194545176":{"manifest":{"name":"Thermostats Update"},"description":"This app updates Z-Wave thermostats entities state and current temperature from external sensors","etag_releases":"W/\"4f84499a204562a34527c805a2dd892eb0bdd24c945f13513e61985c4df5d7b2\"","etag_repository":"W/\"80c54d7ca4a498ab9139e857fa4f33a6d4e136cedc9ad1e02ea6312dddebd5e7\"","full_name":"bieniu/ha-ad-thermostats-update","last_commit":"c8c67e4","last_updated":"2021-12-15T18:49:17Z","last_version":"0.4.2","stargazers_count":6,"topics":["thermostat","z-wave"],"last_fetched":1678386257.393366},"259132481":{"manifest":{"name":"Auto 'Crappy Internet' Rebooter :rocket:"},"description":"Automatically reboot your crappy internet if you have a zwave, zigbee, or bluetooth switch/socket powering your internet modem. Please :star: if you like this app :)","etag_releases":"W/\"39bb2b245fb1658970e858801321fd0d7507f8891eeeeb489e5382f61a3e58e6\"","etag_repository":"W/\"698c3bd8776a37f0a29fbd2ce7f34bfba59021c1a25512307850d5b77223015d\"","full_name":"UbhiTS/ad-autointernetrebooter","last_commit":"4396365","last_updated":"2023-06-21T16:27:09Z","last_version":"v1.0.6","open_issues":3,"stargazers_count":14,"topics":["alexa-media-player","amazon-alexa","apps","fibaro","internet","modem","router","smartthings","speedtest","speedtest-net","vera","wink"],"last_fetched":1709719996.344996},"202701988":{"manifest":{},"description":"Appdaemon App which toggles entities for single/double/hold presses of Xiaomi buttons connected via deconz","etag_releases":"W/\"ccf55743b49ae8ebc1640788821c0beb728f09321a98d741227387e1b8d771ba\"","etag_repository":"W/\"b9131d6dfcff0296dab26525bde9abb3ad1d95588af8cbf66d07aba84a10c82d\"","full_name":"eifinger/appdaemon-deconz-xiaomi-button","last_commit":"9ae56ae","last_updated":"2019-10-13T16:48:52Z","last_version":"v2.0.2","stargazers_count":4,"last_fetched":1705126538.763439},"236656081":{"manifest":{"name":"Who Used the Door?"},"description":"An Appdaemon automation that creates useful door sensors and door notifications.","etag_releases":"W/\"385900f0abed7ef6263e1aafe93c3bda6e9736565c8f59b822988bbdcab4c734\"","etag_repository":"W/\"020556c432bc7eae406ff515d83f5d62a8ad5017fccdf1cb1ac10e788b4d7551\"","full_name":"Petro31/ad_who_used_the_door","last_commit":"a8c9930","last_updated":"2020-02-14T01:18:46Z","last_version":"1.2","stargazers_count":3,"last_fetched":1690402344.453266},"225791156":{"manifest":{"name":"Alexa (& Friends) Reminders & Talking Clock \ud83d\udc14"},"description":"Alexa (or other Smart Speakers) tell you the time without asking every hour. Please \u2b50\ufe0fif you like my app :)","etag_releases":"W/\"2a5d76c50f42f8234f7ee343fa25783a9ef93fc69f51377d217977b53d646bbd\"","etag_repository":"W/\"430640b4504d17138ebd57abd93ae2a6e5c20f3d5e6b357d4f54de81375b0392\"","full_name":"UbhiTS/ad-alexatalkingclock","last_commit":"9b49314","last_updated":"2020-07-19T20:48:45Z","last_version":"v3.0.2","open_issues":7,"stargazers_count":37,"topics":["alexa","alexa-media-player","alexa-voice-service","amazon-alexa","apps","assistant","time","time-tracker"],"last_fetched":1708812692.37229},"222056780":{"manifest":{"name":"\ud83c\udfae ControllerX"},"description":"Create controller-based automations with ease to control your home devices and scenes.","downloads":5650,"etag_releases":"W/\"c798b54b2372e9995e52d6126dbe608a1df6e675e8848dd2f07c51588a48d530\"","etag_repository":"W/\"71fc4acece46b30b4e688c4e6f38169af6d5a90ec295b0def33c99d3fa2cb316\"","full_name":"xaviml/controllerx","last_commit":"e557b11","last_updated":"2024-04-03T11:34:32Z","last_version":"v4.26.2","open_issues":27,"stargazers_count":319,"topics":["automation","color-lights","controller","covers","ikea","light","remote","switch"],"last_fetched":1712225591.350985},"262373887":{"manifest":{"name":"Count Domain Entities"},"description":"Creates sensors that count the number of entities in a specific domain.","etag_releases":"W/\"cb840b8b1f3735c2862b68e772fc5d349c8c745113712f9f17b3a9c07e3e8842\"","etag_repository":"W/\"4db469ec26edcf64dcc71f94a9a5598f1b2ef62be3397fa32215f0cea6f96fbc\"","full_name":"Petro31/ad_count_entities","last_commit":"bda3f80","last_updated":"2020-05-08T19:15:33Z","last_version":"1.0","last_fetched":1678386258.777823},"288563520":{"manifest":{"name":"Calendar TV Reminders \ud83d\udc14"},"description":"Your TV notifies you of the next upcoming event from you calendar every time it turns on. Please :star: my repo if you like like the app, it will encourage me a lot. ","etag_repository":"W/\"0fc2dbad496c08944c4f12c4a854592d4d445c07dc0da614922c626138f6ea23\"","full_name":"UbhiTS/ad-calendartvreminders","last_commit":"d0764bf","last_updated":"2020-08-18T22:31:49Z","open_issues":3,"stargazers_count":11,"topics":["google","google-calendar","google-calendar-api","lg","smart-tv","smarttv","webos"],"last_fetched":1708769594.318551},"251298857":{"manifest":{"name":"Media Player Lights Sync"},"description":"\ud83d\udca1 AppDaemon App that synchronize RGB lights with the thumbnail of a media player in Home Assistant. Be sure to \u2b50\ufe0f my repo!","etag_releases":"W/\"422300c1ad1a27e4b92b9615f80ffea88d95af55a1d117394a0c7b2d7199f8b6\"","etag_repository":"W/\"8252c1686867bc89c081fb3a1ddc6084a943cbb538251ed3bc50ef43952616b6\"","full_name":"ericmatte/ad-media-lights-sync","last_commit":"6d0586c","last_updated":"2023-04-28T00:21:55Z","last_version":"v1.2.0","open_issues":8,"stargazers_count":93,"topics":["media-lights-sync","rgb-lights"],"last_fetched":1711296845.381933},"226944869":{"manifest":{"country":["CH"],"name":"Hue Dimmer Switch Deconz"},"description":"AppDaemon app for controlling a Hue Dimmer Switch integrated through Deconz","etag_repository":"W/\"27a8e9c291ba87978c98b95e1ab01786e0c760168dee81d9e1be7ae292adec22\"","full_name":"Burningstone91/Hue_Dimmer_Deconz","last_commit":"5e8eca1","last_updated":"2020-11-26T17:06:24Z","open_issues":5,"stargazers_count":21,"topics":["deconz","hue-dimmer-switch"],"last_fetched":1711923116.079673},"258680733":{"manifest":{"name":"Alexa (& Friends) Doorbell \ud83d\udc14"},"description":"Notify your home, and greet your guests on arrival with your Smart Speaker. Please :star: if you like this app :)","etag_releases":"W/\"84bd9753bc35477e0f4cac7567e2f5bc5ff4583613275fe340dd0b4aa26cdbe8\"","etag_repository":"W/\"668149110870804faac14c20f213a367a166ee17f5020897931772d8ad538942\"","full_name":"UbhiTS/ad-alexadoorbell","last_commit":"cfd6034","last_updated":"2020-06-01T16:54:27Z","last_version":"v1.1.0","stargazers_count":13,"topics":["alexa","alexa-media-player","alexa-voice-service","amazon-alexa","apps","assistant","doorbell","greeting"],"last_fetched":1706501697.826333},"282440474":{"manifest":{"name":"Wasp in a Box"},"description":"An AppDaemon app for detecting occupancy using door and motions sensors.","etag_releases":"W/\"edbc7c4c7a53cca2be413f347f8e298fb3e56f4032b6bd196f4612a625d922d0\"","etag_repository":"W/\"07e03b80ced4371c9bb6c5ac7cf50e86d1de4bff4cfabe1c47bf7163cf167ff9\"","full_name":"wernerhp/ha.appdaemon.wasp","last_commit":"8c82a6b","last_updated":"2023-11-16T22:17:18Z","last_version":"v1.2.0","open_issues":2,"stargazers_count":40,"last_fetched":1704781019.848283},"249033464":{"manifest":{"name":"Light automation"},"description":"This appdaemon app fully automates your lights, with multiple on/off times, regular service data, and constraint options.","etag_repository":"W/\"7c1fafc3811f4a73e4d013c1c44a61f199f71aa87e5816033d45c0a57c5d0194\"","full_name":"haberda/light_automation","last_commit":"3d23da0","last_updated":"2021-11-12T00:44:05Z","stargazers_count":9,"last_fetched":1678386257.524358},"258980164":{"manifest":{"name":"Alexa (& Friends) Talking Thermostat \ud83d\udc14"},"description":"Set temp limits, enforce fan modes, door/window and daily shut-off, and air cycling makes your thermostat a genius with a voice using your Smart Speaker! Please :star: if you like the app :)","etag_releases":"W/\"09de2c056be6ea0401781668806ad97697edc5d0376c72dbaf5f6f46df0f593f\"","etag_repository":"W/\"04592a412b71d63d0ab235680557088ace9345a097bb3947def734a9c52d6951\"","full_name":"UbhiTS/ad-alexasmarttalkingthermostat","last_commit":"4f3c8e1","last_updated":"2020-08-18T20:55:19Z","last_version":"v2.0.0","stargazers_count":12,"topics":["alexa","alexa-media-player","alexa-voice-service","amazon-alexa","cooling","heating","hvac","hvac-control","temperature","thermostat"],"last_fetched":1708006282.405295},"230346810":{"manifest":{"name":"Clean-GTFS"},"description":"An appdaemon app for cleaning up a GTFS database for use in Home Assistant","etag_repository":"W/\"6095291aad0c9a86616d6cdb3cfc5342de7b759364861b31bec8502f45daf10b\"","full_name":"simonhq/Clean-GTFS","last_commit":"adb48ba","last_updated":"2020-10-14T19:47:34Z","stargazers_count":2,"topics":["gtfs","gtfs-database"],"last_fetched":1704708865.921942},"242432895":{"manifest":{"name":"Periodic lights"},"description":"This AppDaemon app progressively changes the brightness and color temperature of lights over the course of the day. This app also uses change thresholds to ignore lights that have been manually adjusted.","etag_releases":"W/\"5b8d3f4481ff6d5c3d8c1e5706de10a42e3643896854a9a723c41770d58a588e\"","etag_repository":"W/\"a4dc3dbb410378c29e06ea1641c728087592bcb32a2f638557fb52434f270b34\"","full_name":"haberda/Periodic-lights","last_commit":"0466c4b","last_updated":"2023-08-30T13:47:43Z","last_version":"3.0.0","stargazers_count":23,"topics":["appdeamon","brightness","color-temperature","lights"],"last_fetched":1702332736.597031},"193186453":{"manifest":{},"description":"An app to set the default brightness of lights during the night.","etag_releases":"W/\"d1b4eed0ec102b0b07cd59b4e3868eb88af0c2a6acd3e0aeb452df44553ee80b\"","etag_repository":"W/\"500023394e42ea934f247c873606d35d8863ba42bc499ffb22d996d9c4ac7dec\"","full_name":"apop880/Night-Mode","last_commit":"734e037","last_updated":"2019-07-20T04:49:39Z","last_version":"v1.0.0","open_issues":5,"stargazers_count":6,"last_fetched":1695276991.11625},"231832381":{"manifest":{"name":"Replay lights history"},"description":"AppDaemon App for Home Assistant to replay light switch history when no one is home.","etag_repository":"W/\"0b5d4bc37da39fadb3766cd42eb0e724ad8f146e3df1e5da042791aa0f776e24\"","full_name":"Mohlsson/ReplayLightsHistory","last_commit":"02e3fbb","last_updated":"2023-12-12T18:33:21Z","open_issues":1,"stargazers_count":29,"topics":["lights","replay","vacation"],"last_fetched":1704139986.416472},"200034955":{"manifest":{"name":"\u2744\ufe0f NotiFreeze"},"description":"\u2744\ufe0f AppDaemon app which reminds to close windows if temperature difference inside/outside exceeds a specified threshold","etag_releases":"W/\"958fc777a90a3c7306054648eb22c197724883051246b550a156c3ac66d24aaa\"","etag_repository":"W/\"9e29ca78fb5c401cc26415d283841f7b7acf2c580e280bf5bd0217293cd44459\"","full_name":"benleb/ad-notifreeze","last_commit":"f2b21a4","last_updated":"2022-11-08T14:08:58Z","last_version":"v0.6.0","open_issues":11,"stargazers_count":17,"topics":["close-windows","door","notifreeze","room","temperature","temperature-difference"],"last_fetched":1705421804.032298},"199884854":{"manifest":{"country":["DE"],"name":"\ud83c\udfe5 Healthcheck"},"description":"\ud83c\udfe5 AppDaemon healthcheck app. Can be used as a docker-compose healthcheck.","etag_releases":"W/\"71fdbbce581a4514dd7f4723981754a309af2f0efc8dcdb26bc61f8abf462c8d\"","etag_repository":"W/\"a20d2bd86c57e960f1474df6428d755c3b208a3c2b3bf8a319ca39c5080ff29b\"","full_name":"benleb/ad-healthcheck","last_commit":"c73da19","last_updated":"2020-11-01T16:19:53Z","last_version":"v0.4.4","stargazers_count":2,"topics":["healthcheck"],"last_fetched":1684937563.340961},"262440646":{"manifest":{"country":["AU"],"name":"snowydams"},"description":"HA Appdaemon app for the levels in the Snowy Hydro reservoirs","etag_repository":"W/\"3c9869f5f4bb353ff3407c5a57c80790a0e06a34324bd1100ec827ba6da01545\"","full_name":"simonhq/snowydams","last_commit":"cddad84","last_updated":"2020-05-23T07:48:43Z","topics":["creates-sensors","entity","snowy-dams","snowy-hydro-reservoirs"],"last_fetched":1678386260.176284},"288827256":{"manifest":{"country":["AU"],"name":"asx_portfolio"},"description":"HA sensor for a set of ASX stocks and the number you own","etag_repository":"W/\"526a852951ae9d74194b60b701ba2dd861d8d4dda8a974a72191fcc449c34e3b\"","full_name":"simonhq/asx_portfolio","last_commit":"8badbc1","last_updated":"2020-08-20T22:01:31Z","topics":["asx","asx-portfolio"],"last_fetched":1711801215.31893},"197867243":{"manifest":{},"description":"Check your Home Assistant configuration from the frontend, or automatically when the configuration is updated, and optionally restart HASS automatically!","etag_releases":"W/\"d0864d74526ededbaec5b8d17320b7d7791803b0715031fcac01e2bfbdd69a8b\"","etag_repository":"W/\"0662d771a569c44a0b8261f75c60891dbd3c4630d6eafae86aa08ab47e4749f4\"","full_name":"apop880/config-check","last_commit":"e653011","last_updated":"2020-01-26T06:56:03Z","last_version":"0.3.1","open_issues":8,"stargazers_count":13,"last_fetched":1703852428.357065},"193181086":{"manifest":{},"description":"A white noise machine for a media_player entity.","etag_releases":"W/\"5411330d3f27b880739e8826d56998ffb09b24b5b72ba8cfda7468a589b38189\"","etag_repository":"W/\"ed9cd93288013726010421c5d79a9db97bcdcafa0ca66802fbed143ffe84b090\"","full_name":"apop880/White-Noise","last_commit":"8862a8f","last_updated":"2019-07-20T04:49:30Z","last_version":"v1.0.0","stargazers_count":8,"last_fetched":1678386256.726805},"234713855":{"manifest":{"name":"Bring Back group.all_x"},"description":"Brings back group.all_* for desired domains (light, device_tracker, etc)","etag_releases":"W/\"cc5f408d10524a389854fdddb2e38f99937166a0f1d4519acba52262a6b9682f\"","etag_repository":"W/\"700f916568c4595d717e86daa37af647bd225a01f12385c2c1341b250012f62f\"","full_name":"nickneos/Bring-Back-group.all_x","last_commit":"879c93b","last_updated":"2022-11-28T18:42:57Z","last_version":"v0.3.1","stargazers_count":7,"topics":["group"],"last_fetched":1689470807.322277},"566038918":{"manifest":{"country":["CH"],"name":"EnergiaPro gas consumption"},"description":"HACS AppDaemon to get daily gas readings from EnergiaPro customer portal (CH)","etag_releases":"W/\"4ec67e65e947af46d622218626d3348dfc610b9e96aeb56709b6d4c333c14806\"","etag_repository":"W/\"fc5cd1f3e1e0b0a22efb8760d9179c5daad9d178cdee53f5c0902a3708daed8e\"","full_name":"madchap/energiapro_gas_consumption","last_commit":"c66ba74","last_updated":"2024-01-25T10:01:21Z","last_version":"v2.1.1","stargazers_count":2,"topics":["energiapro"],"last_fetched":1706185476.813051},"287476555":{"manifest":{"country":["AU"],"name":"asx_sensor"},"description":"get ASX information in home assistant","etag_repository":"W/\"faf1fab98f351a433a6e1f36342008b7f5b5818e306deddab40664b0b64333ae\"","full_name":"simonhq/asx_sensor","last_commit":"98a2aad","last_updated":"2024-02-11T21:51:47Z","open_issues":4,"stargazers_count":3,"topics":["asx","asx-sensor"],"last_fetched":1707689447.915546},"200470972":{"manifest":{"country":["DE"],"name":"\ud83d\udca1 AutoMoLi - Auto Motion Lights"},"description":"\ud83d\udca1 Fully automatic light management based on conditions like motion, illuminance, humidity, and other clever features","etag_releases":"W/\"91eeb3a7c83cd8c3aef367c74d00bc2d4a639af5b0b7ea24fa305e4d134265ad\"","etag_repository":"W/\"a28b830f6f816231d74237efdd718eb5f7b77ddebe829b2c42f5895137d83a2f\"","full_name":"benleb/ad-automoli","last_commit":"14920bb","last_updated":"2023-09-12T14:57:04Z","last_version":"v0.11.4","open_issues":25,"stargazers_count":108,"topics":["auto-discovery","automoli","docker","hue","humidity","lights","motion-sensors","room","scenes"],"last_fetched":1710447209.700175},"241233825":{"manifest":{"name":"Tradfri remotes"},"description":"AppDaemon app to control Tradfri remotes","etag_releases":"W/\"23ce7690523710c79f20ce05ca1b0017631afa7b82c7adec3436efca9fb47a6e\"","etag_repository":"W/\"501a23d08a53ca6d8e196deb18dfcb436c4e409680ead79a600bc40da29e5517\"","full_name":"haberda/tradfri_remotes","last_commit":"1ac6802","last_updated":"2021-01-30T18:21:46Z","last_version":"2.0.0","stargazers_count":5,"topics":["lights","tradfri","tradfri-ikea-gateway","tradfri-remotes"],"last_fetched":1689106437.286136},"230623251":{"manifest":{"name":"EUROTRONIC TRV Valve position helper"},"description":"EUROTRONIC TRV Valve position helper is an AppDaemon app that allows access to valve position (%) value from Z-Wave TRVs in Home Assistant","etag_releases":"W/\"65492d14fbf90a2a5d2147fa6f5f8d9d3898841fe523f45d18840f6eb0128788\"","etag_repository":"W/\"921f5f8df69bbb79980ad621e4e44000b0f2f6ce8241c60c6dd7b8b85641e221\"","full_name":"jmarsik/ad-eurotronic-trv-valvepos","last_commit":"5b89faa","last_updated":"2020-05-02T11:29:39Z","last_version":"v1.2","stargazers_count":4,"topics":["eurotronic","trv","zwave"],"last_fetched":1678386258.1754},"267696690":{"manifest":{"name":"Goodnight timer"},"description":"Appdaemon script for Home-Assistant to dim light until it is off in X minutes.","etag_releases":"W/\"8f4ce660280d160fac060bbdf32622900762bb6183b1cfac75b116560d03784e\"","etag_repository":"W/\"3850de98d269ecc31077b6005c74f3f96f7d4c4b1b90837197803964a6a9fe66\"","full_name":"hechi/GoodnightT","last_commit":"43dd02f","last_updated":"2020-05-28T21:22:42Z","last_version":"1.0.0","stargazers_count":2,"topics":["xiaomi","xiaomi-button"],"last_fetched":1704867444.540603},"188970295":{"manifest":{"name":"Monitor-App"},"description":"Appdaemon App for Andrew's Monitor Presence Detection System","etag_repository":"W/\"4aed40f64db428ee92f6fe331dce17a6520f2d42529b0241e0b35516567e4f25\"","full_name":"Odianosen25/Monitor-App","last_commit":"702b953","last_updated":"2021-11-28T08:47:23Z","open_issues":22,"stargazers_count":73,"last_fetched":1712225590.563091},"260599208":{"manifest":{"name":"accu_weather"},"description":"HA allergy sensors from AccuWeather","etag_repository":"W/\"b6fd5b4778f6b693588f05977e0d7f65930148d987e52a6082db4cd195ce0365\"","full_name":"simonhq/accu_allergies","last_commit":"07d3275","last_updated":"2023-03-23T22:23:08Z","open_issues":6,"stargazers_count":19,"topics":["accuweather","accuweather-allergies","allergies-information"],"last_fetched":1709993589.301509},"192933458":{"manifest":{},"description":"An app to handle SmartThings buttons in Home Assistant, through ZHA or the SmartThings integration.","etag_releases":"W/\"8a3b8785bbf4fdee33e6cc0d3dba936c1cf8d11d212f2a0c4245ba2df156615b\"","etag_repository":"W/\"531af714bd7d83ee3149e3c7eea5e0e8e7aa8d0024121bbfd92519eeb1e5102d\"","full_name":"apop880/SmartThings-Button","last_commit":"dc25f39","last_updated":"2020-01-26T06:58:30Z","last_version":"v2.0","stargazers_count":7,"last_fetched":1678386256.782784},"233937451":{"manifest":{"country":["AU"],"name":"canberradams"},"description":"A Home Assistant Appdaemon app for creating a sensor with the ACT Dam level information","etag_repository":"W/\"021dd55e048d2f99d9aa66873bf087bc90a9836a381e2e6d814aee05265ab6fa\"","full_name":"simonhq/canberradams","last_commit":"a1e5e61","last_updated":"2020-08-31T07:00:34Z","open_issues":1,"topics":["creates-sensors","dam","entity"],"last_fetched":1702181708.932777},"266504072":{"manifest":{"name":"Home Alarm"},"description":"Alexa & Google Home alarm integrations and notifications system for your home security.","downloads":901,"etag_releases":"W/\"8cd99a75c6a429b4c652ffffb86d0c9b3d8382cd7af18f35bb359f5404121bc4\"","etag_repository":"W/\"b09aafbc0f62cc09d7e074c7996b82c33c2bb77bdea6272d5fb350a1926f844f\"","full_name":"crserran/home-alarm","last_commit":"a0b614c","last_updated":"2023-03-03T11:43:45Z","last_version":"v2.4.0","open_issues":3,"stargazers_count":21,"topics":["alarm","alexa","googlehome","notifications"],"last_fetched":1703852428.705988},"302770368":{"manifest":{"name":"Ring Doorbell Automations"},"description":"Trigger automations when a Ring Doorbell button is pressed","etag_repository":"W/\"9e0c775a37f5ab5933822fc968128d681a786a30477f0a67cab9d22d72c5045f\"","full_name":"nickneos/Appdaemon-Ring-Doorbell-Automations","last_commit":"f169c68","last_updated":"2020-10-10T05:46:26Z","open_issues":2,"stargazers_count":4,"topics":["ring"],"last_fetched":1708777168.902872},"369204881":{"manifest":{"name":"Omnik Data Logger (using portal or direct logging)"},"description":"Datalogger for Omnik solar power inverters with DSMR integration and output to Home Assistant, PVOUTPUT, InfluxDB and MQTT","etag_releases":"W/\"1635d2554559fbaca9f8eeb04f859cc566d0f131a626e01bab83d189be18f01d\"","etag_repository":"W/\"bb585d3728c05edc0ee96499278b10810c1d9efbf29130a5ee4247478048362f\"","full_name":"jbouwh/omnikdatalogger","last_commit":"4c7aa90","last_updated":"2024-03-22T23:40:43Z","last_version":"v1.14.3","stargazers_count":8,"topics":["automation","dsmr-reader","influxdb","mqtt","mqtt-smarthome","pvoutput","solar-energy","solarman","solarmanpv"],"last_fetched":1711155190.525372},"233418481":{"manifest":{"name":"Event Monitor"},"description":"Appdaemon app to monitor events.","etag_releases":"W/\"774cf8ea3ccf5292b8c5b162f75d59c80abe59a544e827e4d1aec20799febfbb\"","etag_repository":"W/\"b6181c0bbb2266dcbb38f1546e179df75a67fe96f3df0b40ced7697e5bdf4109\"","full_name":"Petro31/ad_monitor_events","last_commit":"c19c996","last_updated":"2020-01-15T02:55:20Z","last_version":"1.0","stargazers_count":3,"last_fetched":1678386258.80815},"630782841":{"manifest":{"name":"ELCO Remocon.net AppDaemon"},"description":"An AppDaemon to fetch data from the gas boiler system via the Elco Remocon-Net cloud service and push them to home-assistant entities.","etag_releases":"W/\"1c1ed199b7aac45f8b689bbb418a9d7b5a9dd38ae010b6c90b0c41591ac230cb\"","etag_repository":"W/\"b3a3ea3174c6cfe2ab0fb139b2976d2baa5721d523a5d2b09dfcd348347603d0\"","full_name":"nechry/elco-remocon-net-appdaemon","last_commit":"204182a","last_updated":"2023-11-27T21:05:01Z","last_version":"v1.0.2","stargazers_count":7,"topics":["ariston","ariston-remotethermo","elco","homeassistant-custom-component","remocon-net"],"last_fetched":1708027876.049034},"228037599":{"manifest":{"country":["US"],"name":"Follow Me"},"description":"\ud83d\udeb6\ud83d\udeb6AppDaemon app to loosely couple entities","etag_releases":"W/\"98bf991663abb139c9a26469659f4fb5ebe53d9e4c43f2a4c10915d052df8018\"","etag_repository":"W/\"e9ecc2ac531594f1239489c8c0bc8bbce97b9e749d2a29758393c03eea2175c0\"","full_name":"aneisch/follow_me_appdaemon","last_commit":"c5c6bdc","last_updated":"2021-12-13T16:13:39Z","last_version":"v1.5","stargazers_count":6,"last_fetched":1678386256.883476},"195525107":{"manifest":{},"description":"Watchdog App for AppDaemon.","etag_repository":"W/\"20bbb1477b9d9d738a8e344fb55027d0b717b967e02002e48292f5026a9f2ddb\"","full_name":"ludeeus/ad-watchdog","last_commit":"78febc8","last_updated":"2019-07-07T13:01:58Z","open_issues":2,"stargazers_count":4,"last_fetched":1711296845.728012},"560310393":{"manifest":{"name":"Calremind"},"description":"Reminder system to process and display upcoming HA calendar events","etag_repository":"W/\"22073af003cc2317a7eee23e95610f0c5cb937c6103dd1bc595cb30600057c31\"","full_name":"nra4ever/calremind","last_commit":"7e10fe0","last_updated":"2022-11-21T18:23:05Z","stargazers_count":1,"last_fetched":1690740815.832337}} ================================================ FILE: tests/fixtures/v2-critical-data.json ================================================ [{"repository":"test/test","reason":"Security issues, known to steal auth tokens.","link":"https://github.com/hacs/default/pull/2"}] ================================================ FILE: tests/fixtures/v2-integration-data.json ================================================ {"139894340":{"manifest":{"country":["US"],"name":"Weatheralerts"},"description":"A sensor that gives you weather alerts from alerts.weather.gov.","domain":"weatheralerts","etag_releases":"W/\"725bc2b9d7e86b8b8ac4640f75f4583ddf35aea6fa33e9622d4bc8a0902e800c\"","etag_repository":"W/\"f84c2f2d298716a4b90397ebd9d25793c4505728630b28c2bab6b1e6740b4ddc\"","full_name":"custom-components/weatheralerts","last_commit":"a2e08c9","last_updated":"2023-04-06T17:24:06Z","last_version":"v0.1.5","manifest_name":"Weatheralerts","open_issues":14,"stargazers_count":119,"topics":["weatheralerts"],"last_fetched":1712117860.260509},"344636306":{"manifest":{"country":["NL"],"name":"SAJ Inverter Modbus"},"description":"Home Assistant Component for reading data locally from SAJ (and Zonneplan) Inverters through modbus TCP.","domain":"saj_modbus","etag_releases":"W/\"cad364b31432dde4772b43e7cc66266849b523ec90d324e787708f85eab35612\"","etag_repository":"W/\"7f85d8a45244c0e88253d02b729c72603361769cdbc90ec5e8e2238a52fe2766\"","full_name":"wimb0/home-assistant-saj-modbus","last_commit":"0a06914","last_updated":"2024-04-02T11:20:55Z","last_version":"v1.9.2","manifest_name":"SAJ Inverter Modbus","open_issues":2,"stargazers_count":28,"topics":["saj-inverters","saj-r5","zonneplan"],"last_fetched":1712082232.823092},"222687548":{"manifest":{"name":"Dwains Dashboard"},"description":"An fully auto generating Home Assistant UI dashboard for desktop, tablet and mobile by Dwains for desktop, tablet, mobile","domain":"dwains_dashboard","etag_releases":"W/\"eada3cc78093c10d20f346885c3afb28cc4be2fa947b26ddcd5c0991fbb8cf2e\"","etag_repository":"W/\"07508ad0502d02dfe4110c1acf10905fc962e1fa25970a37f374f31644cee8e0\"","full_name":"dwainscheeren/dwains-lovelace-dashboard","last_commit":"f5aeb55","last_updated":"2024-03-30T13:21:07Z","last_version":"v3.6.0","manifest_name":"Dwains Dashboard","open_issues":139,"stargazers_count":1634,"topics":["dashboard","dwains-lovelace-dashboard","home-assistant-dashboard"],"last_fetched":1712182448.766113},"695661255":{"manifest":{"country":["UY"],"name":"UTE Uruguay"},"description":"Home Assistant UTE (Administraci\u00f3n Nacional de Usinas y Trasmisiones El\u00e9ctricas) component for Uruguay \ud83c\uddfa\ud83c\uddfe","domain":"ute","etag_releases":"W/\"bded17d05122940e9e0cf84cee198ceccb4cd6d317755c160a09c2fa1ae26444\"","etag_repository":"W/\"8304df5767157583141ee235d37c81cae187a45745569caa6ddedcf1c23f9b02\"","full_name":"rogsme/ute_homeassistant_integration","last_commit":"e38c577","last_updated":"2024-03-09T22:30:07Z","last_version":"1.4.0","manifest_name":"UTE Uruguay","stargazers_count":6,"topics":["electricity-consumption","iot"],"last_fetched":1711376356.181334},"337228671":{"manifest":{"name":"Porsche Connect"},"description":"Porsche Connect custom component for Home Assistant","domain":"porscheconnect","etag_releases":"W/\"4ee9f426d373ec2f5984fe084689eb2ec02a42f4730c785a2c3fe37e26c0f019\"","etag_repository":"W/\"d0191c8ca7ea9df63ea183f6afbc7590a8dbc25c53dee40fc65857ba92bf7fb9\"","full_name":"CJNE/ha-porscheconnect","last_commit":"f500ad2","last_updated":"2024-02-19T20:39:18Z","last_version":"0.0.18","manifest_name":"Porsche Connect","open_issues":18,"stargazers_count":24,"topics":["porsche"],"last_fetched":1709482492.217697},"401856574":{"manifest":{"name":"Windcentrale"},"description":"Provides Home Assistant sensors for multiple wind turbines from the Windcentrale","downloads":3,"domain":"windcentrale","etag_releases":"W/\"7b675869f0ab02e7df8e1a103b45c23845dbcee10396f59187f6c0b3254b674e\"","etag_repository":"W/\"7370204ab768ec74b45485a06c143097a4fae76d5acf896f3823b48b6bd83bce\"","full_name":"jobvk/Home-Assistant-Windcentrale","last_commit":"3b7ba75","last_updated":"2024-04-02T18:42:50Z","last_version":"2024.4.0","manifest_name":"Windcentrale","stargazers_count":13,"topics":["dutch","wind-turbines","windcentrale"],"last_fetched":1712089020.732658},"293843053":{"manifest":{"name":"Adax heaters"},"description":"Integration for Adax heaters","domain":"adax","etag_releases":"W/\"b06a2793aabfb6b6569d837d01473208d0d69919b07a889f45ad15bfef117657\"","etag_repository":"W/\"ff66be31a818b52ee9498b253b1e8e45057397ff8e0eb3b46c3e10cd3e1803fd\"","full_name":"Danielhiversen/home_assistant_adax","last_commit":"001c5de","last_updated":"2021-04-28T05:30:29Z","last_version":"0.4.5","manifest_name":"Adax","open_issues":8,"stargazers_count":32,"topics":["adax","adax-heaters"],"last_fetched":1707008417.437984},"229140999":{"manifest":{"name":"go-eCharger"},"description":"Home Assistant custom_component for controlling the go-eCharger EV-Charger","domain":"goecharger","etag_releases":"W/\"8049dd36b2df477ffa9fad90d49238e3ca81bf361d6e6bfcdc9814dae2235260\"","etag_repository":"W/\"418e14fd63ae0c7ad7bb077f53beed11390491fce83d1f9ae40e7ffe01164738\"","full_name":"cathiele/homeassistant-goecharger","last_commit":"6bb0e5e","last_updated":"2024-03-18T19:10:40Z","last_version":"0.25.3","manifest_name":"go-eCharger","open_issues":27,"stargazers_count":84,"topics":["charger","component","custom","go-echarger"],"last_fetched":1711642591.949764},"356655356":{"manifest":{"country":["AT"],"name":"wienerlinien"},"description":"A sensor that give you information about departures from a specified Wiener Linien stop.","domain":"wienerlinien","etag_releases":"W/\"913329fc6b553e86f5e195184e035e65098f60ae3565ef130b765c283367efe7\"","etag_repository":"W/\"68bea66bb9cf2323a85f23abb8ecb4e8c1813a3ab80ecc1562d5bf47cef46cb8\"","full_name":"tofuSCHNITZEL/home-assistant-wienerlinien","last_commit":"ff40afd","last_updated":"2022-11-24T22:55:41Z","last_version":"1.2.1","manifest_name":"Wienerlinien","open_issues":9,"stargazers_count":20,"topics":["wiener-linien"],"last_fetched":1711750825.402244},"609302851":{"manifest":{"name":"TPMS_ble"},"description":"\ud83c\udfcd\ufe0f Home Assistant custom integration for Tire Pressure sensors","domain":"tpms_ble","etag_releases":"W/\"33e7f5c042aede058a74922b5dfba82c35219e99c50eb7816e57f2a27afad2ed\"","etag_repository":"W/\"e4b1845396ce9fbcc94ea501d00ca5cec840bb54c10309be73d6b3a5f02845f5\"","full_name":"bkbilly/tpms_ble","last_commit":"066b28d","last_updated":"2024-01-05T22:29:11Z","last_version":"1.0.3","manifest_name":"TPMS_BLE","stargazers_count":13,"topics":["bluetooth-low-energy","tire-pressure","tpms"],"last_fetched":1708460069.771241},"395991055":{"manifest":{"country":["HU"],"name":"Anniversary"},"description":"Anniversary integration for Home Assistant","downloads":12,"domain":"anniversary","etag_releases":"W/\"c1ca36683bc4b0691bb49a1290f5cc82179c13892c6cd142f7b6f73f246f73b3\"","etag_repository":"W/\"e1b96d270c8c6933a9796f8d7feae0a7fa729c338b11c7a2bb8e3f7028944718\"","full_name":"amaximus/anniversary","last_commit":"6205edf","last_updated":"2023-06-08T08:20:08Z","last_version":"0.3.0","manifest_name":"Upcoming anniversary","stargazers_count":16,"last_fetched":1711728937.74374},"463623003":{"manifest":{"name":"Rainforest EMU-2"},"description":"Intergration for the Rainforest EMU-2 energy monitor","domain":"rainforest_emu_2","etag_releases":"W/\"ae7a892929971c218c14c5896bd268702ce777bd1f4987d96c762336a9e899db\"","etag_repository":"W/\"9738cf844c9a4e8c83e6b5ab03ed0b80772db2b3cb5400c09379bed9d641aa59\"","full_name":"ryanwinter/hass-rainforest-emu-2","last_commit":"547df36","last_updated":"2023-07-03T22:39:24Z","last_version":"v1.3.2","manifest_name":"Rainforest EMU-2","open_issues":12,"stargazers_count":24,"topics":["energy"],"last_fetched":1709022152.817691},"646875198":{"manifest":{"name":"Chime TTS"},"description":"A custom Home Assistant integration to play combined audio files before and/or after text-to-speech (TTS) messages","downloads":940,"domain":"chime_tts","etag_releases":"W/\"638f2c16fdfae89a1aa5a83ea7cbdf0ccce5ab3ef625ed83a5cbcb467b44a02b\"","etag_repository":"W/\"c32a15df4866d8187378a863bc99da2b00ac2f7db1132aa9122afb4838061834\"","full_name":"nimroddolev/chime_tts","last_commit":"6e826a9","last_updated":"2024-04-04T06:21:16Z","last_version":"v1.0.0","manifest_name":"Chime TTS","open_issues":9,"stargazers_count":103,"last_fetched":1712218966.383738},"467638459":{"manifest":{"name":"Niko Home Control II"},"description":"Home Assistant Custom Integration for Niko Home Control II","domain":"nhc2","etag_releases":"W/\"9b775fe38543499573906c4c9112f10ce9e46b1b1523cda21c4fb9e7ce4d737c\"","etag_repository":"W/\"d7aa3945842d5d193a538c8102994fd3ed12076b65f22d60fe12da098eae4783\"","full_name":"joleys/niko-home-control-II","last_commit":"55e59d2","last_updated":"2024-03-21T18:27:52Z","last_version":"v4.0.0","manifest_name":"Niko Home Control II","open_issues":3,"stargazers_count":67,"topics":["automation","domotics","niko"],"last_fetched":1712168405.49268},"378767428":{"manifest":{"country":["BR"],"name":"Drivvo"},"description":"Custom component for information about your car's status available on drivvo.com for the home assistant","domain":"drivvo","etag_releases":"W/\"07aeb70a19681ea2587c8559628a2c6c83f3f885891c3e93c89319b773850f56\"","etag_repository":"W/\"453bad9c9d04f2853908f4d4b01a1eb2e5bc096d87a6e0a98bc0c1f79f24fa22\"","full_name":"hudsonbrendon/sensor.drivvo","last_commit":"7d5251f","last_updated":"2023-11-12T21:53:26Z","last_version":"1.1.0","manifest_name":"Drivvo","open_issues":7,"stargazers_count":25,"topics":["car","drivvo","gasoline","supplies","vehicle"],"last_fetched":1711318596.023422},"442878365":{"manifest":{"name":"Golden Security Alarm"},"description":"Custom Home Assistant integration for G90 security systems","domain":"gs_alarm","etag_releases":"W/\"bfa6ed2c2e761b27c50ea5d0f9d302509d07c7c7c8608fc742fee78bc229a59b\"","etag_repository":"W/\"6dc8e76168ac71c54f99daff4f9afe587d8e44fa1de9b9f22aba5413f8978455\"","full_name":"hostcc/hass-gs-alarm","last_commit":"a1a8723","last_updated":"2024-02-11T17:40:27Z","last_version":"1.12.0","manifest_name":"Golden Security Alarm","stargazers_count":1,"topics":["alarm","alarm-panel"],"last_fetched":1707682598.37836},"323155307":{"manifest":{"name":"Duepi Evo"},"description":"Control Duepi_evo based pellet stoves with Home Assistant over wifi using ESPLink","domain":"duepi_evo","etag_releases":"W/\"e6b1eb09faf114f55ed7132824bc8406e1cc51beb42d9d52a31a082205518dfb\"","etag_repository":"W/\"87a9ae9e17750359ec1c6fd08827a9df45d5db74ca643327e93c68e92035711f\"","full_name":"aceindy/Duepi_EVO","last_commit":"8979550","last_updated":"2024-03-26T08:11:56Z","last_version":"v2024.02.20(2)","manifest_name":"Duepi Evo","stargazers_count":19,"topics":["heating-systems"],"last_fetched":1711448060.412239},"621677113":{"manifest":{"name":"OpenEPaperLink"},"description":"Home assistant Integration for the OpenEPaperLink project","domain":"open_epaper_link","etag_releases":"W/\"40c4994992947e9d6c05e7a3a413974415da8d77e53acebbb4cf30a7e736e549\"","etag_repository":"W/\"c795f0da8ca22824634808f9d0332b504917acbabca81e4c83692633a2f1dde4\"","full_name":"jonasniesner/open_epaper_link_homeassistant","last_commit":"39d7144","last_updated":"2024-03-24T07:50:05Z","last_version":"0.4.7.6","manifest_name":"OpenEPaperLink","open_issues":15,"stargazers_count":111,"topics":["epaper-displays"],"last_fetched":1712002696.013048},"401145616":{"manifest":{"name":"myenergi"},"description":"Home Assistant integration for MyEnergi devices","domain":"myenergi","etag_releases":"W/\"a81a75dca24345e9dd0e575a4997edd4257ef45c73b102bff7cd96c2cc21d696\"","etag_repository":"W/\"9a3366a923daac37e78533ec1723608b3879359bf7d390531f59409ce50bb9d3\"","full_name":"CJNE/ha-myenergi","last_commit":"4ee043a","last_updated":"2024-03-27T07:18:38Z","last_version":"0.0.27","manifest_name":"myenergi","open_issues":45,"stargazers_count":125,"topics":["ev-charging","green-energy","myenergi"],"last_fetched":1712225670.374293},"433577406":{"manifest":{"name":"Config Editor"},"description":"Home Assistant Configuration Editor Helper","domain":"config_editor","etag_releases":"W/\"24e69b8e88f48f6033494b474b70d751ff2c9fed950966aacadd2a1385183216\"","etag_repository":"W/\"d93cfe061227f579c9e8c35563c7aea95fa26b9bea4ed1474f3062659735273e\"","full_name":"htmltiger/config-editor","last_commit":"944ad5a","last_updated":"2024-03-07T13:48:27Z","last_version":"4.4","manifest_name":"Config Editor","stargazers_count":28,"topics":["homeassistant-config"],"last_fetched":1711383573.444188},"623127338":{"manifest":{"country":["ES"],"name":"Octopus Spain"},"description":"Componente para Home Assistant que obtiene la \u00faltima factura y la Solar Wallet de Octopus Energy Spain.","domain":"octopus_spain","etag_releases":"W/\"8003be1fd488cb5afeab0e03b27af06c57dcbf4ab957c4fd5846acba120bbc16\"","etag_repository":"W/\"14446e665400ff5dd6d4709a89b0ca23ba675937365d9b97b40be797e9b2bc2f\"","full_name":"MiguelAngelLV/octopus_spain","last_commit":"40cacec","last_updated":"2024-01-07T19:49:30Z","last_version":"V1.1","manifest_name":"Octopus Spain","open_issues":2,"stargazers_count":33,"topics":["homeassistant-custom-component","octopus-energy","spain"],"last_fetched":1710368241.206572},"292390011":{"manifest":{"name":"Peloton"},"description":"A platform which allows you to get current and past ride data from Peloton into HomeAssistant","domain":"peloton","etag_releases":"W/\"ea7eec887b81bf76bf9ecc80a045fc823a40f4cd909a0efc462a469696397ade\"","etag_repository":"W/\"d04025c4ea2b489308807e9a6128b0231c89684c29ff68fb0f4a810addf9e9c4\"","full_name":"edwork/homeassistant-peloton-sensor","last_commit":"ed6c1a9","last_updated":"2023-06-14T17:59:57Z","last_version":"0.10.0","manifest_name":"Peloton","open_issues":13,"stargazers_count":75,"topics":["peloton","peloton-api","peloton-client"],"last_fetched":1711045098.325018},"706873015":{"manifest":{"name":"WundaSmart"},"description":"WundaSmart Integration for Home Assistant","domain":"wundasmart","etag_releases":"W/\"83c13eee4fb8c442cbc7abda341f1e0c026da715f247023eb691f556f27638f8\"","etag_repository":"W/\"eca05a49d1ba5a1555c7045c3287d12fcc99bd8d45da539cf183da1e717ede4e\"","full_name":"tonyroberts/hawundasmart","last_commit":"4d5cb02","last_updated":"2024-03-19T16:36:29Z","last_version":"v1.1.0","manifest_name":"WundaSmart","open_issues":2,"stargazers_count":4,"topics":["heating","heating-control","heating-controller","wundasmart"],"last_fetched":1710872619.109515},"679361462":{"manifest":{"country":["SE"],"name":"SSAM H\u00e4mtschema"},"description":"SSAM integration for Home Assistant","domain":"hassam","etag_releases":"W/\"6f3cb894493818455c03af7cc4d122c6fc7e6d2dc5a02020d869e9e5a6622f7e\"","etag_repository":"W/\"b12f84d7883e901f8e38e5584478ade4cd6d8065fa1dc11dfc3001c5a3c129d1\"","full_name":"kverqus/hassam","last_commit":"b8fb9cc","last_updated":"2024-03-24T13:25:38Z","last_version":"v2.0.0","manifest_name":"SSAM H\u00e4mtschema","stargazers_count":2,"topics":["home-assistant-component","ssam"],"last_fetched":1711297144.794008},"246939713":{"manifest":{"country":["NO"],"name":"Wasteplan TRV"},"description":"Home Assistant component for Trondheim renholdsverk pickups.","domain":"wasteplan_trv","etag_releases":"W/\"2339b17068f0924746e54695b85f93fb5da4dcd231446dfd7171bed44a57c8e0\"","etag_repository":"W/\"343e9502701e80ccda9b7d4312f8a5ed5b453f270c8e661a83cb9bad8a29a2dd\"","full_name":"jonkristian/wasteplan_trv","last_commit":"9c416a9","last_updated":"2023-06-26T10:39:35Z","last_version":"v2.0.1","manifest_name":"Wasteplan TRV","stargazers_count":15,"topics":["trondheim","trv","waste-management"],"last_fetched":1700518594.687483},"242700009":{"manifest":{"name":"Kostal Plenticore"},"description":"Home Assistant Component for Kostal Plenticore ","domain":"kostal_plenticore","etag_releases":"W/\"026ff4d15c74e0ba3d4d889f514abcdf300caad20aee11c3d7af3a73a3f49bae\"","etag_repository":"W/\"f93fdc913e575f3cca49dd7f1e38e869eb4c5bcdaaddeb2f407051665d703d82\"","full_name":"ITTV-tools/homeassistant-kostalplenticore","last_commit":"5072414","last_updated":"2022-07-21T18:38:06Z","last_version":"0.10.0","manifest_name":"Kostal Plenticore Inverter","stargazers_count":14,"topics":["component","kostal","plenticore"],"last_fetched":1700144177.365896},"251039581":{"manifest":{"name":"SolisCloud portal integration"},"description":"HomeAssistant integration for the SolisCloud PV Monitoring portal via SolisCloud API","domain":"solis","etag_releases":"W/\"6bde1a58481cafe09e5d547cc0c8d30ddae4a438f4733c802d8158b704a61f66\"","etag_repository":"W/\"0d8d0dd7caeccda689c77a9673fd3f1f3af4000db001c9caece06a29b3eb64f1\"","full_name":"hultenvp/solis-sensor","last_commit":"c18f770","last_updated":"2024-03-28T22:26:41Z","last_version":"v3.5.2","manifest_name":"Solis Inverter","open_issues":12,"stargazers_count":176,"topics":["solarman","solis","soliscloud"],"last_fetched":1712225809.191661},"544550612":{"manifest":{"country":["HU"],"name":"W1000 energy monitor"},"description":"Home Assistant custom component for W1000 energy portal (e.g. https://energia.eon-hungaria.hu/ ) ","domain":"w1000-energy-monitor","etag_repository":"W/\"0be35d0ffc8530d8a1aae69128618e04f10345ef244c4aa0e879d24b57396696\"","full_name":"ZsBT/hass-w1000-portal","last_commit":"b754e27","last_updated":"2024-04-02T18:36:14Z","manifest_name":"W1000 Energy Monitor","open_issues":4,"stargazers_count":42,"topics":["energy","eon","home-assistant-component","w1000"],"last_fetched":1712089254.261414},"177469955":{"manifest":{"name":"Mitsubishi Kumo Cloud"},"description":"Home Assistant module interfacing with Mitsubishi mini-split units","domain":"kumo","etag_releases":"W/\"b4634f71c393c6f5aa7db7d8b7faebe23745d33a8ffb6254253987a9771877ea\"","etag_repository":"W/\"4ba27f5f3b36034c68fb19315da68cbd7835eb23ce0287373e7b5d7133bfb099\"","full_name":"dlarrick/hass-kumo","last_commit":"b8e041d","last_updated":"2024-02-03T16:22:18Z","last_version":"v0.3.11","manifest_name":"Kumo","open_issues":17,"stargazers_count":84,"topics":["climate","kumo","kumocloud","mini-split","mitsubishi"],"last_fetched":1712168291.967375},"289550686":{"manifest":{"name":"Zoom"},"description":"Custom Home Assistant component for Zoom. Tracks when you are connected to a Zoom call by default but may allow you to track more.","downloads":867,"domain":"zoom","etag_releases":"W/\"87d13945ae95ae5b09d95aa2a597704bba368ef59b29a4b175d43c54685c3d51\"","etag_repository":"W/\"3c2bf48668aa196a0cedd3b75f4a1754cf22e2ed8975f671be2d9b229fbc9400\"","full_name":"raman325/ha-zoom-automation","last_commit":"0803bbe","last_updated":"2024-03-20T15:48:23Z","last_version":"v0.8.5","manifest_name":"Zoom","open_issues":14,"stargazers_count":59,"topics":["automation","ha","webhook-event","zoom"],"last_fetched":1711995751.732366},"570006201":{"manifest":{"name":"Victron GX modbus TCP"},"description":"Integration for Home Assistant to fetch data from the victron gx device via modbusTCP","domain":"victron","etag_releases":"W/\"ae8a088f6c84658d39b082fae15fc154b8f0057eae1f5fdc3c77f2b8d4782b50\"","etag_repository":"W/\"387664a9a240258bbe3cab72d1ef095114e1a84fd707e6b8dd27c8541411dffe\"","full_name":"sfstar/hass-victron","last_commit":"b47a6c3","last_updated":"2024-03-30T11:45:34Z","last_version":"v0.2.0","manifest_name":"victron","open_issues":61,"stargazers_count":135,"topics":["energy","modbus-tcp","victron","victronenergy"],"last_fetched":1712226040.421879},"233092629":{"manifest":{"country":["NO"],"name":"tvh_rec"},"description":"tvheadend recorder sensor - lovelace upcoming media card","domain":"tvh_rec","etag_repository":"W/\"81ec91eb5700bc809d3c3e059fa68fb46e7e77f47653fce950c4299cfe08789f\"","full_name":"kodi1/tvh_rec","last_commit":"dee1e18","last_updated":"2022-01-09T10:38:49Z","manifest_name":"Tvheadend recordings sensor","stargazers_count":3,"topics":["recordings","tvheadend"],"last_fetched":1678387413.707369},"544426802":{"manifest":{"name":"Dreame Vacuum"},"description":"Home Assistant integration for Dreame robot vacuums with map support","downloads":17950,"domain":"dreame_vacuum","etag_releases":"W/\"2e4cc153b2111f425a3e931a30d313936bfb75e65c6e475dd92c3a9be82994d0\"","etag_repository":"W/\"ea4a780bbd845f39900aefca4371f781d31920811fdd7392109f5573cf022913\"","full_name":"Tasshack/dreame-vacuum","last_commit":"4d99c69","last_updated":"2024-04-02T12:04:50Z","last_version":"v1.0.2","manifest_name":"Dreame Vacuum","open_issues":4,"stargazers_count":584,"topics":["automation","cloud","dreame","dreamehome","dreametech","map","mi-home","miio","robot","vacuum","vacuum-map","xiaomi"],"last_fetched":1712204701.123116},"460108030":{"manifest":{"name":"go-eCharger integration for Home Assistant using the MQTT API"},"description":"go-eCharger integration for Home Assistant using the MQTT API","domain":"goecharger_mqtt","etag_releases":"W/\"d93438ec5dac8d405ba035e8b2bd4e2389d0e09afb2d54b14b4609f3ceb68506\"","etag_repository":"W/\"2900b395eeb633542707c2c476f67a01b9901cf289695d5ffddc8c12d13d9687\"","full_name":"syssi/homeassistant-goecharger-mqtt","last_commit":"411fe0d","last_updated":"2024-02-08T07:32:44Z","last_version":"0.22.0","manifest_name":"go-eCharger (MQTT)","open_issues":24,"stargazers_count":65,"topics":["go-echarger","goe-charger"],"last_fetched":1712010046.916399},"140907992":{"manifest":{"country":["NZ","AU"],"name":"Goldair WiFi climate devices"},"description":"Home Assistant integration for Goldair WiFi heaters, dehumidifiers and fans","downloads":940,"domain":"goldair_climate","etag_releases":"W/\"d1ebeb4a46824e9640660eb7d3f62f7dea31ac20cf4af074987b023e831532d1\"","etag_repository":"W/\"00f96cf47de708f093463524861bc715bdf9132dac143b9a6e3532deebd29df5\"","full_name":"nicole-ashley/homeassistant-goldair-climate","last_commit":"df5f895","last_updated":"2022-05-17T04:15:51Z","last_version":"0.1.3","manifest_name":"Goldair WiFi climate devices","open_issues":16,"stargazers_count":19,"topics":["dehumidifier","fan","goldair","heater","wifi"],"last_fetched":1704464287.992621},"164489685":{"manifest":{"name":"Nextbike Integration"},"description":"Nextbike integration for Home Assistant","domain":"nextbike","etag_releases":"W/\"07733ed5bf16e50816b21f763042913526f7103539d6290be00f84293ef397bb\"","etag_repository":"W/\"9ffdd3c8bcc92dc674d30019e6120d624880f1a6105c67748c79accbd8926e09\"","full_name":"syssi/nextbike","last_commit":"30eb4ee","last_updated":"2024-01-04T21:31:29Z","last_version":"1.1.1","manifest_name":"Nextbike integration for Home Assistant","open_issues":1,"stargazers_count":14,"topics":["free-floating","nextbike"],"last_fetched":1709945993.221296},"554898014":{"manifest":{"name":"Fusion Solar"},"description":"Integrate FusionSolar into your Home Assistant.","domain":"fusion_solar","etag_releases":"W/\"d1db978e2c2ab67c029ed4943b2eebfc9ed752156c52687a3ec53d1f2b604dea\"","etag_repository":"W/\"3b071cfb6ffde864434b96e204ac6deb844443fa15cad079e968c4847f4ec8f5\"","full_name":"tijsverkoyen/HomeAssistant-FusionSolar","last_commit":"cdc720d","last_updated":"2024-03-01T10:52:10Z","last_version":"v3.0.4","manifest_name":"FusionSolar","open_issues":1,"stargazers_count":119,"topics":["fusionsolar","huawei"],"last_fetched":1712226067.275117},"674291780":{"manifest":{"name":"Eufy RoboVac"},"description":"Add a Eufy RoboVac easily to Home Assistant","domain":"robovac","etag_releases":"W/\"fd3aaf7dfb5382a2241e52f3ee5839cd33d0814a3e1996f24fb4d04c8d3201af\"","etag_repository":"W/\"87a4d06000ea5b034827f24e3e356f5896e432f5b2a1b4e1b020d8c99cd73960\"","full_name":"CodeFoodPixels/robovac","last_commit":"f397319","last_updated":"2024-03-29T00:36:46Z","last_version":"v1.2.11","manifest_name":"Eufy Robovac","open_issues":28,"stargazers_count":85,"topics":["eufy","robovac","vacuum"],"last_fetched":1712168236.298192},"344660161":{"manifest":{"name":"eGauge"},"description":"Home Assistant custom component for eGauge monitor","domain":"egauge","etag_releases":"W/\"7f6b3e46339fbf3b8f89370f5c2c5331158b1181766f46c1f3ef8bb50ddac4ef\"","etag_repository":"W/\"4cf15235041697749f0bd1f0e8741021b587092c540d5f7850a7696bef29fce8\"","full_name":"neggert/hass-egauge","last_commit":"e0877b0","last_updated":"2023-05-24T06:57:35Z","last_version":"v0.4.1","manifest_name":"eGauge","open_issues":3,"stargazers_count":15,"last_fetched":1710684984.77421},"163322610":{"manifest":{"name":"Panasonic Comfort Cloud HA component"},"description":"Panasonic Comfort Cloud HA component","domain":"panasonic_ac","etag_repository":"W/\"22cb0f8f6c296f9059d6ad43b9a9b1af13ead8f09332526ac0911ea168c68e20\"","full_name":"djbulsink/panasonic_ac","last_commit":"e675fa8","last_updated":"2023-12-22T00:12:31Z","manifest_name":"Panasonic AC","open_issues":11,"stargazers_count":29,"last_fetched":1710735431.273996},"210194956":{"manifest":{"name":"Car Wash"},"description":"Car Wash Binary Sensor for Home Assistant","downloads":3,"domain":"car_wash","etag_releases":"W/\"26c2a1f2ee7f2f0e115abaf8fd9e80c76948a29eafe3894ac2a7f42ba93b94a7\"","etag_repository":"W/\"52ca2592eded40d548371ab94a156939b58d25cc2b0033018d0d4ad41648dbed\"","full_name":"Limych/ha-car_wash","last_commit":"84695ef","last_updated":"2023-03-26T00:33:13Z","last_version":"1.5.5","manifest_name":"Car Wash","open_issues":10,"stargazers_count":77,"topics":["binary-sensor","car","car-wash","wash","weather-forecast"],"last_fetched":1712192469.995652},"374763546":{"manifest":{"name":"AIMP Media Player"},"description":"AIMP custom component for \ud83c\udfe0 Home Assistant using web remote","domain":"aimp","etag_repository":"W/\"a4d4dbc0598e67a234773755c1da9b20ffd73aef0368b1adf050d2cf0b86dc78\"","full_name":"xilense/aimp_custom_component","last_commit":"108431c","last_updated":"2021-06-21T18:20:20Z","manifest_name":"AIMP Media Player","stargazers_count":6,"topics":["aimp","internet-of-things","iot","iot-automation","raspberry-pi","remote-control"],"last_fetched":1705616430.767882},"241427839":{"manifest":{"country":["NL"],"name":"Omnik Inverter Solar Sensor (No Cloud)"},"description":"Read the current, daily and total Wh from your Omnik Inverter via local network (no cloud!)","domain":"omnik_inverter","etag_releases":"W/\"ed01686e9956eb435577c4ced01ed7b43625ee05fd59e01c1ebdf736d3bc1814\"","etag_repository":"W/\"d1f635ff81566831ac42058bf64aeea8cd3c6cd2e9e598a68d4df14d5fa71fe6\"","full_name":"robbinjanssen/home-assistant-omnik-inverter","last_commit":"1c7cc95","last_updated":"2024-04-03T09:00:14Z","last_version":"v2.6.4","manifest_name":"Omnik Inverter","open_issues":7,"stargazers_count":52,"topics":["python3"],"last_fetched":1712139667.619591},"340664955":{"manifest":{"country":["IL"],"name":"Proof Dashcam Integration"},"description":"HACS integration to proof.co.il dashcam","domain":"proof","etag_releases":"W/\"7b40ce6cdbadc0aaa2a33ea2a7fc7d25fc310ac0b62cc43afaac412b4970c4b1\"","etag_repository":"W/\"68de452ea26ebfee878b7d0160c3636a3076a23f78b8a4ed84f95ec3a031d8ff\"","full_name":"dimagoltsman/ha-proof-dashcam-integration","last_commit":"46562f0","last_updated":"2021-03-13T18:43:28Z","last_version":"0.1.3","manifest_name":"Proof Dashcam","stargazers_count":1,"topics":["proof"],"last_fetched":1681812997.243097},"537806998":{"manifest":{"name":"Overwolf Webhook"},"description":"Home Assistant custom integration that handles game events from Overwolf and broadcasts them as events in Home Assistant","domain":"overwolfstatus","etag_releases":"W/\"7984e87b087e8d3ba2082070b0e46505816849ad8bc469cd50b912c2d4ffffc4\"","etag_repository":"W/\"78a5679fc5d2494971a4746eb3301fdda44149bb4eb277745b90970222ef8acc\"","full_name":"lociii/homeassistant-overwolf-status","last_commit":"1c2c97f","last_updated":"2023-03-29T18:56:17Z","last_version":"1.0.1","manifest_name":"Overwolf Webhook","stargazers_count":9,"topics":["game-state-integration","gaming","overwolf"],"last_fetched":1707181150.528134},"328566789":{"manifest":{"country":["US"],"name":"BeoPlay"},"description":"Home Assistant component to control BeoPlay including TVs, Speakers and others. ","domain":"beoplay","etag_releases":"W/\"95d2f16a8b7f3646c8113cd28218b7c212719c85ba897a02c53376b18931549d\"","etag_repository":"W/\"900de68c3ae7f228b27836fdb6771b201e21d3b05293dd1b5b67ae405dcb2bf0\"","full_name":"giachello/beoplay","last_commit":"65e64b8","last_updated":"2024-03-20T01:39:23Z","last_version":"v2024.3.2","manifest_name":"BeoPlay for Bang & Olufsen","open_issues":2,"stargazers_count":20,"topics":["bang-olufsen"],"last_fetched":1711242188.618914},"463652459":{"manifest":{"country":["DE"],"name":"BEST Bottrop Garbage Collection Dates"},"description":"Home Assistant Component for BEST Bottrop Garbage Collection Dates","domain":"best_bottrop_garbage_collection","etag_releases":"W/\"25b864a0e6cca2f617e28a4ff3c27179d21187e78a3511b9947b82cf7d3b332e\"","etag_repository":"W/\"229cf23a5ac187452a11a428775656b9c73c97a1239a961af32ce366e7c457bc\"","full_name":"Nazze/ha_best_bottrop_garbage_collection","last_commit":"c7f9139","last_updated":"2023-12-30T17:51:07Z","last_version":"v0.26","manifest_name":"BEST Bottrop garbage collection dates","stargazers_count":1,"topics":["bottrop","garbage-collection"],"last_fetched":1703967522.363169},"708304485":{"manifest":{"country":["NZ"],"name":"MetService New Zealand Weather"},"description":"Metservice New Zealand component for Home Assistant","downloads":304,"domain":"metservice_weather","etag_releases":"W/\"34babe1cf8441d7ebe052769ff2fd603fa276d79fbe5a4ce90278e031a43bd1a\"","etag_repository":"W/\"d6faaea0f3a15b8f2ca5310d08aef5c1587991dca71343daf94f1132326d397d\"","full_name":"ciejer/metservice-weather","last_commit":"4ed2dd5","last_updated":"2024-04-01T11:24:17Z","last_version":"v0.6.0","manifest_name":"MetService New Zealand Weather","open_issues":7,"stargazers_count":12,"topics":["weather"],"last_fetched":1711974329.503778},"614438299":{"manifest":{"name":"homee"},"description":"a Home Assistant custom component to integrate the homee smart home platform","domain":"homee","etag_releases":"W/\"4fd9a5dc7baf030e03b6bdcdc2ec088bf02141e940ffd54ed32999ed0d1974de\"","etag_repository":"W/\"8e49cde053b88a28a1914dc9f3676f2d38a1a009157c22ecb55a0cc17ee7405c\"","full_name":"Taraman17/hass-homee","last_commit":"d304e23","last_updated":"2024-03-18T09:01:03Z","last_version":"v2.9.2","manifest_name":"homee","open_issues":6,"stargazers_count":12,"topics":["homee"],"last_fetched":1712132656.905257},"560282866":{"manifest":{"name":"Universal Lighting Controllers"},"description":"Universal Light Controller Integration for Home Assistant","domain":"uniled","etag_releases":"W/\"7c24750387c8d7bf9db806610947fa9a60aa215f5b501c71029b2d978b7762bd\"","etag_repository":"W/\"e462a1531b7f727d7f645727fd42c93aa52c94046412f1a15064e7619a55b18f\"","full_name":"monty68/uniled","last_commit":"9888df5","last_updated":"2024-02-20T07:56:24Z","last_version":"2.2.5","manifest_name":"Universal Light Controller","open_issues":5,"stargazers_count":51,"topics":["banlanx","ble","controller","deng","hao","light","mesh","sp107e","sp110e","sp601e","sp602e","sp608e","sp6117e","sp611e","sp620e","zengge"],"last_fetched":1711981096.2326},"606563418":{"manifest":{"name":"ventoptimization"},"description":"A integration for minimizing heat loss through optimal venting","downloads":1,"domain":"ventoptimization","etag_releases":"W/\"b8c2fa83badfa33d8d64e16c4a8b0dc3a4971bb1c6a647c80f6dd92ca1b39474\"","etag_repository":"W/\"ceda737217c536e61fff5f2fc7fd6108e1e7d2af8ab0e24142e8b3346e956350\"","full_name":"HrGaertner/HA-vent-optimization","last_commit":"525c48b","last_updated":"2023-12-15T23:20:55Z","last_version":"0.7.0","manifest_name":"Vent optimization","open_issues":5,"stargazers_count":16,"topics":["efficiency","optimization","venting"],"last_fetched":1704675731.031927},"364208180":{"manifest":{"name":"Jellyfin"},"description":"Jellyfin integration for Home Assistant","domain":"jellyfin","etag_releases":"W/\"c206690c844b89ab8b2aa5caadab545f48db226cb1a1fa9da6cee8d0d5e79eeb\"","etag_repository":"W/\"6c41f0c211cff0f83af84689787c5dba13646038176b637dc9e7f234e2aec343\"","full_name":"koying/jellyfin_ha","last_commit":"62db27d","last_updated":"2022-10-22T14:54:07Z","last_version":"v1.1.1","manifest_name":"Jellyfin","open_issues":28,"stargazers_count":91,"topics":["jellyfin"],"last_fetched":1711587567.180343},"427773030":{"manifest":{"name":"TuneBlade"},"description":"Home Assistant custom integration for controlling AirPlay devices connected to a TuneBlade server","domain":"tuneblade","etag_releases":"W/\"f4110ff710fff617ccdc881f8c2c011d5e2f11f6665eca7448f75807ba493e75\"","etag_repository":"W/\"6e5c73c96a2c3a45ea0b3a648bfcd0693908e48d03bac328f8df51005067669a\"","full_name":"spycle/tuneblade","last_commit":"bce9847","last_updated":"2022-01-15T20:39:21Z","last_version":"v0.0.5","manifest_name":"TuneBlade","open_issues":1,"stargazers_count":1,"topics":["tuneblade"],"last_fetched":1691197702.810715},"584497784":{"manifest":{"name":"FreeAir Connect"},"description":"Adds data from FreeAir-Connect to Home Assistant","domain":"freeair_connect","etag_releases":"W/\"0bfad788c9ce77c5723f2e941a54a00e723324509fd5b0b7b09a337a730ec4ca\"","etag_repository":"W/\"3b7d2d6bc58e7ae032941c5b03ce652b9abd04ed2af6a9c994e57eabfce3aaa2\"","full_name":"mampfes/ha_freeair_connect","last_commit":"55ab4f5","last_updated":"2024-04-01T08:22:50Z","last_version":"1.3.2","manifest_name":"FreeAir Connect","stargazers_count":12,"topics":["blumartin","freeair","freeair-connect"],"last_fetched":1711966777.423426},"340926904":{"manifest":{"country":["DK"],"name":"Novafos"},"description":"Homeassistant wrapper around the Novafos KMD water metering data warehouse.","domain":"novafos","etag_releases":"W/\"1be6c6d91519be240b596c1336ad092e2ca1124a5633d93cf87ba71470cbcf89\"","etag_repository":"W/\"b26395112b0976f07845f30b37ab82ade9048923b3ed0e5b1a7d41eb5425196e\"","full_name":"kpoppel/homeassistant-novafos","last_commit":"92be5d3","last_updated":"2023-05-03T22:55:31Z","last_version":"v4.1.3","manifest_name":"Novafos","open_issues":3,"stargazers_count":8,"topics":["water"],"last_fetched":1711534699.333419},"327779379":{"manifest":{"name":"Optus"},"description":"Optus Mobile Home Assistant Integration","domain":"optus","etag_releases":"W/\"e2013e2d64fe0d66aa423ae3884a8aaef7123f8551fb536193bc7e59a8cc6800\"","etag_repository":"W/\"425d21142edf2e15c90acdc545b741de5d73c7fc369fb8bf103866c43203b609\"","full_name":"itchannel/optus-ha","last_commit":"7186455","last_updated":"2021-06-13T00:40:48Z","last_version":"0.0.2","manifest_name":"Optus","stargazers_count":3,"topics":["assistant","mobile","optus"],"last_fetched":1678379572.884348},"209996125":{"manifest":{"name":"Remote PicoTTS"},"description":"A custom component for Home Assistant which integrates my picoTTS Addon on HASS.io,","domain":"picotts_remote","etag_releases":"W/\"fff1e0787319a9233accaeb24888809824a89ae86c8750c6ae9db0d985b4d448\"","etag_repository":"W/\"e0b8a5fce4f0717b09c3c80965eecb57c8fe154e5a59833dd55321a2df8f9d6b\"","full_name":"Poeschl/Remote-PicoTTS","last_commit":"b2877ff","last_updated":"2022-06-03T14:25:15Z","last_version":"1.0.1","manifest_name":"Picotts (Remote)","stargazers_count":11,"topics":["component","picotts-addon","remote-picotts"],"last_fetched":1708633176.863504},"482473793":{"manifest":{"country":["FR"],"name":"Prix Carburant"},"description":"R\u00e9cup\u00e9ration des prix des stations en France","domain":"prix_carburant","etag_releases":"W/\"ee9b03bfc5e97c8babd57448c4b433922f261253a4d7d45a9e4d7ec6d182a303\"","etag_repository":"W/\"b91a388af81db33735102423df53a313e23fbaddf4a65656015b3c35d531e90b\"","full_name":"Aohzan/hass-prixcarburant","last_commit":"24db0b2","last_updated":"2024-04-02T13:57:10Z","last_version":"3.5.0","manifest_name":"Prix Carburant","open_issues":4,"stargazers_count":24,"topics":["carburant","gas","price"],"last_fetched":1712074621.930767},"228063780":{"manifest":{"name":"Indoor Air Quality UK Index"},"description":"Indoor Air Quality Sensor Component for Home Assistant","downloads":427,"domain":"iaquk","etag_releases":"W/\"fe67a6965888b8dfd50c2b61494cbe5ea5a97f2076e0201229cf24a71cc3e43a\"","etag_repository":"W/\"07e56c389077a6988333a4e377e4830ec748ba4188327e5f9e28f294d01e3765\"","full_name":"Limych/ha-iaquk","last_commit":"e4c2500","last_updated":"2024-03-20T18:13:03Z","last_version":"1.6.6","manifest_name":"Indoor Air Quality UK Index","open_issues":13,"stargazers_count":97,"topics":["air-quality","indoor"],"last_fetched":1711981058.509366},"259900367":{"manifest":{"country":["DE"],"name":"AbfallPlus"},"description":"AbfallPlus component for Home Assistant ","domain":"abfallplus","etag_releases":"W/\"55c314fd56031b98f3e81003778cc3bca11e5fd6e5f0f74ed54601c14b960bfe\"","etag_repository":"W/\"f9a6d925900425e4580f04e14fcc74bfd0b7daab748f41715f33ece6103501be\"","full_name":"Bouni/abfallplus","last_commit":"db90926","last_updated":"2023-12-06T14:43:35Z","last_version":"0.3.0","manifest_name":"abfallplus","open_issues":3,"stargazers_count":13,"topics":["abfallplus"],"last_fetched":1707826944.351774},"198794376":{"manifest":{"name":"Met.no Nowcast"},"description":"Met.no Nowcast component for Home Assistant","downloads":4,"domain":"metnowcast","etag_releases":"W/\"e003d9bf1f0cc5570bf33bec7a6a90dcd450c9d91987d983d47fd426c729b0bf\"","etag_repository":"W/\"efbfc0198dc563fdb30741014d1fd10807ae10beda0c62c68d036ed11d6fabe1\"","full_name":"toringer/home-assistant-metnowcast","last_commit":"580c516","last_updated":"2023-11-26T18:45:44Z","last_version":"v2.3.1","manifest_name":"Met.no Nowcast","stargazers_count":8,"topics":["metno","nowcast","nowcasting-precipitation"],"last_fetched":1701030056.175765},"669776150":{"manifest":{"name":"BeoLink"},"description":"Home Assistant component that acts as a bridge making your Home Assistant entities available in the BeoLink app","domain":"beolink","etag_releases":"W/\"c3e1d5ef6795ea0858dfb07b23e99ecfe5b087d1367e44230bd931b1f37e738c\"","etag_repository":"W/\"570070ccb7343ab7557f79c76f0c7e2bac60279094757fd43f63d203a23e42fa\"","full_name":"djerik/beolink-ha","last_commit":"fa8d72f","last_updated":"2024-02-21T23:26:00Z","last_version":"1.0.4","manifest_name":"BeoLink","open_issues":1,"stargazers_count":6,"topics":["bangolufsen","beolink-gateway"],"last_fetched":1708563366.618778},"197058358":{"manifest":{},"description":"Emfit QS Sleep Tracker Component for Home Assistant","domain":"emfitqs","etag_releases":"W/\"b0486fb8543bdbce4b897826c5b2dd803f12691700dc66362e22ab1d1a285f2c\"","etag_repository":"W/\"c1c63a30be99b02c8b8ac72d5a2f8876e10b9e865e647fd34097442b8354397f\"","full_name":"jxlarrea/ha-emfitqs","last_commit":"588f80e","last_updated":"2024-01-17T11:11:09Z","last_version":"2.3","manifest_name":"Emfit QS Sleep Tracker","stargazers_count":18,"topics":["emfit","emfitqs","presence","presence-detection","sleep-tracker"],"last_fetched":1708822929.27544},"257634153":{"manifest":{"name":"FXMarketAPI Integration"},"description":"This is a custom component to integrate into FXMarketAPI (https://fxmarketapi.com) to get the live mid-rates in Home Assistant.","domain":"fxmarketapi","etag_releases":"W/\"4727c9f445000a2c63b20c41e5ed64fe3c81ff723cc7ef1b059debcb718246f8\"","etag_repository":"W/\"e2d5f4323f8d31725cfecb74cffc3b2202bb780747064dc87ac9b9fae17b83cd\"","full_name":"rob196/home-assistant-fxmarketapi","last_commit":"c3e467c","last_updated":"2021-06-01T16:32:25Z","last_version":"v1.0.3","manifest_name":"FXMarketAPI","open_issues":1,"stargazers_count":2,"last_fetched":1698109265.61236},"620277986":{"manifest":{"name":"Quatt"},"description":"Unofficial Quatt heat pump integration for Home Assistant","downloads":268,"domain":"quatt","etag_releases":"W/\"ffe53dddd8297ee6d2455373f00d4423c492f1ff262d88b08e04b6aaf5c7b467\"","etag_repository":"W/\"dcfa4aef71680eadd3c698137eeea5cbc816187a0723c9355ada53f20e9fb2c0\"","full_name":"marcoboers/home-assistant-quatt","last_commit":"b17f47a","last_updated":"2024-04-01T11:42:13Z","last_version":"0.5.1","manifest_name":"Quatt","open_issues":9,"stargazers_count":20,"topics":["heatpump","hvac","quatt"],"last_fetched":1711995657.312106},"478745957":{"manifest":{"country":["FR"],"name":"Ile de france Mobilite"},"description":"Custom component for ile de france mobilit\u00e9s","domain":"idfm","etag_releases":"W/\"bcfbe5c1e8cae9d56a3bd781d6b78d5da8f4a9f34030940d5416c519e66de559\"","etag_repository":"W/\"95a091f763a1395125dd78bcb15bb30521e6ba8bf43c6866991eacdbde93471a\"","full_name":"droso-hass/idfm","last_commit":"1d99d86","last_updated":"2024-03-22T18:37:05Z","last_version":"v2.3.0","manifest_name":"Ile de france Mobilite","open_issues":1,"stargazers_count":13,"topics":["time","transports"],"last_fetched":1711801363.808691},"261849832":{"manifest":{"name":"Garo Wallbox"},"description":"Garo wallbox - Home Assistant Component ","domain":"garo_wallbox","etag_releases":"W/\"095d2916a6a8818b269442152a3cc843b24a8ee7dba291ec8f35d5e704fdb290\"","etag_repository":"W/\"d6604b14d30bf95a4716d2cd7971ecd4449c14eb757724a6442c9302eb9d44c7\"","full_name":"sockless-coding/garo_wallbox","last_commit":"3111b6a","last_updated":"2023-07-14T19:15:53Z","last_version":"v1.0.11","manifest_name":"Garo Wallbox","open_issues":20,"stargazers_count":18,"last_fetched":1711707692.816068},"514029149":{"manifest":{"country":["PL"],"name":"Sodexo Dla Ciebie"},"description":"Sodexo Dla Ciebie - Home Assistant Custom Component for Sodexo cards in Poland","domain":"sodexo_dla_ciebie","etag_releases":"W/\"8bc4da869868dfa826f090cf351d630b67bd479895b2355c084216d97a598a07\"","etag_repository":"W/\"d92f03fa4996bb82ad577972d7c5206838a4dd26ceaa6bf17bb1ca3ba2a01edf\"","full_name":"anarion80/sodexo_dla_ciebie","last_commit":"53b13b3","last_updated":"2024-03-07T19:02:04Z","last_version":"v1.1.0","manifest_name":"Sodexo Dla Ciebie","open_issues":1,"topics":["sodexo"],"last_fetched":1711995350.020205},"398739214":{"manifest":{},"description":"Add a Webhook service to HomeAssistant, originally designed for use with Discord Webhooks","downloads":13,"domain":"webhook_service","etag_releases":"W/\"3fbcd1881295ba94ae0ba6c56cbd35c63a9623e568fa6d1ed8791c9efba70118\"","etag_repository":"W/\"6f3d9a9844eb50173743e468fdb4cec16bb96e9bc0787b5e65f74b2fce3e6b31\"","full_name":"HCookie/Webhook-Service-home-assistant","last_commit":"16a8514","last_updated":"2023-03-23T09:33:59Z","last_version":"v1.0","manifest_name":"Webhook Service Integration","open_issues":1,"stargazers_count":9,"topics":["webhooks"],"last_fetched":1712197541.568113},"388979130":{"manifest":{"country":["AU"],"name":"NSW Covid Data"},"description":"A group of sensors for Home Assistant that tracks New South Wales COVID-19 Data","downloads":312,"domain":"nswcovid","etag_releases":"W/\"5c29ebb2094fca4aed1ffb0bb7068b83b456f5e71305da062b6cd022b64322a6\"","etag_repository":"W/\"4628a76a5e62e6f81f45e542f50d475c292cc6cbe2e5d70c150010c8c6d8e97d\"","full_name":"troykelly/homeassistant-au-nsw-covid","last_commit":"0c394ef","last_updated":"2023-02-22T06:17:16Z","last_version":"v0.0.26","manifest_name":"NSW Covid","open_issues":12,"stargazers_count":1,"topics":["covid-19","nsw-government","nsw-health"],"last_fetched":1705062742.518987},"556352757":{"manifest":{"name":"Geo Home Smart Meter Integration"},"description":"Geo Home smart meter integration for Home Assistant","domain":"geo_home","etag_repository":"W/\"6ae7a2d8a09e7cf994e131ca3b0f4a0c29fb0fa47908a45fc170a18655063b11\"","full_name":"mmillmor/geo_home","last_commit":"940a884","last_updated":"2024-03-15T21:28:04Z","manifest_name":"Geo Home","open_issues":4,"stargazers_count":21,"topics":["home-assistant-integration","smart-meter"],"last_fetched":1710550738.586675},"656612812":{"manifest":{"name":"Stream Deck"},"description":"Stream Deck Integration for Home Assistant","domain":"streamdeck","etag_releases":"W/\"e4652e1c0858fa83fa6f96dfaeb8c3ff46a9f7f7a74b9319278cf558280d1aec\"","etag_repository":"W/\"9931322a72ed6845c5fa8dc318f61791d8f48feb474403ac38ea9ddd2ca7b1cf\"","full_name":"Patrick762/hassio-streamdeck","last_commit":"7e8cae1","last_updated":"2023-11-08T20:56:34Z","last_version":"0.0.7","manifest_name":"Stream Deck","open_issues":1,"stargazers_count":12,"topics":["remote-control","stream-deck"],"last_fetched":1709929095.419665},"229755760":{"manifest":{"name":"Balboa Spa Client"},"description":"Balboa spa integration for home-assistant","domain":"balboa","etag_releases":"W/\"7e7863809b9a8a692c482908e01195654eb81da8e8fca4d44d9a52924f4fba17\"","etag_repository":"W/\"eeab3a0b9e721c27592fd71afcc78c4b857fdc3a5145acec265422cad44d1c0d\"","full_name":"garbled1/balboa_homeassistan","last_commit":"aece6fd","last_updated":"2024-01-05T23:15:24Z","last_version":"0.6.1","manifest_name":"Balboa Spa Client","open_issues":16,"stargazers_count":24,"topics":["balboa"],"last_fetched":1704502770.735692},"292720530":{"manifest":{"country":["BY","CA","CH","CY","CZ","DE","EE","ES","FR","GB","GR","HR","HU","IE","IL","IT","KZ","LT","LV","MK","MK","PL","PT","RO","RS","RU","SI","SK","UA"],"name":"Pandora Car Alarm System"},"description":"\ud83d\ude97 Pandora Car Alarm (and Telemetry) System / \u0410\u0432\u0442\u043e\u0441\u0438\u0433\u043d\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438 \u0442\u0435\u043b\u0435\u043c\u0435\u0442\u0440\u0438\u044f Pandora (\u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f BENISH Guard)","domain":"pandora_cas","etag_releases":"W/\"edcb12c0a264e6e96827e2325399bedc85714557cd9b29920ca6b5bc620471eb\"","etag_repository":"W/\"862c3a6c25039f7d4ba2747cb96ff56ab6d7ef7720abe89b8e8fa5c07b226f00\"","full_name":"alryaz/hass-pandora-cas","last_commit":"16c9162","last_updated":"2024-03-31T21:52:04Z","last_version":"v2024.3.10","manifest_name":"Pandora Car Alarm System","open_issues":3,"stargazers_count":33,"topics":["benish","benish-guard","car-system","pandora-alarm","vehicle-tracking"],"last_fetched":1711933212.894289},"590806135":{"manifest":{"name":"Home Assistant Registry"},"description":"Adds services for home assistant registry operations","domain":"ha_registry","etag_releases":"W/\"469bd3e0cf0a298c6fc8ec785cf44226f65d5e5e0886e57abc9b9d750e4223cf\"","etag_repository":"W/\"c3750ced70c542cd99dc8b31ac2480b02767c822b186df8b741d2bf85091e0b9\"","full_name":"amosyuen/ha-registry","last_commit":"af481fc","last_updated":"2024-04-03T15:14:48Z","last_version":"v1.0.0","manifest_name":"Home Assistant Registry","open_issues":11,"stargazers_count":14,"topics":["homeassistant-custom-component"],"last_fetched":1712160942.38856},"632007442":{"manifest":{"country":["NL"],"name":"Home Assisant Eetlijst"},"description":"A custom integration to get your Eetlijst info into Home Assistant","domain":"eetlijst","etag_releases":"W/\"4e3fce8f268c84c7bf1e74d555ffdd465a052de86bb54260c3a2cd12326bc43b\"","etag_repository":"W/\"d7215ce37ef8fd3350069e6d0dfad63d2c2669dbdcf7463387205a34fc30360a\"","full_name":"Slalamander/Home-Assistant-Eetlijst","last_commit":"0961685","last_updated":"2024-02-21T15:54:31Z","last_version":"v1.1.3","manifest_name":"Eetlijst","stargazers_count":1,"topics":["eetlijst"],"last_fetched":1708539758.660403},"560311562":{"manifest":{"country":["NZ"],"name":"ManageMyHealth"},"description":"Add your next ManageMyHealth appointment to Home Assistant's Calendar","downloads":37,"domain":"managemyhealth","etag_releases":"W/\"d3e6ccc10637b0df87a674424faf959fecbf41dd6d844e86636ff08ba2fa9c1f\"","etag_repository":"W/\"163b2a8077cc88595d87e78d074ab0674dda0b79c51b2904105268feb41a5586\"","full_name":"codyc1515/ha-managemyhealth","last_commit":"0ac4ff1","last_updated":"2024-02-04T01:31:20Z","last_version":"v2.2.0","manifest_name":"ManageMyHealth","open_issues":2,"stargazers_count":1,"topics":["appointment","health","managemyhealth","nz"],"last_fetched":1708488958.644479},"598289640":{"manifest":{"country":["US"],"name":"PetKit"},"description":"Home Assistant integration for PetKit devices","downloads":2572,"domain":"petkit","etag_releases":"W/\"96414f3ed385af0ade1a94b50dc129555740f45ec116fc5dae269eed7c6b08b1\"","etag_repository":"W/\"3a891276017535a245a42bd1ac696bbf2d470b8875b355258c7e3dceb6576e49\"","full_name":"RobertD502/home-assistant-petkit","last_commit":"1def454","last_updated":"2024-02-23T23:39:29Z","last_version":"0.1.10","manifest_name":"PetKit","open_issues":4,"stargazers_count":121,"topics":["eversweet-3-pro","fresh-element","fresh-element-mini-pro","fresh-element-solo","pet-feeder","pet-fountain","petkit","petkit-feeder","petkit-hacs","petkit-water-fountain","pura-max","pura-x","smart-feeder","smart-litter-box","smart-pet"],"last_fetched":1712175700.305955},"342026799":{"manifest":{"country":["HU"],"name":"Pollen Information Hungary"},"description":"Home Assistant custom component for Pollen Information in Hungary","domain":"pollen_hu","etag_releases":"W/\"c9b83cf524fe3ec7b21980d3fe898b7593cad8539acbe91efb2730dca1f23e61\"","etag_repository":"W/\"dd0229a49a9df45c8c0a9471e10438a2c88d4730e6f601564d50543995518d95\"","full_name":"amaximus/pollen_hu","last_commit":"af5a37f","last_updated":"2023-09-05T11:47:47Z","last_version":"0.6.0","manifest_name":"Pollen Information Hungary","stargazers_count":10,"topics":["homeassistant-custom-component","hungary"],"last_fetched":1698257727.84027},"490231724":{"manifest":{"name":"Elro Connects"},"description":"Elro Connects K1 for Home Assistant via HACS","domain":"elro_connects","etag_releases":"W/\"083afe7660b915a07aad8e70d087f3fe4b65eadb40dac9b5fafe232b0b241851\"","etag_repository":"W/\"45eb7c7032b1df5b29653413102f735eb5f6ed1f640aaa027137a8aee8775f26\"","full_name":"jbouwh/ha-elro-connects","last_commit":"40989ad","last_updated":"2024-01-04T16:15:43Z","last_version":"v0.2.3","manifest_name":"Elro Connects","open_issues":1,"stargazers_count":9,"topics":["elro","fire-alarm","fire-alarm-monitoring-system","siterwell"],"last_fetched":1705453360.545642},"565137157":{"manifest":{"name":"eDIN+ integration for Home Assistant"},"description":"eDIN+ Home Assistant Integration","domain":"edinplus","etag_releases":"W/\"160d1361de06811e099483942e8af7827c109cf6399a4c78cf8bc7d4cf38a537\"","etag_repository":"W/\"a1582c280215e79fd4d7c2405f74d6608a924573967a47cd264f8fe4d67968b0\"","full_name":"sftgunner/edinplus-integration","last_commit":"b5bb760","last_updated":"2024-02-25T16:50:41Z","last_version":"v0.6.6-alpha","manifest_name":"eDIN+","open_issues":4,"stargazers_count":5,"topics":["edin-plus","home-assistant-custom-component","home-assistant-integration","mode-lighting"],"last_fetched":1708885309.439273},"325635211":{"manifest":{"name":"dobiss"},"description":"Custom Home Assistant Integration for the Dobiss NXT platform","domain":"dobiss","etag_releases":"W/\"54c5f10745350ac053e3b23a43a8ebc7b7b233ed8193904c7ee4fcf3e2857699\"","etag_repository":"W/\"1a3231fd1eb183028c1bd0363d67dda43968ac8b95315bb609eb4f246661c691\"","full_name":"kesteraernoudt/dobiss","last_commit":"78ac45e","last_updated":"2024-03-27T21:17:36Z","last_version":"v1.8","manifest_name":"dobiss","open_issues":4,"stargazers_count":7,"last_fetched":1711577883.470911},"177978011":{"manifest":{"name":"ShellyForHass (Shelly integration)"},"description":"Shelly smart home platform for Home Assistant","downloads":23524,"domain":"shelly","etag_releases":"W/\"56df404af40a3850100aa7b0c05d7fd9ab2d99a478382261317a3ff4dadb7ba2\"","etag_repository":"W/\"0735c128943a57687a451d27712678a211ed8f6bc4942311a37ed5c44225b6ad\"","full_name":"StyraHem/ShellyForHASS","last_commit":"53fa993","last_updated":"2024-02-14T17:31:45Z","last_version":"1.0.5","manifest_name":"Shelly smart home","open_issues":190,"stargazers_count":606,"last_fetched":1711289885.569582},"234983286":{"manifest":{"name":"Govee BLE HCI monitor sensor integration"},"description":"Govee Temperature/Humidity BLE Home Assistant Component","domain":"govee_ble_hci","etag_releases":"W/\"f4e2c5e868e407d9f5323043cca0748f3026e25eb396de595e2317c4cf73ddd6\"","etag_repository":"W/\"e4064a01a455bd14e2c992fcd32d554ca065188c33032fd3b5396c8d94b0221f\"","full_name":"Home-Is-Where-You-Hang-Your-Hack/sensor.goveetemp_bt_hci","last_commit":"a72f65c","last_updated":"2023-01-07T20:46:55Z","last_version":"v0.10.3","manifest_name":"Govee BLE HCI monitor sensor integration","open_issues":1,"stargazers_count":158,"topics":["ble","govee","h5051","h5072","h5074","h5075","h5101","h5102","h5177","h5179","home-assistant-component"],"last_fetched":1710252907.681347},"585145942":{"manifest":{"name":"iRTrans"},"description":"Integration for IRTrans Ethernet devices (LAN DB)","downloads":47,"domain":"irtrans","etag_releases":"W/\"ee1784c5522f26423a37bb22b6a412314c2490bc070032d79d3f5bcc4a71ac16\"","etag_repository":"W/\"f00a8d897edb2cabb681c3f29e2be2aecab0b3e29bd22c6da3b3abf17d6b3892\"","full_name":"schwarzenbergf/irtrans","last_commit":"98385af","last_updated":"2024-04-01T10:29:23Z","last_version":"v1.1","manifest_name":"IRTrans","stargazers_count":4,"topics":["infrared-blaster","infrared-control"],"last_fetched":1711995783.720521},"250498561":{"manifest":{"name":"SecuritySpy for Home Assistant"},"description":"SecuritySpy Integration for Home Assistant with Camera Streams and Motion Detection","domain":"securityspy","etag_releases":"W/\"c18ab3ba2138925663620ac5ad2bb9399f12c131fbaab815a6358314b5b32c84\"","etag_repository":"W/\"82a213267398155fc8bf3c3be1d036547e1788a0d1734e66b306da172b43ff10\"","full_name":"briis/securityspy","last_commit":"e2c0664","last_updated":"2024-04-01T09:16:04Z","last_version":"v1.1.8","manifest_name":"SecuritySpy for Home Assistant","open_issues":14,"stargazers_count":33,"topics":["home-assistant-component","securityspy"],"last_fetched":1711974318.985435},"383608593":{"manifest":{"name":"Toshiba AC"},"description":"Toshiba AC integration into home-assistant.io","downloads":65,"domain":"toshiba_ac","etag_releases":"W/\"db77acc883428537d211d680ed55e517890840ee097459791523b629eb01a4a0\"","etag_repository":"W/\"8710eca24b3ee57a4956e330c04c3cf016df9306f4fd02d63887b8ad09d7ee46\"","full_name":"h4de5/home-assistant-toshiba_ac","last_commit":"86f9dba","last_updated":"2024-01-04T22:00:57Z","last_version":"2024.1.0","manifest_name":"Toshiba AC","open_issues":22,"stargazers_count":103,"topics":["climate","toshiba"],"last_fetched":1711456002.808894},"302145522":{"manifest":{"country":["CA"],"name":"Rocket Launch Live - Next 5 Launches"},"description":"Home Assistant custom HACS integration to integrate the next 5 global rocket launches from https://rocketlaunch.live","domain":"rocketlaunchlive","etag_releases":"W/\"32b03123c1888a786c670e3122735201cf438e45abdef3659ba7a3eb586821d6\"","etag_repository":"W/\"d2cf85d0f8b48aadf8b1a901a670c8236f00097892e1cb5922cbba9cfcff619f\"","full_name":"djtimca/harocketlaunchlive","last_commit":"adf5d7d","last_updated":"2024-01-02T18:55:27Z","last_version":"12a","manifest_name":"Rocket Launch Live - Next 5 Launches","open_issues":1,"stargazers_count":15,"topics":["launch","nasa","rocket","spacex","ula"],"last_fetched":1710159910.076058},"311913208":{"manifest":{"name":"Gecko"},"description":"Home Assistant integration for spas equipped with Gecko Alliance in.touch2 modules","domain":"gecko","etag_releases":"W/\"bff9d36141db42e0a7f4fbd24070c2f5463d61fc8e24f70540eb4c29f0c2576e\"","etag_repository":"W/\"c141e3e4943ddb56c6c2dac70efe2720266552eb9dd599c3124f15c6f248e947\"","full_name":"gazoodle/gecko-home-assistant","last_commit":"1938ea7","last_updated":"2023-02-06T20:19:08Z","last_version":"v0.1.9","manifest_name":"Gecko","open_issues":35,"stargazers_count":53,"topics":["gecko","home-assistant-integration","hot-tub","intouch2","jacuzzi","spa"],"last_fetched":1712153715.069171},"202220932":{"manifest":{},"description":"\ud83d\udd39 Change the favicon of your Home Assistant instance","domain":"favicon","etag_releases":"W/\"db41821b054aec5d3ae0546df5f351b8285fa8f3182e29fb8811530fd052bf24\"","etag_repository":"W/\"b148351d47770c6d1a71b1a782de23158290d7fa707337284a54540a80da1e7f\"","full_name":"thomasloven/hass-favicon","last_commit":"af5cf85","last_updated":"2024-01-02T15:26:39Z","last_version":"10.4","manifest_name":"Favicon changer","open_issues":5,"stargazers_count":100,"last_fetched":1711484498.881055},"260169906":{"manifest":{"name":"Luxtronik"},"description":"Luxtronik integration for Home Assistant","domain":"luxtronik","etag_releases":"W/\"6d1b7e7c68be0101b04013833da21e618fd24f440cb2472a9b541230bbc9a056\"","etag_repository":"W/\"99e6a93965a9fef0d914d9d056d34502ed217f05f8dbfebcf3264093bd56376c\"","full_name":"Bouni/luxtronik","last_commit":"3420ab3","last_updated":"2023-09-11T06:05:43Z","last_version":"2023.01.01","manifest_name":"Luxtronik","open_issues":33,"stargazers_count":76,"topics":["luxtronik","luxtronik2"],"last_fetched":1710032312.734308},"172733314":{"manifest":{"name":"HACS"},"description":"HACS gives you a powerful UI to handle downloads of all your custom needs.","downloads":390946,"domain":"hacs","etag_releases":"W/\"57a2ae228b22fd334addd3ab4e7506045c20e67a428dd8e23560dca4efae81db\"","etag_repository":"W/\"5b95a3bf0ff7f0a326b609a5a9be11536435ffc732b333e55b16e2570a8fb514\"","full_name":"hacs/integration","last_commit":"a422090","last_updated":"2024-04-04T10:17:41Z","last_version":"1.34.0","manifest_name":"HACS","open_issues":52,"stargazers_count":4574,"topics":["community","package-manager"],"last_fetched":1712226069.454769},"169467285":{"manifest":{"name":"EdgeOS (Ubiquiti)"},"description":"Integration with EdgeOS (Ubiquiti)","domain":"edgeos","etag_releases":"W/\"23a0e98893ca705ff7f2840dc858d3220c2b21bf138982932b02405dcfea9201\"","etag_repository":"W/\"e66cd0c50fc96f4e0b8f84e0c578bf16204c800d71ffd858652a1b065c1ad7b8\"","full_name":"elad-bar/ha-edgeos","last_commit":"a7e52b6","last_updated":"2024-01-18T14:46:45Z","last_version":"v2.0.31","manifest_name":"Ubiquiti EdgeOS Routers","open_issues":26,"stargazers_count":127,"topics":["edgeos"],"last_fetched":1712002598.526919},"643579135":{"manifest":{"name":"Solar Optimizer"},"description":"The Solar Optimizer integration for Home Assistant starts and stops your equipments depending on the Solar net production","domain":"solar_optimizer","etag_releases":"W/\"318f613c8b57920bf957949107284eba3f11376297f5489c9835c77dd3406cbf\"","etag_repository":"W/\"3f0ad5dc675e6733380900e09e710c0da66cbeab87879c55883d3aafa6cf2ac0\"","full_name":"jmcollin78/solar_optimizer","last_commit":"824b39d","last_updated":"2023-12-21T19:59:23Z","last_version":"1.5.0","manifest_name":"Solar Optimizer","open_issues":9,"stargazers_count":45,"topics":["energy","optimisation","solar"],"last_fetched":1712225835.55366},"453785158":{"manifest":{"country":["FR"],"name":"gogs"},"description":"Gogs component to follow your repositories","domain":"gogs","etag_releases":"W/\"575ffc390bdb7c262c0664d44ec4d3035dd0a64e4e537e9926c724a04e6b9bda\"","etag_repository":"W/\"4a0bc1f3d7e0d234c9b958ff8a31493792e57c7fd3e6266628ae226248593322\"","full_name":"youdroid/home-assistant-gogs","last_commit":"f1c51d1","last_updated":"2022-04-24T20:35:04Z","last_version":"v1.0.1","manifest_name":"gogs","stargazers_count":1,"topics":["gogs","home-assistant-component"],"last_fetched":1678387632.07683},"471000066":{"manifest":{"country":["NO","SE","FI","DK","EE","LT","LV","AT","BE","DE","FR","NL","PL"],"name":"Peaqev ev-Charging"},"description":"Home Assistant custom component that aids in both peak-level energy charge avoidance and spotprice-aware charging.","domain":"peaqev","etag_releases":"W/\"a39751a693150e1bb422d9acd9324eaab39f599cd4ea2c9b4a683041eff04c98\"","etag_repository":"W/\"4171e1b05a006be20a8dc7c0e688e6a639336c067f508c52cfa86ee399775b3a\"","full_name":"elden1337/hass-peaq","last_commit":"0f0bc03","last_updated":"2024-04-02T20:23:10Z","last_version":"3.4.4","manifest_name":"peaqev ev-charging","open_issues":20,"stargazers_count":43,"topics":["chargeamps","easee","effektavgift","effekttariff","ev-charging","garo","peak-shaving","smart-pricing","zaptec"],"last_fetched":1712096225.842739},"232813686":{"manifest":{"name":"SkyQ"},"description":"Home Assistant SkyQ Media player component","downloads":3001,"domain":"skyq","etag_releases":"W/\"e750cdf1017af80ac3d31f25d32a90786ff3547346e30c62c2c5a54faad1af29\"","etag_repository":"W/\"c4cec281da2639f2f69cd9a5ebed9e117a425af7c29aadcac39b10fdb1dd8560\"","full_name":"RogerSelwyn/Home_Assistant_SkyQ_MediaPlayer","last_commit":"a297b9e","last_updated":"2024-01-01T13:21:28Z","last_version":"v2.11.7","manifest_name":"Sky Q","stargazers_count":93,"topics":["homeassistant-custom-component","sky","skyq"],"last_fetched":1710764951.855364},"645730299":{"manifest":{"name":"LeoNTP"},"description":"Home Assistant integration for LeoNTP 1200","domain":"leo_ntp","etag_releases":"W/\"d84bddf0acc80c27862d98a5438e7b1a467c66be4f4595aaea77729d9a2b6513\"","etag_repository":"W/\"847d53136f17265fc3987d6e4d755c658dc6326aa1e71148e0ca9c004b3c631e\"","full_name":"CumpsD/home-assistant-leo-ntp","last_commit":"973b03f","last_updated":"2024-04-01T20:45:11Z","last_version":"v1.2.0","manifest_name":"LeoNTP","stargazers_count":2,"topics":["leo-ntp","ntp","timeserver"],"last_fetched":1712009654.095294},"391700886":{"manifest":{"name":"aria2 integration"},"description":"Aria2 integration for home assistant","domain":"aria2","etag_releases":"W/\"0f6617014b623a0db47714a3fe17935c90c8c772e6547c261a12e9959d32320d\"","etag_repository":"W/\"246d34bdef2251b137838ca6c59fa226252cf0aae2e9db8a35390ded796e4b3e\"","full_name":"deblockt/hass-aria2","last_commit":"cee7587","last_updated":"2023-10-05T19:04:30Z","last_version":"0.4.1","manifest_name":"aria2","open_issues":3,"stargazers_count":4,"topics":["aria2","download-manager","downloader"],"last_fetched":1699446323.835649},"636943975":{"manifest":{"name":"Portainer"},"description":"Portainer integration for Home Assistant","downloads":7409,"domain":"portainer","etag_releases":"W/\"19581ff557852ef5ec67b9408030400cab0e2eb6f904a521f5ebc72edc8d365f\"","etag_repository":"W/\"08ed5d19f0611589acbd753a9dbb643196dad5adba6558219325b73ea6772dcb\"","full_name":"tomaae/homeassistant-portainer","last_commit":"d707063","last_updated":"2024-03-31T12:01:17Z","last_version":"v1.0.2","manifest_name":"Portainer","open_issues":15,"stargazers_count":72,"topics":["docker","homeassistant-custom-component","portainer"],"last_fetched":1711959951.923476},"201963665":{"manifest":{"name":"Healthchecks.io"},"description":"Update and display the status of your healthchecks.io checks.","downloads":1864,"domain":"healthchecksio","etag_releases":"W/\"be6d14ba4a624cab75917bf702a3c9f3f90737614738c9f19e563dd8be94c1b4\"","etag_repository":"W/\"8fbfad640eb5dbb854b6e69d5849363a2d5745a5dffa2b5d988e051c57c124e8\"","full_name":"custom-components/healthchecksio","last_commit":"33341cf","last_updated":"2023-10-09T18:52:42Z","last_version":"22.2.0","manifest_name":"Healthchecks.io","open_issues":5,"stargazers_count":45,"topics":["api-client","healthchecksio","monitor"],"last_fetched":1711995425.265258},"397776105":{"manifest":{"country":["GB"],"name":"Hildebrand Glow (DCC)"},"description":"Home Assistant integration for UK SMETS (Smart) meters pulling data from the DCC via the Hildebrand Glow API ","domain":"hildebrandglow_dcc","etag_releases":"W/\"072c74402023bed02b3a2450fc07f9fe7dd7798b958c15bf2e03c14e73d77ca9\"","etag_repository":"W/\"c19deb82678a7394b28b4d222a25431966182301a90e855a24291cb9002f90de\"","full_name":"HandyHat/ha-hildebrandglow-dcc","last_commit":"98cc0e4","last_updated":"2024-01-23T00:53:28Z","last_version":"v1.0.3","manifest_name":"Hildebrand Glow (DCC)","open_issues":40,"stargazers_count":217,"topics":["electricity","electricity-consumption","energy","energy-consumption","gas","glow","hildebrand","smart-meter","smart-meters","smartmeter","smets","smets2","uk"],"last_fetched":1712161132.234518},"326220257":{"manifest":{"country":["FR","PL","PT"],"name":"Viomi Robot Vacuum Cleaner SE (V-RVCLM21A)"},"description":"Hacky Home assistant support for Viomi SE (V-RVCLM21A)","downloads":2859,"domain":"viomise","etag_releases":"W/\"c100011265cf373fb13c699bee8b4b3e776f8396289e7610fd9b845cf67ae440\"","etag_repository":"W/\"0e8e377b689423cfbb93d4b296c1fc4dbabfbc17c9ad7cb4bae112cc9b4345c5\"","full_name":"marotoweb/home-assistant-vacuum-viomise","last_commit":"791e24e","last_updated":"2022-06-29T18:36:07Z","last_version":"v2022.06.26beta","manifest_name":"Viomi Robot Vacuum Cleaner SE (V-RVCLM21A)","open_issues":9,"stargazers_count":20,"topics":["robot-vacuum","vacuum","viomi"],"last_fetched":1711959787.42991},"528618549":{"manifest":{"name":"Molad Sensor"},"description":"Molad Sensor for HACS","domain":"molad","etag_releases":"W/\"632f953fd6101172c94ea687eb97773435d1cbc15336e0a84a92eac450a437b2\"","etag_repository":"W/\"7360e286236105caa748792c0bf3668661862287f9ec02c73b114a3c253dbe38\"","full_name":"chaimchaikin/molad-ha","last_commit":"a25de66","last_updated":"2024-03-06T02:28:37Z","last_version":"v.0.3.4","manifest_name":"Molad Sensor","topics":["hebrew-calendar","jewish","jewish-calendar","molad"],"last_fetched":1709698554.132608},"693064759":{"manifest":{"name":"HVAC Group"},"description":"Group together `climate` components for easy control","downloads":1275,"domain":"hvac_group","etag_releases":"W/\"fb9aa6b2b495bbb82606411c5fd86576cc9804c41d3d3705909130ee244414f4\"","etag_repository":"W/\"71287510fd4076a6ef9be4b9339f2c687585cd6b856dc7989c4ea0ecef13ae32\"","full_name":"tetele/hvac_group","last_commit":"7aa672e","last_updated":"2024-04-01T18:45:50Z","last_version":"0.2.0","manifest_name":"HVAC Group","open_issues":9,"stargazers_count":16,"topics":["climate","helper"],"last_fetched":1712002928.330437},"292197182":{"manifest":{"name":"Yeelight bluetooth"},"description":"Home assistant custom component for Yeelight bluetooth","domain":"yeelight_bt","etag_releases":"W/\"d27b91d9c83261909023ace842b45e1f6763cebf8a85a6da8b8f827bb81255a7\"","etag_repository":"W/\"2ef06ac9d74c5466b9fce424f4276cc6c0699bc0adf60ea69a05958bb9da1e2b\"","full_name":"hcoohb/hass-yeelightbt","last_commit":"4aba68b","last_updated":"2024-01-05T01:46:51Z","last_version":"v1.4.0","manifest_name":"Yeelight bluetooth","open_issues":9,"stargazers_count":46,"topics":["bluetooth","bluetooth-low-energy","yeelight-lamp"],"last_fetched":1711404958.042304},"366332990":{"manifest":{"name":"Electrolux Wellbeing"},"description":"Get the status from your Electrolux devices connected to Wellbeing","domain":"wellbeing","etag_releases":"W/\"fb67be9ea9fc85c94c58712628ff51bd71833fbf55f7cc66001d1d55548f7513\"","etag_repository":"W/\"94b49f348cc6d0d925ad106edc6de302295353f66e2ebf06e2a22410433a15e0\"","full_name":"JohNan/homeassistant-wellbeing","last_commit":"aded105","last_updated":"2024-02-13T21:39:51Z","last_version":"v1.0.17","manifest_name":"Electrolux Wellbeing","open_issues":12,"stargazers_count":63,"topics":["electrolux","electrolux-wellbeing","wellbeing"],"last_fetched":1711534667.08893},"526379993":{"manifest":{"name":"tami4edge"},"description":"Home Assistant Integration for tami4edge","domain":"tami4edge","etag_repository":"W/\"1e5ebb321957ad29605b3477951b3dbfb255fcc9ee3382d2b394a411618dfd4a\"","full_name":"0xAlon/tami4edge","last_commit":"90e4816","last_updated":"2023-10-17T15:49:45Z","manifest_name":"tami4edge","open_issues":8,"stargazers_count":11,"last_fetched":1708179096.433605},"383732864":{"manifest":{"name":"Garmin Connect"},"description":"The Garmin Connect integration allows you to expose data from Garmin Connect to Home Assistant.","domain":"garmin_connect","etag_releases":"W/\"616accc43be65fe81cbfea1366b657c0eba1e23d76797d5812c1f0184525c74a\"","etag_repository":"W/\"c245a3b49f9bdbae938deb343cc22f60bbec2aea770f067203e490f815fbdfb8\"","full_name":"cyberjunky/home-assistant-garmin_connect","last_commit":"a12306d","last_updated":"2024-04-03T06:09:53Z","last_version":"0.2.19","manifest_name":"Garmin Connect","open_issues":49,"stargazers_count":189,"topics":["garmin-connect","home-assistant-component"],"last_fetched":1712125059.027553},"145180996":{"manifest":{"name":"Feedparser"},"description":"\ud83d\udcf0 RSS Feed Integration","domain":"feedparser","etag_releases":"W/\"07948c0a73be474384f4ddea65cfca105d7008814f0d4fe11bee2793226e1d39\"","etag_repository":"W/\"cd5679bf76254b56639451600e32e013138aa8731779fbddeaeca65a5a388d2f\"","full_name":"custom-components/feedparser","last_commit":"2be3736","last_updated":"2024-03-11T22:01:09Z","last_version":"0.1.11","manifest_name":"Feedparser","open_issues":20,"stargazers_count":129,"topics":["feedparser","home-assistant-component","rss","rss-parser"],"last_fetched":1710965724.623139},"263075818":{"manifest":{"name":"HA-meural"},"description":"Integration for NETGEAR Meural Canvas digital art frame in Home Assistant ","domain":"meural","etag_releases":"W/\"a3c5451544ba41292e9aae10891c26311279324006c0c31af691681e4669cae0\"","etag_repository":"W/\"8b1d157d998ff5081499e89b0ced3b81d6ec051695eeb0f3e9622f6fc6fc1943\"","full_name":"GuySie/ha-meural","last_commit":"8c21d59","last_updated":"2023-08-16T19:55:02Z","last_version":"v1.0.1","manifest_name":"Meural","open_issues":8,"stargazers_count":55,"topics":["meural","netgear"],"last_fetched":1703787541.684135},"517429793":{"manifest":{"name":"EcoStruxure PowerTag Link Gateway"},"description":"EcoStruxure PowerTag Link Gateway","domain":"powertag_gateway","etag_releases":"W/\"7db62dc741b0a17ae1115d28c756da7ecf5d8f058650b6510ef83a4b86e6dfe2\"","etag_repository":"W/\"715712ed70e7f54e367c14324a220eae561fbb3d3a16097dc144912b7f12418f\"","full_name":"Breina/PowerTagGateway","last_commit":"da1007f","last_updated":"2024-03-19T08:19:08Z","last_version":"v0.2.2","manifest_name":"PowerTag Link Gateway","open_issues":3,"stargazers_count":13,"topics":["ecostruxure","energy-monitor","schneider-electric"],"last_fetched":1711275234.096145},"531349329":{"manifest":{"name":"MyDolphin Plus"},"description":"A custom Home Assistant Component for WiFI enabled Maytronics Dolphin pool cleaner robots","domain":"mydolphin_plus","etag_releases":"W/\"428364e6f27f2b71a6833c065e9a0cb1485cbed9c7f3bd92df906e2758afbe04\"","etag_repository":"W/\"a19926f0a61eaa7bde8f9845eb458804a2446f56d1687d8c312e615a7f6dc666\"","full_name":"sh00t2kill/dolphin-robot","last_commit":"8f8b207","last_updated":"2024-04-02T02:48:18Z","last_version":"v1.0.10","manifest_name":"MyDolphin Plus","open_issues":8,"stargazers_count":35,"topics":["dolphin","maytronics","robot"],"last_fetched":1712031763.028187},"622332920":{"manifest":{"name":"TTLock"},"description":"Home Assistant integration for TTLock locks","downloads":1433,"domain":"ttlock","etag_releases":"W/\"79f502453fe9f34f16ceccb1e7f1127c5b0fc4819f0886ad6970265e2085f601\"","etag_repository":"W/\"9c4d078449486d2af7a0e3cbf390c7c253ccc4e56ba20bcd961a1e25859f7b69\"","full_name":"jbergler/hass-ttlock","last_commit":"9a1ee91","last_updated":"2023-12-29T01:05:47Z","last_version":"v0.6.1","manifest_name":"TTLock","open_issues":9,"stargazers_count":42,"topics":["cielsa","e-lok","ttlock"],"last_fetched":1711470006.170039},"228662926":{"manifest":{"country":["NL"],"name":"Toon Climate"},"description":"This component provides a climate device for rooted Toon thermostats.","domain":"toon_climate","etag_releases":"W/\"642203a38dd8b6a05aaa58267e7d21b4b32eb9ddff7762b57a413260e8a6924e\"","etag_repository":"W/\"93a2b2aa643973b6c225b9f60d0dcd6d4bc76f398d208664a0b9b0ca7e13f5bb\"","full_name":"cyberjunky/home-assistant-toon_climate","last_commit":"64efc60","last_updated":"2024-01-02T14:18:42Z","last_version":"1.0.15","manifest_name":"Toon Climate","stargazers_count":31,"last_fetched":1711570526.70284},"101482973":{"manifest":{"name":"Xiaomi Mi Air Purifier, Air Humidifier, Air Fresh and Pedestal Fan Integration"},"description":"Xiaomi Mi Air Purifier and Xiaomi Mi Air Humidifier integration for Home Assistant","domain":"xiaomi_miio_airpurifier","etag_releases":"W/\"e32bf638756fe38f0bb17a2fade13340664c9b14beda2a89d54d927f3c9b1938\"","etag_repository":"W/\"aa1d3539192f8767d3cc001b1c54a967d2de3fa553fedb0ddda6cfd299496340\"","full_name":"syssi/xiaomi_airpurifier","last_commit":"f22c2c0","last_updated":"2024-03-04T09:40:47Z","last_version":"2023.12.0.0","manifest_name":"Xiaomi Mi Air Purifier, Air Humidifier, Air Fresh and Pedestal Fan Integration","open_issues":97,"stargazers_count":438,"topics":["airfresh","airhumidifier","airpurifier","fan","miio","miio-protocol","miot","xiaomi"],"last_fetched":1712089241.365842},"373845609":{"manifest":{"name":"Powercalc"},"description":"Custom component to calculate estimated power consumption of lights and other appliances","downloads":6652,"domain":"powercalc","etag_releases":"W/\"1ecfbad6472cddb3292f58c4eaaed443d82376768f5c9c6a687161e78eae6d8c\"","etag_repository":"W/\"b066f09daa1ae0bffe0c02dd35ae6c8b739ed06aa7720823e7e8e1d591a07b3a\"","full_name":"bramstroker/homeassistant-powercalc","last_commit":"b5e5ad8","last_updated":"2024-04-01T20:01:22Z","last_version":"v1.11.4","manifest_name":"Powercalc","open_issues":14,"stargazers_count":840,"topics":["consumption","energy-monitor","hue-lights","metering","power"],"last_fetched":1712009622.657027},"271984369":{"manifest":{"name":"Ferroamp Sensors"},"description":"Ferroamp MQTT Home Assistant sensors for EnergyHub, SSO, ESM and ESO","domain":"ferroamp","etag_releases":"W/\"13376efb65aed68522f423c0989761ec158c608305585c9db99be4fae7f14fa1\"","etag_repository":"W/\"4a19a765e99f1a9f36fc3998962e1ca6bcbbe4b088aab0e59552a59da521b836\"","full_name":"henricm/ha-ferroamp","last_commit":"56f593d","last_updated":"2024-04-04T04:18:28Z","last_version":"v1.14.1","manifest_name":"Ferroamp MQTT Sensors","open_issues":5,"stargazers_count":36,"topics":["ferroamp","homeassistant-custom-component"],"last_fetched":1712211582.375764},"342427139":{"manifest":{"name":"openHASP"},"description":"Home Assistant custom component for openHASP","domain":"openhasp","etag_releases":"W/\"4f170b06c4175a176697f6acb5415d7e787a892d5fdc77544def16e991df53f2\"","etag_repository":"W/\"8c8e949f789f8e84d464fec860a413dec5f95e5773ceb95dff91310ed501f7ac\"","full_name":"HASwitchPlate/openHASP-custom-component","last_commit":"ee7172a","last_updated":"2024-03-09T01:02:02Z","last_version":"0.6.6","manifest_name":"openHASP","open_issues":13,"stargazers_count":42,"topics":["openhasp"],"last_fetched":1711916199.439725},"232269564":{"manifest":{"country":["CN"],"name":"Konke"},"description":"\u63a7\u5ba2\u5c0fK \u63a5\u5165Home Assistant\uff0c\u652f\u6301\u6700\u65b0\u7248\u672cHA \u76ee\u524d\u6700\u65b0\u7248\u672c\uff080.103\uff09\uff0c\u76f8\u4fe1\u672a\u6765\u7684\u7248\u672c\u4e5f\u53ef\u4ee5\u652f\u6301\u3002","domain":"konke","etag_repository":"W/\"a2f37cd630e1f3e10e7759c17a1b892197b4926fcd1409cf6da7760d018e527e\"","full_name":"5high/konke","last_commit":"186d78f","last_updated":"2024-03-25T06:47:54Z","manifest_name":"\u63a7\u5ba2\u5c0fK","open_issues":4,"stargazers_count":22,"last_fetched":1711354640.060973},"289579468":{"manifest":{"name":"Eskom Loadshedding Interface"},"description":"Fetches loadshedding data from Eskom","domain":"eskom_loadshedding","etag_releases":"W/\"1d221f3eb332219fd4beedb03c918a33ae0466ea14f57b5b832365b91c27f108\"","etag_repository":"W/\"eea2cb696388101fcfa76e44fa5e63d2b52cee4c4ff0d4bb27ff9ee1bc955c37\"","full_name":"swartjean/ha-eskom-loadshedding","last_commit":"f141788","last_updated":"2022-11-27T12:13:05Z","last_version":"v1.1.2","manifest_name":"Eskom Loadshedding Interface","open_issues":7,"stargazers_count":68,"topics":["eskom","eskomsepush","esp","loadshedding","south-africa"],"last_fetched":1710433453.289211},"405007807":{"manifest":{"name":"FoxESS Cloud"},"description":"Home Assistant & FoxESS integration. Monitor you photovoltaic installation directly from HA \u2600\ufe0f \u26a1\ufe0f ","domain":"foxess","etag_releases":"W/\"9d8b4a183924946b49fc09e1f560841af08380d73ace2d21ddf9a794cda3e387\"","etag_repository":"W/\"b86cbea2d28718d55174befddd3268843c0b89c76a7fd46f2e2fd35afbf40af1\"","full_name":"macxq/foxess-ha","last_commit":"7a9a80e","last_updated":"2024-03-28T17:33:38Z","last_version":"v0.38","manifest_name":"HA & FoxESSCloud integration","open_issues":45,"stargazers_count":100,"topics":["energy-monitor","foxess","photovoltaics","pv"],"last_fetched":1712053181.93395},"480112024":{"manifest":{"country":["SE"],"name":"Sj\u00f6fartsverket ViVa"},"description":"Get wind information from the Swedish Sj\u00f6farsverket's ViVa service.","domain":"sjofartsverket_viva","etag_releases":"W/\"c843693534943286778fcf0fd676fda2360bd23f84de839589223905549c7daa\"","etag_repository":"W/\"85c07113e8cffc0a66fda51f97c494f0e91891c2556d5d9971df0622b631901a\"","full_name":"patrickribbing/sjofartsverket_viva-component","last_commit":"f597fff","last_updated":"2023-07-14T12:19:43Z","last_version":"v1.4","manifest_name":"Sj\u00f6fartsverket ViVa","open_issues":1,"stargazers_count":3,"last_fetched":1696868573.507528},"371474642":{"manifest":{"name":"consul"},"description":"home-assistant service for control the consul \ud83d\udd34","domain":"consul","etag_releases":"W/\"86b4f3b0e42669276ca9ce90c717c43c374d0759efadbb187a2199be5c4b2477\"","etag_repository":"W/\"1185a9aec593031fda5b96287c21ae8758c1f5c55463b3f67e2bd08e64d0a018\"","full_name":"gtjadsonsantos/consul","last_commit":"5883891","last_updated":"2021-10-09T12:30:45Z","last_version":"2021.2.0","manifest_name":"consul","stargazers_count":3,"topics":["consul"],"last_fetched":1683757115.227497},"582464471":{"manifest":{"name":"OralB_ble"},"description":"\ud83e\udea5 Integrates OralB Bluetooth Toothbrushes","domain":"oralb_ble","etag_releases":"W/\"8395f9de0b88796ba11d0d543399272dea273f87bd3e41f74b702fdc10512bf8\"","etag_repository":"W/\"b84fb06a953c2cb53131eb23d5e21a19bfca1208125064c1bd3fd14d8abb1c68\"","full_name":"bkbilly/oralb_ble","last_commit":"64a95b1","last_updated":"2023-01-06T07:45:15Z","last_version":"1.0.8","manifest_name":"OralB BLE","open_issues":2,"stargazers_count":6,"topics":["bluetooth","oralb"],"last_fetched":1707228782.01323},"453890532":{"manifest":{"country":["CA"],"name":"Ontario Energy Board"},"description":"Home Assistant component that installs a sensor with the current energy rate for Ontario energy companies","domain":"ontario_energy_board","etag_releases":"W/\"fab8d6023984c1f169bd2675b23f04469ee0c900ba73de1d3680d4d02ce72520\"","etag_repository":"W/\"3da38d417ae01a4162603f7333c06fc615fde3800e6d77e01fefc77d9b833a4c\"","full_name":"jrfernandes/ontario_energy_board","last_commit":"5857098","last_updated":"2023-11-15T17:41:07Z","last_version":"v0.3.6","manifest_name":"Ontario Energy Board","open_issues":8,"stargazers_count":36,"topics":["canada","electricity","energy-prices","hydro","ontario"],"last_fetched":1711858829.899082},"422931599":{"manifest":{"name":"Better Thermostat"},"description":"This custom component for Home Assistant will add crucial features to your climate-controlling TRV (Thermostatic Radiator Valves) to save you the work of creating automations to make it smart. It combines a room-temperature sensor, window/door sensors, weather forecasts, or an ambient temperature probe to decide when it should call for heat and automatically calibrate your TRVs to fix the imprecise measurements taken in the radiator's vicinity.","domain":"better_thermostat","etag_releases":"W/\"96dc41da27a6ef8ca2c6d339a3d9754f4747a5bf92faaa77307ea043c00f80c9\"","etag_repository":"W/\"ae6e8bc0cf5f7e4eeb522eaeca223a4dd88c0334f0eb7e4813c45f4106726880\"","full_name":"KartoffelToby/better_thermostat","last_commit":"6a349d9","last_updated":"2024-03-24T22:24:33Z","last_version":"1.4.0","manifest_name":"Better Thermostat","open_issues":152,"stargazers_count":683,"topics":["climate","energy-efficiency","moes","sea801","sea802","spzb0001","thermostat","ts0601","tuya","zigbee","zigbee2mqtt"],"last_fetched":1712225851.750001},"523291160":{"manifest":{"name":"Daily Schedule"},"description":"Home Assistant Daily Schedule Custom Component","downloads":2169,"domain":"daily_schedule","etag_releases":"W/\"63b4727e2f9523b9e3e1c5c4323cc3464397279c846063e7fcba3a17ee1b4bb2\"","etag_repository":"W/\"0065fda2bdc9d4da2f27186182eb56827607488fb50726335165749ba1213951\"","full_name":"amitfin/daily_schedule","last_commit":"e02d63e","last_updated":"2024-04-01T06:03:22Z","last_version":"v1.6.1","manifest_name":"Daily Schedule","stargazers_count":17,"topics":["homeassistant-custom-component"],"last_fetched":1711995344.659036},"501618674":{"manifest":{"name":"BleBox shutterBox with tilt"},"description":"HACS integration for BleBox shutterBox that adds tilt support","domain":"blebox_shutterbox_tilt","etag_releases":"W/\"d1e34b8cf9d4cb0e4db1e0802e2fff4ab053e20ce2f37ef6be23b50a6a135864\"","etag_repository":"W/\"963a97c00a36bc46579159a503c3dcbea6bf6a4c9f62823d3eafb6431e0465df\"","full_name":"andrzejchm/blebox_shutterbox_tilt","last_commit":"12ec011","last_updated":"2023-10-24T01:14:26Z","last_version":"1.0.1","manifest_name":"BleBox shutterBox with tilt","open_issues":15,"stargazers_count":6,"last_fetched":1698114033.900277},"360408082":{"manifest":{"country":["US"],"name":"Flair"},"description":"Custom component for Home Assistant Core for Flair pucks, vents, rooms, structures, and minisplits ","downloads":455,"domain":"flair","etag_releases":"W/\"625bc43707d62b13d32b44907ce6bf34fc9dd02870f2c0d2fb4df55bc37eeec2\"","etag_repository":"W/\"7b1a7b41cba10ce3a0d2e3883003696dad07bef96e7943aeff2d2443c9648c77\"","full_name":"RobertD502/home-assistant-flair","last_commit":"43414e5","last_updated":"2024-02-06T21:42:47Z","last_version":"0.1.12","manifest_name":"Flair","stargazers_count":85,"topics":["flair","flair-hvac","flair-puck","flair-vent","flair-vents"],"last_fetched":1710291829.498036},"258852884":{"manifest":{"name":"Helios EasyControls Modbus TCP/IP integration"},"description":"Helios EasyControls Modbus TCP/IP integration for Home Assistant","downloads":359,"domain":"easycontrols","etag_releases":"W/\"9893ee56ef4cdde6ba331ba6115f78cdf38d51a2b0d190ca9d92a6f51fedc83d\"","etag_repository":"W/\"e267bef15aa8937088fc67c414806884734d5c3ab6f0fbe571c49ca2e5f49452\"","full_name":"laszlojakab/homeassistant-easycontrols","last_commit":"e68ac2b","last_updated":"2023-08-05T19:06:53Z","last_version":"0.6.0","manifest_name":"Helios Easy Controls","open_issues":12,"stargazers_count":19,"topics":["easycontrols","eazyctrl","modbus"],"last_fetched":1711822859.259467},"346536654":{"manifest":{"name":"Ember Mug"},"description":"Ember Mug Integration for Home Assistant","domain":"ember_mug","etag_releases":"W/\"74f77f167d17b8556ff89a48f8d14cabf2e7618ba7357bbcbae2cd5f35dc3290\"","etag_repository":"W/\"3dfea3b8eadbfda615cb8b823ac99df472e369ba5a1564e6da61f6607407f8a5\"","full_name":"sopelj/hass-ember-mug-component","last_commit":"c6e52b8","last_updated":"2024-02-28T00:19:55Z","last_version":"1.0.0","manifest_name":"Ember Mug","open_issues":4,"stargazers_count":101,"topics":["ember-mug"],"last_fetched":1712153990.152213},"601113362":{"manifest":{"country":["IL"],"name":"MaNish whatsapp custom notification / notify"},"description":"manish custom notifier allows you to send whatsapp notification using Whatsapp Cloud API","domain":"manish","etag_releases":"W/\"bce3a90d7689b9eef0b94c5ae7a1b5f3c7fa51ecc4e7d0ea54266dc9464a2044\"","etag_repository":"W/\"278c6e13c543e2bf3d3b7653b222a811992e716683a0acdfa51b54d14d341650\"","full_name":"t0mer/manish-custom-notifier","last_commit":"d6adeea","last_updated":"2023-03-12T19:46:54Z","last_version":"0.2.0","manifest_name":"Whatsapp notifier basde on manish api wrapper for whatsapp cloud api","open_issues":2,"stargazers_count":18,"topics":["homeassistant-custom-component","notifications","python3","whatsapp","whatsapp-api"],"last_fetched":1692958786.428255},"160728801":{"manifest":{},"description":"Home Assistant Sensor for the LightwaveRF energy monitor","domain":"lightwaverf_energy","etag_releases":"W/\"e6266bde3cdbf473599ae4a30f38aad70db5745afa05db5bb7ce56ed8986aa0b\"","etag_repository":"W/\"c91e379196ff8abcaa8835bc58da1c9ad805baa3e49c7d7bc78b6a2aa8f43793\"","full_name":"asantaga/lightwaverf_HA_EnergySensor","last_commit":"a54b24b","last_updated":"2023-05-16T11:21:38Z","last_version":"R1.6","manifest_name":"Lightwave Energy Monitor","open_issues":6,"stargazers_count":5,"topics":["electricity","energysensor","lightwaverf"],"last_fetched":1701547970.787892},"512922944":{"manifest":{"country":["CZ"],"name":"Czech Energy Spot Prices"},"description":"Home Assistant integration that provides current Czech electricity spot prices based on OTE.","domain":"cz_energy_spot_prices","etag_releases":"W/\"f4cb122e525c671979dc925e684458170b989d9ebc77ff9bfca06c3542e12be3\"","etag_repository":"W/\"91decdbbecfc97b9e290a3f132b0520796121ef906f4d662e5b01790f8da5fb0\"","full_name":"rnovacek/homeassistant_cz_energy_spot_prices","last_commit":"d35d9f2","last_updated":"2023-10-21T20:17:10Z","last_version":"0.6.3","manifest_name":"Czech Energy Spot Prices","open_issues":21,"stargazers_count":62,"topics":["electricity","energy","gas","spot"],"last_fetched":1712089188.782937},"360213486":{"manifest":{"name":"yi-hack Home Assistant integration"},"description":"Home Assistant custom integration for Yi cameras: yi-hack-MStar, yi-hack-Allwinner, yi-hack-Allwinner-v2, yi-hack-v5 and sonoff-hack","domain":"yi_hack","etag_releases":"W/\"c349a2043143e28351d5534dde9df03dac4fb968d7a4dd55dc82d4bbc06a06e6\"","etag_repository":"W/\"69c6a591b99e9ae525270fbeb3539bd31c834c9f5ab2e7a34d73715d9cf51da2\"","full_name":"roleoroleo/yi-hack_ha_integration","last_commit":"9d3a62d","last_updated":"2024-03-31T17:11:48Z","last_version":"0.4.9","manifest_name":"Yi Home Cameras with yi-hack","open_issues":55,"stargazers_count":191,"topics":["camera","custom","firmware","hack","rtsp","yi"],"last_fetched":1712182727.228245},"625923963":{"manifest":{"name":"SOMweb (for Sommer garage doors)"},"description":"Custom component for Home Assistant to manage garage doors and gates by Sommer","downloads":159,"domain":"somweb","etag_releases":"W/\"84a4223bc8416a80311d829288cb7e616f6ef25f14c9b3c17d4ca227c2b74955\"","etag_repository":"W/\"ca1885a6f86f487958ed4cc72a5a2dbada72dcff62182539bb2bec3ea86b9d57\"","full_name":"taarskog/home-assistant-component-somweb","last_commit":"96f83b5","last_updated":"2023-10-09T04:50:03Z","last_version":"v1.0.0","manifest_name":"SOMweb (for Sommer garage doors)","open_issues":3,"stargazers_count":3,"topics":["cover","garage-door-opener","home-assistant-custom-component","home-assistant-integration","sommer","somweb"],"last_fetched":1699028643.750653},"532472578":{"manifest":{"name":"Evonic Fires"},"description":"Unofficial Evonic Fire integration for Home Assistant","domain":"evonic","etag_releases":"W/\"3b37aa02a5066ae9256a6180b7f8ed8b3952c1289f502a12824b88f339cb4ef0\"","etag_repository":"W/\"61ec627c33d446e199d3bf488b946d61c44905cb3989cf941d49e795dbec264c\"","full_name":"greghesp/ha-evonic","last_commit":"38ce590","last_updated":"2023-09-03T07:42:19Z","last_version":"v0.3.2","manifest_name":"Evonic","open_issues":3,"stargazers_count":9,"topics":["evonic","evonicfires","homeassistant-custom-component"],"last_fetched":1710958710.953297},"572284948":{"manifest":{"name":"Carelink Integration"},"description":"Unofficial Home Assistant Carelink Component","domain":"carelink","etag_releases":"W/\"d1d5825ebbf9712da689d388c0946705915ca6a576afcf1fe7785e92ea80e769\"","etag_repository":"W/\"b451086bc097bd50fe3d7767e506c3a949aff7b6825f5a47004819edddfd78fb\"","full_name":"yo-han/Home-Assistant-Carelink","last_commit":"03eb7b4","last_updated":"2024-03-25T16:19:39Z","last_version":"2024.3.1","manifest_name":"carelink","open_issues":4,"stargazers_count":19,"topics":["carelink","diabetic","hassio-integration","medtronic"],"last_fetched":1712197817.067077},"631670903":{"manifest":{"name":"ZCS Lawn Mower Robot"},"description":"ZCS Lawn Mower Robots (Ambrogio, Techline, Wiper) platform as a Custom Component for Home Assistant.","domain":"zcsmower","etag_releases":"W/\"201470aa00f501df2600012a25486e6e02ea11e9be662eafef938060e1f1dc6d\"","etag_repository":"W/\"d1bacb4ab0aebba365f2ee82f9a692af46eadb1071974369a69a40be5d4d889b\"","full_name":"ufozone/ha-zcs-mower","last_commit":"0c09883","last_updated":"2024-04-02T10:30:50Z","last_version":"v1.3.1","manifest_name":"ZCS Lawn Mower Robot","open_issues":3,"stargazers_count":8,"topics":["ambrogio","lawn-mower","lawnmower","mower","mower-robot","wiper","zcs","zucchetti"],"last_fetched":1712061161.403564},"230151505":{"manifest":{"country":["HU"],"name":"Dijnet integration"},"description":"Dijnet integration for Home Assistant","downloads":14,"domain":"dijnet","etag_releases":"W/\"86dea050da3c615a2706f318b77dd3399fb858a84a7eb13bd177d76591012dd4\"","etag_repository":"W/\"cbcf3a42c37521f9968ec6534c26452416d315d381048381a5d678549a452be9\"","full_name":"laszlojakab/homeassistant-dijnet","last_commit":"34c99b3","last_updated":"2024-01-31T19:26:12Z","last_version":"0.6.3","manifest_name":"Dijnet","open_issues":4,"stargazers_count":11,"topics":["dijnet"],"last_fetched":1708446039.78052},"228299254":{"manifest":{"name":"LUNOS Heat Recovery Ventilation"},"description":"LUNOS HRV Ventilation Fan Control for Home Assistant","domain":"lunos","etag_releases":"W/\"a50ab5b6041d47cc5c1711c75195d7af295407a43c582abb5af4b0d5b039df3e\"","etag_repository":"W/\"79a0c4448c4a9072f2b28db22ff4e54a661a730a3ecf7ac52e45bc524ccc40de\"","full_name":"rsnodgrass/hass-lunos","last_commit":"8d58560","last_updated":"2024-01-28T01:41:58Z","last_version":"0.3.0","manifest_name":"LUNOS Heat Recovery Ventilation","stargazers_count":24,"topics":["hrv","hvac","lunos","smart-home-solutions","ventilation"],"last_fetched":1706415719.421098},"422834940":{"manifest":{"name":"Kef Connector"},"description":"A Home Assistant integration for KEF speakers","domain":"kef_connector","etag_releases":"W/\"118dc3073b974086802c3fa946957ed5264e0d0254f8edd7933068aeaefb6192\"","etag_repository":"W/\"4551138250c15d6afea14d5060d4005255caa798744a9571c7bd0157c33af070\"","full_name":"N0ciple/hass-kef-connector","last_commit":"3ea3393","last_updated":"2024-02-20T20:42:08Z","last_version":"0.6.0","manifest_name":"Kef Connector","open_issues":2,"stargazers_count":7,"topics":["kef","ls50","ls50w2","ls60","lsx","lsx2","lsx2lt","speaker"],"last_fetched":1711383709.976366},"601894276":{"manifest":{"country":["CN"],"name":"general_link"},"description":"GeneralLink custom component for Home Assistant","domain":"general_link","etag_releases":"W/\"07feb025df132390f529e81959543c5b8556dfd0486d94af0445a68a1d2c4621\"","etag_repository":"W/\"2fed96cfa9479008a4d499c8c2f46811998e88d353679714d06fecf5ecbb6fde\"","full_name":"leonardlcl/general_link","last_commit":"ad1d1b7","last_updated":"2024-03-29T03:05:05Z","last_version":"v1.5.18","manifest_name":"GeneralLink","stargazers_count":2,"topics":["custom-integration","general","general-link","generallink","link"],"last_fetched":1711686030.259001},"648761057":{"manifest":{"name":"Juke Audio"},"description":"Custom Home Assistant integration for Juke Audio","domain":"jukeaudio_ha","etag_releases":"W/\"bb969f38a2e455927563387642a57913872691f6109f87a9807ec2ba5b5adddd\"","etag_repository":"W/\"f3f875316d3a5ecf81b7d686f1a5586f8ee6b21381e957ec8c28679a5234d67d\"","full_name":"pkarimov/jukeaudio_ha","last_commit":"8f2afcf","last_updated":"2024-01-13T17:25:28Z","last_version":"v0.0.7","manifest_name":"Juke Audio","open_issues":1,"stargazers_count":1,"topics":["jukeaudio"],"last_fetched":1711587682.417267},"395770920":{"manifest":{"name":"OpenEI"},"description":"OpenEI integration for Home Assistant","downloads":11,"domain":"openei","etag_releases":"W/\"76b66aae9adc4acea5305b76e4544a3af4a524346acbfa138f80ab73aca59698\"","etag_repository":"W/\"6fe82791bc034049dc896f91e3d18f04518f448827c9bc777528d54bfa565b90\"","full_name":"firstof9/ha-openei","last_commit":"bd795e9","last_updated":"2023-11-04T17:59:58Z","last_version":"0.1.13","manifest_name":"OpenEI Utility Rates","stargazers_count":14,"topics":["api","energy","rates"],"last_fetched":1705213152.408217},"193371469":{"manifest":{"country":["PL"],"name":"Antistorm"},"description":"This sensor uses official API to get storm warnings from https://antistorm.eu.","downloads":179,"domain":"antistorm","etag_releases":"W/\"c93380a2090c4500b095ffb2fdff1cfac3a69bb1df523d21470daf2f9f868fc0\"","etag_repository":"W/\"a1c1fa141776901fae06a5c511730622bf5d481dff99a8667d3b523711ca2a1e\"","full_name":"PiotrMachowski/Home-Assistant-custom-components-Antistorm","last_commit":"3fe37c5","last_updated":"2024-02-21T11:06:57Z","last_version":"v2.0.0","manifest_name":"Antistorm","stargazers_count":12,"topics":["weather"],"last_fetched":1708604886.999993},"491066500":{"manifest":{"name":"Robonomics"},"description":"Connect your Home Assistant devices to web3 infrastructure with Robonomics Web Services subscription.","domain":"robonomics","etag_releases":"W/\"efe829ec1d9b105f2ff3a043f67237a557cc9a147045c224367e0fbe4470b7bb\"","etag_repository":"W/\"880706cb009847fa828a558352a7f1488748ca54cafb132383e5b739ac6ce415\"","full_name":"airalab/homeassistant-robonomics-integration","last_commit":"a62b708","last_updated":"2024-04-03T13:39:00Z","last_version":"1.7.4","manifest_name":"Robonomics","open_issues":1,"stargazers_count":6,"topics":["blockchain","iot","robonomics"],"last_fetched":1712160926.402891},"495607253":{"manifest":{"country":["DK","NO","SE","FI"],"name":"Nordnet investments API sensors"},"description":"Home Assistant + Nordnet API = awesome sensors with for your investments & holdings","domain":"nordnet","etag_releases":"W/\"d38c50fee3bd18d84fa513b028064c679e0de5d7408e097539be0afa8310073f\"","etag_repository":"W/\"b955c8c61d864b43507ccf4dc5145856afc5ddc3518868b47cf1e2cde0653333\"","full_name":"jippi/hass-nordnet","last_commit":"61916ea","last_updated":"2024-03-01T12:48:46Z","last_version":"v0.3.3","manifest_name":"Nordnet API sensors","open_issues":3,"stargazers_count":6,"topics":["finance","stock-market","stocks"],"last_fetched":1709302552.602429},"196055705":{"manifest":{"name":"Clientraw weather parser"},"description":"Clientraw weather parser (clientraw.txt) for HomeAssistant","domain":"clientraw","etag_releases":"W/\"d955b7a245a2b2a4f1f6eff54e8960529b2370b58e810e0eb41629fc954d19e1\"","etag_repository":"W/\"89654914d28868890ff3053d2167270f2175d31e0301c4b885780a7b858fbb30\"","full_name":"pilotak/homeassistant-clientraw","last_commit":"20c1626","last_updated":"2023-11-02T17:59:30Z","last_version":"v2.6.1","manifest_name":"Clientraw","stargazers_count":19,"topics":["clientraw","davis","weather"],"last_fetched":1702343068.597907},"298816063":{"manifest":{"country":["AU"],"name":"Trackimo Device Tracker"},"description":"Trackimo Integration for HACS Home Assistant","downloads":1,"domain":"trackimo","etag_releases":"W/\"2a13cb2b060999d504a2d21f49d5b72c7b466ed3d35ed7728d8c2eaacac5272d\"","etag_repository":"W/\"90d78d3bd22dcc8a0a342c9af6afeffbe1d643880cb6581292ee56af144cc355\"","full_name":"troykelly/hacs-trackimo","last_commit":"5c45086","last_updated":"2022-06-02T13:49:21Z","last_version":"v0.0.22","manifest_name":"Trackimo","stargazers_count":1,"topics":["geolocation","trackimo"],"last_fetched":1705062742.407598},"235316264":{"manifest":{"country":["CH"],"name":"Meteo Swiss"},"description":":sun_behind_rain_cloud: :switzerland: Meteo Swiss Integration for Home Assisant","domain":"meteo-swiss","etag_releases":"W/\"37ddc760fe37ba39ee245e717bd4a1fed3ac6f541ad83c40bc339967044c2e77\"","etag_repository":"W/\"c03836f283a04a5a87b0e346b78f3b75d8f814ca5db82be84f177abc0883f125\"","full_name":"websylv/homeassistant-meteoswiss","last_commit":"70f9c69","last_updated":"2023-11-07T20:04:53Z","last_version":"1.5","manifest_name":"Meteo Swiss","open_issues":51,"stargazers_count":58,"last_fetched":1710282036.47611},"472497355":{"manifest":{"country":["DK","SE","NO","FI","EE","LV","LT","FR","NL","BE","AT","DE","LU"],"name":"Energi Data Service"},"description":"Fetches spot prices from Energi Data Service","downloads":828,"domain":"energidataservice","etag_releases":"W/\"403e8b50f1bdd26efa3aa53ec8b0b51d2ae4ce251e52226fde7d836bc445bc27\"","etag_repository":"W/\"093fcaa912a8f5a7de10f028ea157ce47e0f7df35beb5bd9d371eaf62b3409f4\"","full_name":"MTrab/energidataservice","last_commit":"20cb11c","last_updated":"2024-04-04T04:56:34Z","last_version":"v1.5.4","manifest_name":"Energi Data Service","open_issues":8,"stargazers_count":153,"topics":["energi","spotprice","statistics"],"last_fetched":1712211713.739084},"685246640":{"manifest":{"country":["ES"],"name":"MeteoGalicia_Tides"},"description":"A Home Assistant integration that provides tides info from MeteoGalicia, the meteorological agency for Galicia, Spain","downloads":13,"domain":"meteogalicia_tides","etag_releases":"W/\"067784d6d250e2e8e25e27fa7281f1ee39440869f60b5e9a3010c055a1466f60\"","etag_repository":"W/\"f8f856e07085dea5feedce523d50b0e3f6f31b979bb17e1ef5d9daaa85e3bc88\"","full_name":"Danieldiazi/homeassistant-meteogalicia_tides","last_commit":"4e258b5","last_updated":"2023-12-25T19:59:07Z","last_version":"2023.9.2","manifest_name":"MeteoGalicia_Tides","stargazers_count":1,"topics":["hacs-custom","meteogalicia","tides"],"last_fetched":1703542400.111649},"323923603":{"manifest":{"name":"Tapo Controller"},"description":"A custom integration to control Tapo devices from home assistant.","domain":"tapo","etag_releases":"W/\"07cd07d334a775efa5f9c549233c264133b7f3cdbcfdf35194fd61a9c8a378b0\"","etag_repository":"W/\"828ecc0de79f92edebec21265716ea2c8890e9e28dd468c918e024f82af63f26\"","full_name":"petretiandrea/home-assistant-tapo-p100","last_commit":"2bcc6ad","last_updated":"2024-03-29T19:14:20Z","last_version":"3.0.0","manifest_name":"Tapo Controller","open_issues":43,"stargazers_count":724,"topics":["energy","l510","l530","l900","monitoring","p100","p105","p110","smart-plug","tapo","tapo-device","tapo-light-bulb"],"last_fetched":1712132561.224406},"524730333":{"manifest":{"name":"Team Tracker"},"description":"Home Assistant integration that provides real-time scores in multiple professional (NBA, NFL, NHL, MLB, MLS, and more), college (NCAA), and international (soccer, golf, tennis, mma, racing) sports using ESPN APIs.","domain":"teamtracker","etag_releases":"W/\"9b745a7ddb9a45df77b1ccdf131971a683ce7e4f47a83cda1f81ced1935d7fd3\"","etag_repository":"W/\"a9c1a317907f2f111928facb054c371a56d8726bf58d78ad8bd782641d957576\"","full_name":"vasqued2/ha-teamtracker","last_commit":"ccce79c","last_updated":"2024-01-10T00:07:17Z","last_version":"v0.11.1","manifest_name":"Team Tracker","open_issues":4,"stargazers_count":121,"topics":["afl","atp","baseball","basketball","espn","football","hockey","mlb","mls","nba","ncaa","nfl","nhl","pga","soccer","teamtracker","ufc","volleyball","wta"],"last_fetched":1711916473.698826},"358505160":{"manifest":{"name":"Weenect"},"description":"Homeassistant integration for weenect","domain":"weenect","etag_releases":"W/\"256e34671d36c16436c8b53b65584f4a58ba37bcd4bc35ca62b09baf8da1f5cd\"","etag_repository":"W/\"d12edf1bf0b34dc1f8b87ed61a66ed89f402dbdbde4f47933707ebf43d8acd77\"","full_name":"eifinger/hass-weenect","last_commit":"2cc0695","last_updated":"2024-03-10T20:28:39Z","last_version":"v5.1.0","manifest_name":"Weenect","open_issues":8,"stargazers_count":4,"topics":["weenect"],"last_fetched":1711995485.741351},"582589896":{"manifest":{"name":"Versatile Thermostat"},"description":"A full featured Thermostat for Home Assistant: presets, window, motion, presence and overpowering management","domain":"versatile_thermostat","etag_releases":"W/\"430da8359a7ef7f65733ae2b077f3cacc0ede87fe583e7a263c241180574c448\"","etag_repository":"W/\"ef1d5110011653c0842371dd4a835fb451be2da1e5ab680eac592cb431870bde\"","full_name":"jmcollin78/versatile_thermostat","last_commit":"2a3d3ff","last_updated":"2024-04-01T11:01:33Z","last_version":"6.2.1","manifest_name":"Versatile Thermostat","open_issues":7,"stargazers_count":229,"topics":["hacs-custom","thermostat"],"last_fetched":1712161169.396461},"544105569":{"manifest":{"name":"BenQ projector"},"description":"Home Assistant integration for BenQ projectors over the serial (and network?) interface.","domain":"benqprojector","etag_releases":"W/\"b34aa65d2e03f72199d613b470e21100a73115b4df8eed8ddcf49a5987b2d54d\"","etag_repository":"W/\"520e3fce4d06b47d58a00dbd52cd0e213e8fbeb8218626c03de3bf54941b87ec\"","full_name":"rrooggiieerr/homeassistant-benqprojector","last_commit":"c3f9fc8","last_updated":"2024-01-24T08:17:26Z","last_version":"0.0.14","manifest_name":"BenQ Projector","open_issues":6,"stargazers_count":20,"topics":["benq","projector","projector-control"],"last_fetched":1710497986.323179},"701510734":{"manifest":{"country":["DE"],"name":"Speedport"},"description":"Home Assistant integration for Telekom Speedport","downloads":351,"domain":"speedport","etag_releases":"W/\"3ca489dc6a8d466d6a6557de2e61d3b3840410718c3d742014b8b1d8fc974260\"","etag_repository":"W/\"2c7aa73dbfefb708ad269ef91010e8eef6e0b43e13c29370fe5a306e57d24c45\"","full_name":"Andre0512/speedport","last_commit":"7546fcb","last_updated":"2024-02-18T21:20:15Z","last_version":"v0.3.5","manifest_name":"Speedport","open_issues":8,"stargazers_count":17,"topics":["custom-integration","speedport","telekom"],"last_fetched":1712002457.523116},"394704821":{"manifest":{"name":"SolaX Inverter Modbus"},"description":"SolaX Power Modbus custom_component for Home Assistant (Supports some Ginlong Solis, Growatt, Sofar Solar, TIGO TSI & Qcells Q.Volt Hyb)","domain":"solax_modbus","etag_releases":"W/\"51810412223fe9cf5ee8284bc45cfac958543087fc8d94ad8b1a23ad6b1709cd\"","etag_repository":"W/\"6708c595686ff0582bfca5a7a1f2bf770147e5723f3a93523dce893ee041659f\"","full_name":"wills106/homeassistant-solax-modbus","last_commit":"3db370a","last_updated":"2024-04-03T16:20:35Z","last_version":"2024.04.1","manifest_name":"SolaX Inverter Modbus","open_issues":55,"stargazers_count":247,"topics":["ginlong-solis","growatt","modbus","modbus-rtu","modbus-serial","modbus-tcp","qcells","qvolt-inverter","rs485","sofar","sofar-hyd","sofarsolar","solax","solis"],"last_fetched":1712182782.998222},"460167330":{"manifest":{"country":["GB"],"name":"Pod Point"},"description":"A simple Home Assistant integration that shows basic information from Pod Point and allows the control of charging schedules to disable and enable the pod.","domain":"pod_point","etag_releases":"W/\"6e8734eafe1586d5aac71636942e341ba749b5ad4f845b51ff4632dd2a74e59d\"","etag_repository":"W/\"145d38d230bce3eb22e7adfebadf797b6bf383c8d529e9c120213fa2906a44c4\"","full_name":"mattrayner/pod-point-home-assistant-component","last_commit":"205eb17","last_updated":"2024-02-11T10:20:25Z","last_version":"1.2.2","manifest_name":"Pod Point","open_issues":6,"stargazers_count":34,"topics":["energy-consumption","ev-charging"],"last_fetched":1712060970.812173},"476357279":{"manifest":{"name":"Music Assistant"},"description":"Turn your Home Assistant instance into a jukebox, hassle free streaming of your favorite media to Home Assistant media players.","downloads":9088,"domain":"mass","etag_releases":"W/\"00975790686497523554bb47813e4fb803f02d2b92e1191fac56c45bfd32dac7\"","etag_repository":"W/\"98bf779af02c761b1d3e6475ef003e1943687a0aed60a3e6d8332e0ac1399827\"","full_name":"music-assistant/hass-music-assistant","last_commit":"f3947c2","last_updated":"2024-04-01T12:27:29Z","last_version":"2024.3.5","manifest_name":"Music Assistant","open_issues":46,"stargazers_count":1042,"topics":["music-library","music-player"],"last_fetched":1712175626.920707},"219363790":{"manifest":{"country":["SE"],"name":"TV4 Play"},"description":"Play videos from the Swedish channel 4","domain":"tv4_play","etag_releases":"W/\"9690481e0ef2cc67632a3191dd664c10378336e9e62c5505aee3243d6893b6c4\"","etag_repository":"W/\"c1a15acc5d9cc2a5e1274ae1eb9bd6708e315b984c5e70b08b91f2166c98d6e8\"","full_name":"lindell/home-assistant-tv4-play","last_commit":"276e34a","last_updated":"2023-11-30T19:35:53Z","last_version":"1.1.2","manifest_name":"TV4 Play","open_issues":2,"stargazers_count":17,"topics":["tv4","tv4play"],"last_fetched":1701382633.051779},"336798340":{"manifest":{"name":"TrueNAS"},"description":"TrueNAS integration for Home Assistant ","downloads":8177,"domain":"truenas","etag_releases":"W/\"c974c1fe23350b095420008122e997be0d6eb1dac95668a8453cc367a7bf6a7d\"","etag_repository":"W/\"3d1a164c6dfcb11f9d70c17bda477ba7a9fcbf1976c31302e6ae02d188e1c860\"","full_name":"tomaae/homeassistant-truenas","last_commit":"851719c","last_updated":"2024-04-03T19:16:33Z","last_version":"v1.2.5","manifest_name":"TrueNAS","open_issues":8,"stargazers_count":153,"topics":["homeassistant-custom-component","truenas"],"last_fetched":1712197815.441812},"250345421":{"manifest":{"name":"Folding@HomeControl"},"description":"Homeassistant integration for FoldingAtHomeControl","domain":"foldingathomecontrol","etag_releases":"W/\"c7d8f07d49d37f38fdc8527528f76a9abd22dbe26fd3aa86c8c2fdb8d311174b\"","etag_repository":"W/\"eeb8940a383cd43f51944e8df9e6610dee8b9992414d502b35534b0dcfcdebd7\"","full_name":"eifinger/hass-foldingathomecontrol","last_commit":"007a366","last_updated":"2024-04-01T17:15:39Z","last_version":"v2.4.1","manifest_name":"Folding@HomeControl","open_issues":3,"stargazers_count":18,"topics":["asyncio","folding-at-home","foldingathome","python3"],"last_fetched":1711995485.591782},"458237432":{"manifest":{"name":"Uptime Kuma"},"description":"Uptime Kuma HACS integration","domain":"uptime_kuma","etag_releases":"W/\"fcdf42feb367168bdb50b9f7449a8befa03d4ff6b8c7b82833c7eb57f5187528\"","etag_repository":"W/\"4c3a5a310ceb215db3988ecad4d03602ec8197f804c157701a169656844813b1\"","full_name":"meichthys/uptime_kuma","last_commit":"d405733","last_updated":"2024-03-18T17:54:39Z","last_version":"v2.3.0","manifest_name":"Uptime Kuma","open_issues":14,"stargazers_count":92,"topics":["home-assistant-custom-component","homeassistant-custom-component","uptime-kuma"],"last_fetched":1711470097.341044},"226707533":{"manifest":{"name":"ltss"},"description":"Long time state storage (LTSS) custom component for Home Assistant using Timescale DB","domain":"ltss","etag_releases":"W/\"56f70ae02377bec7433f7511547fb71ca8523778d59486860ae344af573b65f0\"","etag_repository":"W/\"cc8de3b4656bc238311627ce38ab35b1615aa63ffd3e4bbdd49848173ec624cc\"","full_name":"freol35241/ltss","last_commit":"fb7218a","last_updated":"2024-04-03T18:24:03Z","last_version":"v2.1.0","manifest_name":"Long Time State Storage (LTSS)","open_issues":18,"stargazers_count":73,"topics":["database","ltss","state-storage","storage","timescaledb"],"last_fetched":1712218777.362741},"258012483":{"manifest":{"name":"Livebox TV UHD"},"description":"Livebox TV UHD custom component for Home Assistant","domain":"liveboxtvuhd","etag_releases":"W/\"11c4875db836f45a8fd67e6db6aa3d6f1e7ef04e0913a043792c4b9d65dc8626\"","etag_repository":"W/\"869eb587f3c15ffd867e1eef2c20e53b1d604a57eb6fc89e1e38fa29ac0a233d\"","full_name":"AkA57/liveboxtvuhd","last_commit":"4d47f91","last_updated":"2024-01-28T11:25:26Z","last_version":"v1.0.5","manifest_name":"Orange Livebox TV UHD","open_issues":11,"stargazers_count":26,"topics":["livebox"],"last_fetched":1710540749.412412},"291317330":{"manifest":{"country":["SK"],"name":"Electric Vehicle Charge Control"},"description":"Home Assistant custom component for Electric Vehicle Charge Control devices by Phoenix Contact ","domain":"phoenix_contact","etag_repository":"W/\"2afdd2c73bb291c3abe719d8bcfc2e89cdc30f3d5d6b8cdf6a98cf32787038b6\"","full_name":"mletenay/home-assistant-ev-charge-control","last_commit":"e7c6291","last_updated":"2023-01-25T21:40:24Z","manifest_name":"Electric Vehicle Charger","open_issues":1,"stargazers_count":1,"topics":["charging-stations","electric-vehicles","evse"],"last_fetched":1706977258.079935},"577981941":{"manifest":{"name":"Panasonic Eolia HA component"},"description":"Panasonic Eolia component for Home Assistant","domain":"panasonic_eolia","etag_repository":"W/\"538dfb8827c27db89370fee8d23dfc5b0b870ba1e62775fda5c0948b5aa2584f\"","full_name":"avolmensky/panasonic_eolia","last_commit":"df9d727","last_updated":"2024-03-11T08:34:10Z","manifest_name":"Panasonic Eolia AC","stargazers_count":2,"topics":["eolia","panasonic"],"last_fetched":1710152138.555253},"463624702":{"manifest":{"country":["US"],"name":"Hatch Rest Mini Sound Machine"},"description":"Home Assistant Integration for Hatch Rest Mini","domain":"ha_hatch","etag_releases":"W/\"14c6d2342819703a3fee668b36c422ff0843eea3dc84ba91cd06f8e484f86189\"","etag_repository":"W/\"636c385dd0bdf7a3a6be79ccd8f88e0133fecdd432e6929868435bddcb4cc438\"","full_name":"dahlb/ha_hatch","last_commit":"e5f1b7c","last_updated":"2024-04-01T10:46:54Z","last_version":"v1.17.1","manifest_name":"Hatch Rest Mini/Plus","open_issues":7,"stargazers_count":69,"topics":["hatch-baby-rest","python3"],"last_fetched":1711974366.281158},"375838748":{"manifest":{"name":"Selve NG"},"description":"Home Assistant Custom component to manage Selve devices","domain":"selve","etag_releases":"W/\"794959d38e4da474072588ccb2495edd6aa620a48a10f3edd3e6911d05f10955\"","etag_repository":"W/\"4bf33ab4eb37c504aeb973a8c760065a197ba5df1f74946582346a1c17213599\"","full_name":"Kannix2005/homeassistant-selve","last_commit":"f23f4ad","last_updated":"2023-08-09T08:57:42Z","last_version":"v3.0.6-1","manifest_name":"Selve NG","open_issues":3,"stargazers_count":11,"topics":["selve"],"last_fetched":1706307363.872763},"146379582":{"manifest":{"name":"Trakt"},"description":"\ud83d\udcfa Trakt Integration for Upcoming Media Card","domain":"trakt","etag_releases":"W/\"d97d1162c3de077710f7c622f9522eb8bebd7ebeeab85f7650337a1122097ed7\"","etag_repository":"W/\"dfa21e7d1f27b7f04a4bd69e6722fb3fef6e70893bf36a4f8f3bc176b9fa58ee\"","full_name":"custom-components/sensor.trakt","last_commit":"e6ce74f","last_updated":"2022-06-21T14:17:46Z","last_version":"2.0.4","manifest_name":"Trakt","open_issues":13,"stargazers_count":57,"last_fetched":1709928819.127874},"636324558":{"manifest":{"name":"Owlet"},"description":"Owlet HA integration","downloads":81,"domain":"owlet","etag_releases":"W/\"26b9567672c5ce4a31503f0dce15922062631e8ea0875fecc67848852451b96d\"","etag_repository":"W/\"da5515006e0255f1e8a4fae03a0df817bcbc244b0a8324b9a33c08f1c97720c6\"","full_name":"ryanbdclark/owlet","last_commit":"4b90ce0","last_updated":"2024-03-27T15:57:34Z","last_version":"2024.3.1","manifest_name":"Owlet Smart Sock","open_issues":1,"stargazers_count":16,"topics":["home-assistant-component","owlet"],"last_fetched":1711808281.074081},"484708274":{"manifest":{"name":"AsusRouter"},"description":"Monitor and control your AsusWRT-powered router from Home Assistant","domain":"asusrouter","etag_releases":"W/\"4b65255f2a113d728f624eb56539dc934c7c3103f4d39685daee0cecd56df77c\"","etag_repository":"W/\"bfdfcad2ee78023240ed3a0c1f1713cf22b24171df34323ae27f2e3914290ea3\"","full_name":"Vaskivskyi/ha-asusrouter","last_commit":"b643ef4","last_updated":"2024-03-20T22:35:58Z","last_version":"0.30.0","manifest_name":"AsusRouter","open_issues":40,"stargazers_count":156,"topics":["asus","asuswrt","asuswrt-merlin","router"],"last_fetched":1711880462.592172},"235659413":{"manifest":{"name":"Eloverblik"},"description":"Home Assistant Custom Component showing data from eloverblik.dk","domain":"eloverblik","etag_releases":"W/\"c4a6e88ed6890b2523a79f9995c8d73a1e1c837edbd0c268ba2a4e07a2bd2abc\"","etag_repository":"W/\"629101cf54da5e32270fd35f5c2023b8f6e594ee4b5ba4880c6dab7f85bccbd5\"","full_name":"JonasPed/homeassistant-eloverblik","last_commit":"63dc596","last_updated":"2024-03-29T22:15:21Z","last_version":"v0.5.2","manifest_name":"Eloverblik","open_issues":7,"stargazers_count":163,"last_fetched":1712038855.768129},"266779715":{"manifest":{"name":"Yahoo Finance"},"description":"Home Assistant component which allows you to get stock updates from Yahoo finance.","domain":"yahoofinance","etag_releases":"W/\"ce18303ce1321176b428427e1016dda77b15db2b030e274126d63add719d1e18\"","etag_repository":"W/\"fbf18dae93db411aa31aa64a5044b4ce3787f9c4c1d6d44c2426293e840f612b\"","full_name":"iprak/yahoofinance","last_commit":"93ad780","last_updated":"2024-03-21T01:01:50Z","last_version":"v1.2.6","manifest_name":"Yahoo Finance","open_issues":4,"stargazers_count":65,"topics":["stock-updates","yahoo-finance"],"last_fetched":1711933430.034609},"195883127":{"manifest":{},"description":"Garbage collection Nissewaard for Home Assistant","domain":"nissewaard","etag_repository":"W/\"10690be32c310e9e3befea41017777fad334e55669f3025dc5d070a387c42690\"","full_name":"Martinvdm/garbage-nissewaard-homeassistant","last_commit":"d15a028","last_updated":"2021-04-11T12:18:11Z","manifest_name":"Nissewaard garbage collection sensor","last_fetched":1681208401.627963},"366911690":{"manifest":{"name":"Dahua"},"description":"Dahua Camera and Doorbell Home Assistant Integration","domain":"dahua","etag_releases":"W/\"92b43f1bfc4abc0f1e48bf9765208ba96145a21c7740f2389f63bd669f2fa6ea\"","etag_repository":"W/\"c54b4bcdca9b6673f8e57a9a3c364c2b8c17a82ef4a7f6dfbe244010a6678f3c\"","full_name":"rroller/dahua","last_commit":"6b70043","last_updated":"2024-03-29T16:26:15Z","last_version":"0.9.51","manifest_name":"Dahua","open_issues":159,"stargazers_count":343,"topics":["amcrest","camera","dahua","doorbell","ipcam","lorex"],"last_fetched":1712118182.30324},"309018094":{"manifest":{"name":"fordpass"},"description":"Fordpass integration for Home Assistant","domain":"fordpass","etag_releases":"W/\"4ea0c36590759476dff97254611cf857426fe975ec120e793aa2482c587f8390\"","etag_repository":"W/\"d606519301b8460bc07e4c78f8ee50ff1e7bf0bc639d6e06e8e325a1ae5483fe\"","full_name":"itchannel/fordpass-ha","last_commit":"e957011","last_updated":"2024-02-09T04:21:59Z","last_version":"1.66-Release","manifest_name":"FordPass","open_issues":57,"stargazers_count":238,"topics":["assistant","car","fordpass","home"],"last_fetched":1711520395.682789},"620107388":{"manifest":{"country":["NZ"],"name":"em6 Energy Price"},"description":"New Zealand wholesale grid price sourced from EM6 for Home Assistant","domain":"em6","etag_releases":"W/\"198bd7bf320d1f6a0338686cc5c2ea8dad17ea249290a4f48f387f96880eee18\"","etag_repository":"W/\"ce7673cb2e189cf2fa110e6040fb576b5b1538e8d7aeec4c65b986f763b731c5\"","full_name":"codyc1515/ha-em6","last_commit":"a2cf9bc","last_updated":"2024-02-27T03:02:41Z","last_version":"v1.0.0","manifest_name":"em6 Energy Price","open_issues":2,"stargazers_count":2,"topics":["em6"],"last_fetched":1709115324.912075},"586066332":{"manifest":{"name":"Tuiss Smartview Blinds (Blinds2go)"},"description":"Integrates Blinds2go smart blinds powered by the Tuiss Smartview platform with Home Assistant using ble. ","domain":"tuiss2ha","etag_releases":"W/\"3e2e8c352ca736c750d4b6d4c0f9906834e6b33a2ef9adb1cf561e87b79c91c1\"","etag_repository":"W/\"bdaad7f3aa9a9e6879aa57368406814af25143b682bf961f4f9ad2ad27f623b8\"","full_name":"pink88/Tuiss2HA","last_commit":"51594d9","last_updated":"2024-02-29T19:01:25Z","last_version":"1.3.1","manifest_name":"Tuiss Smartview","open_issues":1,"stargazers_count":26,"topics":["blinds","covers","smart-blinds"],"last_fetched":1711822958.95618},"316396217":{"manifest":{"name":"Mjpeg Timelapse"},"description":"Mjpeg Timelapse integration for Home Assistant","domain":"mjpeg_timelapse","etag_repository":"W/\"bf2057554ccb248fcca557dd65674848b97b26bf20ebbfc1b7e0bbd2fa6a8e74\"","full_name":"evilmarty/mjpeg-timelapse","last_commit":"9d7a6e6","last_updated":"2023-05-20T10:05:33Z","manifest_name":"Mjpeg Timelapse","open_issues":6,"stargazers_count":24,"topics":["camera"],"last_fetched":1710108917.602931},"347143701":{"manifest":{"name":"Channels DVR Recently Recorded"},"description":"\u25b6\ufe0f Channels DVR component to feed Upcoming Media Card.","domain":"channels_dvr_recently_recorded","etag_releases":"W/\"13a37de915a1f5354f0e7518ef577a044f6da0b6b356f259e575dca721d95850\"","etag_repository":"W/\"40d14625795ebc10fbdfcb2511cb38077a00cd484fb03a36960237c3174e86bf\"","full_name":"rccoleman/channels_dvr_recently_recorded","last_commit":"071ace1","last_updated":"2023-09-02T17:10:23Z","last_version":"v0.1.0","manifest_name":"Channels DVR Recently Recorded","open_issues":5,"stargazers_count":12,"topics":["channels-dvr","homeassista"],"last_fetched":1712111220.568432},"330645002":{"manifest":{"name":"Danfoss Ally"},"description":"Danfoss Ally integration for Home Assistant","downloads":5,"domain":"danfoss_ally","etag_releases":"W/\"b5a783b69fabbdcb986704aadf338fc58f001677edd8539ecbd4643bab9b37d5\"","etag_repository":"W/\"96833047fa2dd85e206cb7d26c30dc24c64c94922a27c4c178f1d66b40e49f85\"","full_name":"MTrab/danfoss_ally","last_commit":"180b6a8","last_updated":"2024-03-29T12:11:47Z","last_version":"v1.3.3","manifest_name":"Danfoss Ally","open_issues":1,"stargazers_count":36,"topics":["climate","homeassistant-custom-component","thermostat"],"last_fetched":1711721814.281341},"620909192":{"manifest":{"name":"Cryptoinfo Advanced"},"description":"Provides Home Assistant sensors for all cryptocurrencies supported by CoinGecko","domain":"cryptoinfo_advanced","etag_releases":"W/\"feee525efb8475b98e2179010f3c56cd69b9446d3757079fe78f08a9eeeb211e\"","etag_repository":"W/\"3f0435a0d2f57dd22f299bd021263994b718e444715ba2363a85430d0c340f8d\"","full_name":"TheHolyRoger/hass-cryptoinfo","last_commit":"036257e","last_updated":"2024-01-19T10:58:12Z","last_version":"v0.3.6","manifest_name":"Cryptoinfo Advanced","open_issues":1,"stargazers_count":7,"topics":["bitcoin","cryptocurrency"],"last_fetched":1711880461.332562},"193588612":{"manifest":{"country":["PL"],"name":"iMPK sensor"},"description":"This sensor uses unofficial API retrieved by decompilation of iMPK application to provide a list of MPK Wroc\u0142aw news available in original app.","downloads":116,"domain":"impk","etag_releases":"W/\"32d404c27e54de9312a8e438df426452b6093c9e360dca81d0096fbe0e0bddce\"","etag_repository":"W/\"46316939724cbe06a8e5476f39419e23b2e4ee2440520514594c2fc67e4b7e57\"","full_name":"PiotrMachowski/Home-Assistant-custom-components-iMPK","last_commit":"92de5c0","last_updated":"2023-07-07T02:53:39Z","last_version":"v1.1.5","manifest_name":"iMPK","open_issues":2,"stargazers_count":15,"topics":["public-transport","wroclaw"],"last_fetched":1711578009.331212},"255258767":{"manifest":{"country":["FR"],"name":"GCE IPX800 V4"},"description":"IPX800 V4 integration for Home-Assistant","domain":"ipx800v4","etag_releases":"W/\"e8dd76e6ad4128a5c208365e4d3781bdbb05d5dc648c3d42a462937f18116a00\"","etag_repository":"W/\"d68836e4bf1fdceb7ed79d076ed051212de8c0229d7f099ec154c387bad49808\"","full_name":"Aohzan/ipx800","last_commit":"fe465d0","last_updated":"2024-02-17T17:22:45Z","last_version":"3.8.1","manifest_name":"GCE IPX800 V4","open_issues":2,"stargazers_count":19,"topics":["domotique","gce-electronics","ipx800"],"last_fetched":1708604507.919069},"668215386":{"manifest":{"name":"Mastodon Profile Stats"},"description":"A Home Assistant integration to provide stats of Mastodon user profiles","downloads":96,"domain":"mastodon_profile_stats","etag_releases":"W/\"4a9141f8dd7b43365fe457b434f95974a7e96c1e7edf4c5e98d7bc55404efea3\"","etag_repository":"W/\"ee0a339aefc8188caac49c4643dcf350f6865561202103a6fa434663824443d5\"","full_name":"andrew-codechimp/HA-Mastodon-Profile-Stats","last_commit":"e1990d5","last_updated":"2024-04-02T06:25:21Z","last_version":"1.0.11","manifest_name":"Mastodon Profile Stats","stargazers_count":6,"topics":["mastodon"],"last_fetched":1712045784.90418},"272140589":{"manifest":{"name":"Monitor Docker"},"description":"Monitor Docker containers from Home Assistant","domain":"monitor_docker","etag_releases":"W/\"038d462533c301e04b47f47ab2c47d8fe70816c56d33417121272a245178db7c\"","etag_repository":"W/\"566da45da0d33028c2f6f0f736ed184981f01f97268fa6d991638ce9c51cc148\"","full_name":"ualex73/monitor_docker","last_commit":"5ca0d13","last_updated":"2023-12-27T17:36:40Z","last_version":"1.14","manifest_name":"Monitor Docker","open_issues":55,"stargazers_count":251,"topics":["docker"],"last_fetched":1712211851.862283},"282688934":{"manifest":{"name":"EVA II PRO WiFi Midea Inventor Dehumidifier custom integration"},"description":"Home Assistant Custom Integration for EVA II PRO WiFi Smart Dehumidifier appliance by Midea/Inventor.","domain":"midea_dehumidifier","etag_releases":"W/\"83cf39d53b21ec7834ff37aac9e764d2b6b8c0ab479fb899fab635016264c7a7\"","etag_repository":"W/\"47cf9af6c19d00c63ca1fc6cc56732d908c3c2b1afedccfdb9713df72ccdc871\"","full_name":"barban-dev/homeassistant-midea-dehumidifier","last_commit":"eabbdec","last_updated":"2024-01-06T22:27:28Z","last_version":"v1.04","manifest_name":"EVA II PRO WiFi Midea Inventor Dehumidifier custom integration","open_issues":25,"stargazers_count":67,"topics":["dehumidifier","eva-ii-pro-wifi","internet-of-things","inventor","iot","midea"],"last_fetched":1710792851.090221},"276915021":{"manifest":{"name":"Easee EV Charger"},"description":"Custom component for Easee EV charger integration with Home Assistant","downloads":2928,"domain":"easee","etag_releases":"W/\"a959c2338ba0b850e3a8de2a702ca1e062ffb21da0114bebdc8d5028b6f8d1d2\"","etag_repository":"W/\"209a0690369bf9c0585cd9bc0eed2540300252d5efb504a2bde3eb6db4db7b64\"","full_name":"nordicopen/easee_hass","last_commit":"5608be4","last_updated":"2024-04-01T15:36:12Z","last_version":"v0.9.58","manifest_name":"Easee EV charger","open_issues":43,"stargazers_count":188,"topics":["easee","ev-charging"],"last_fetched":1712082115.194372},"702067512":{"manifest":{"name":"Webasto Connect (ThermoConnect)"},"description":"Integration for Webasto ThermoConnect devices","downloads":135,"domain":"webastoconnect","etag_releases":"W/\"1579c71207f91772863dd91c46c1fa2051570f72971b347d13369c6794f343f3\"","etag_repository":"W/\"8fc7255e03256102fb0d80a37c48c1b9841927c81b5e4fa89980f99a531a8289\"","full_name":"MTrab/webastoconnect","last_commit":"df99bd3","last_updated":"2024-04-03T07:31:35Z","last_version":"v0.2.0","manifest_name":"Webasto Connect (ThermoConnect)","open_issues":1,"stargazers_count":5,"topics":["homeassistant-custom-component"],"last_fetched":1712132522.271388},"250022973":{"manifest":{"name":"SmartThinQ LGE Sensors"},"description":"HomeAssistant custom integration for SmartThinQ LG devices configurable with Lovelace User Interface.","domain":"smartthinq_sensors","etag_releases":"W/\"9f4d996a7b5dcfed50228e4f3bfb07553f0d4a9bc321f75aaa2605e6f51349fc\"","etag_repository":"W/\"7d899f63464e57230a796eb6d79f7daeeb2c5368cd872354496ee3127f7d726b\"","full_name":"ollo69/ha-smartthinq-sensors","last_commit":"a022531","last_updated":"2024-03-31T23:39:20Z","last_version":"v0.39.0","manifest_name":"SmartThinQ LGE Sensors","open_issues":71,"stargazers_count":948,"topics":["ac","air-purifier","climate","dehumidifier","dishwasher","dryer","fan","lg","lge","microwave","oven","range","refrigerator","sensors","smartthinq","thinq","washer"],"last_fetched":1712218971.695934},"441028036":{"manifest":{"country":["CA"],"name":"Hilo"},"description":"Home Assistant Hilo Integration via HACS","downloads":7,"domain":"hilo","etag_releases":"W/\"12e1169a2b6901257605b9fe670a93dbe2cf42aa7a8964d14fa234ba3cafa83c\"","etag_repository":"W/\"5c62b1ef4c213df279a1f62023e80daf517361c7210d5cc1b1906552d2a9220e\"","full_name":"dvd-dev/hilo","last_commit":"8c66ce1","last_updated":"2024-04-04T00:50:33Z","last_version":"v2024.3.3","manifest_name":"Hilo","open_issues":5,"stargazers_count":114,"topics":["hilo","home-automation-system","hydro-quebec","signalr-client"],"last_fetched":1712197482.830337},"186347733":{"manifest":{"name":"Audi connect"},"description":"Adds an audi connect integration to home assistant","domain":"audiconnect","etag_repository":"W/\"82d43cd01e258db152b788630012d178f1decd37cb03c2a74fe70a782eccd527\"","full_name":"audiconnect/audi_connect_ha","last_commit":"82f9d37","last_updated":"2024-03-08T18:00:15Z","manifest_name":"Audi Connect","open_issues":76,"stargazers_count":183,"topics":["audi","audi-connect","sensors"],"last_fetched":1709928745.755874},"256899380":{"manifest":{"name":"Project Three Zero (7-11 Fuel Lock Monitor)"},"description":"Project Three Zero Home Assistant Integration","domain":"project_zero_three","etag_repository":"W/\"174fbfa767030aa430073834312ce5d2fb3051bd4e9b27472aeaa58294fc5ecb\"","full_name":"atymic/project_three_zero_ha","last_commit":"d9a86f7","last_updated":"2023-10-15T22:27:07Z","manifest_name":"7-11 Fuel Price Tacker","open_issues":1,"stargazers_count":4,"topics":["fuel"],"last_fetched":1710407471.771373},"519811207":{"manifest":{"country":["VN"],"name":"EVN Data Fetcher"},"description":"A simple yet efficient custom component to fetch data from EVN Vietnam for Home Assistant","domain":"nestup_evn","etag_releases":"W/\"ae97a70d586d49f139cbf5514350efce28a508d102098fadf1d268652dea747e\"","etag_repository":"W/\"c46feb871cece635df0d3196d1b4b98f3f9c0f2fe9617c287ac722f48ff547f3\"","full_name":"trvqhuy/nestup_evn","last_commit":"848bb7e","last_updated":"2024-03-20T00:51:02Z","last_version":"v2.2.0","manifest_name":"EVN Data Fetcher","open_issues":4,"stargazers_count":46,"topics":["electricity-meter","homeassistant-custom-component","polling-service"],"last_fetched":1712053382.195148},"242335771":{"manifest":{"country":["SE"],"name":"SVT Play"},"description":"Play SVT Play videos and channels via home assistant","domain":"svt_play","etag_releases":"W/\"c3d522072123fa046e5d39af654d24e22eacb26a3d0b47667b838217b80c19a3\"","etag_repository":"W/\"8b098065af065610a681e265d7ee1f2e57753e6f0fe0c97fde9571b9d1308ae4\"","full_name":"lindell/home-assistant-svt-play","last_commit":"e390b71","last_updated":"2024-04-04T05:12:28Z","last_version":"1.2.0","manifest_name":"SVT Play","open_issues":1,"stargazers_count":20,"topics":["svt","svtplay","sweden","tv","video"],"last_fetched":1712211666.75207},"338782385":{"manifest":{"country":["CH"],"name":"Compal WiFi"},"description":"Home Assistant component to switch WiFi on/off for Compal CH7465LG modem.","downloads":2,"domain":"compal_wifi","etag_releases":"W/\"384e4a3fc3537aed24d6fa8c4c29d78ee56c8e3dbee31df65c2e0598b7934e92\"","etag_repository":"W/\"67d4f052ae7a20ef4744939d981cbfbe3f7ebd04ed9ad757030da799a9424abe\"","full_name":"frimtec/hass-compal-wifi","last_commit":"79d412b","last_updated":"2024-03-29T09:18:41Z","last_version":"1.3.5","manifest_name":"Compal WiFi","stargazers_count":4,"topics":["ch7465lg","compal","compal-wifi-switch","switch","wifi","wlan"],"last_fetched":1711707402.878382},"199306511":{"manifest":{"name":"Kostal Piko"},"description":"A custom component to get the readings of a Kostal Piko inverter","domain":"kostal","etag_releases":"W/\"b2a0cc9d3f419beb43a9bde5fb4db41b07e6fa21834bb51f616b18b42cf31572\"","etag_repository":"W/\"07a8f7758d89c29b27fda034e0db9f44d08f9fa67ff6ca0888dbaf22ca8533ed\"","full_name":"gieljnssns/kostalpiko-sensor-homeassistant","last_commit":"93657fa","last_updated":"2021-06-16T14:25:39Z","last_version":"v2.7","manifest_name":"Kostal","open_issues":6,"stargazers_count":12,"last_fetched":1702211095.090025},"178101579":{"manifest":{},"description":"hassio support for Airthings Wave BLE environmental radon sensor.","domain":"airthings_wave","etag_releases":"W/\"92f89cca3e4dcfb5059e7338537278cae116663e68ba3c27f96d31c8db9ffcb3\"","etag_repository":"W/\"ab68011a7af41c360a04e2bf53c2e0bd29b2885853b5c2fc2e08014a34db65e2\"","full_name":"custom-components/sensor.airthings_wave","last_commit":"cfa407d","last_updated":"2023-07-14T22:00:07Z","last_version":"v5.0.0","manifest_name":"Airthings Wave","open_issues":7,"stargazers_count":100,"topics":["airthings-wave","bluetooth-low-energy","btle","environmental","radon"],"last_fetched":1712096167.337896},"520791578":{"manifest":{"name":"SolarEdge Optimizers Data"},"description":"Intergration to get optimizers information from the SolarEdge portal","domain":"solaredgeoptimizers","etag_releases":"W/\"8ad6123418f9b27a3c8e7ba97ae668686cfb483d6af345aa10e3dfa57e6a5f5e\"","etag_repository":"W/\"f8947895e647fbbc320e56242b411e3b589f25908cc5ffacadb7d5acd15b266d\"","full_name":"ProudElm/solaredgeoptimizers","last_commit":"365539f","last_updated":"2024-03-27T00:44:06Z","last_version":"v1.2.3","manifest_name":"SolarEdge Optimizers Data","open_issues":17,"stargazers_count":39,"topics":["optimizers","solaredge-api"],"last_fetched":1711642925.882688},"594751789":{"manifest":{"country":["CN"],"name":"Vaillant Plus"},"description":"Home Assistant custom component for controlling vSmart in Vaillant+ cn app.","domain":"vaillant_plus","etag_releases":"W/\"7a96bcc94f7851fc07e3cb88a46a6812fa80853f2d03c779b8fbcfae1551278c\"","etag_repository":"W/\"bff0e560725a72eaa56c82b434d068f4d172d0e0af84bd543ebf439e9f9fa13a\"","full_name":"daxingplay/home-assistant-vaillant-plus","last_commit":"a596aca","last_updated":"2024-04-04T09:46:22Z","last_version":"v1.2.3","manifest_name":"Vaillant Plus","open_issues":5,"stargazers_count":2,"topics":["vaillant","vsmart"],"last_fetched":1712225709.231039},"443529332":{"manifest":{"name":"Bobcat Miner 300"},"description":"Home Assistant integration for the Bobcat Helium Miner","domain":"bobcatminer","etag_releases":"W/\"b252a9ab27b2bc67a9241877f7ab3b2633dec70504cd60ef77bbfe7ddfc41cb2\"","etag_repository":"W/\"d7486f4f955e8a4ae7a986d4df7f7c4a715ee251591d5e16b19541b528147eca\"","full_name":"ardevd/ha-bobcatminer","last_commit":"4abd77d","last_updated":"2024-02-24T11:15:25Z","last_version":"v0.8.3","manifest_name":"Bobcat Miner","open_issues":2,"stargazers_count":11,"topics":["bobcatminer","cryptocurrency","helium","mining"],"last_fetched":1708971346.929573},"239366330":{"manifest":{"name":"SenseME"},"description":"Haiku with SenseME fan integration for Home Assistant","domain":"senseme","etag_releases":"W/\"9d0889e191568179ffb525972ef67b1d913ea6767a9186223eb39f5c459186e3\"","etag_repository":"W/\"f2c48831c7aa05f21f4386feaef2ec859f17c4fb0a1b4836aa9eb4108fb08c84\"","full_name":"mikelawrence/senseme-hacs","last_commit":"de4cf04","last_updated":"2021-12-28T02:15:41Z","last_version":"v2.2.5","manifest_name":"SenseME","open_issues":9,"stargazers_count":21,"topics":["bigassfans","fan","haiku","senseme"],"last_fetched":1704954177.01235},"481763130":{"manifest":{"name":"Generic Water Heater"},"description":"Home Assistant Custom Component - Generic Water Heater","domain":"generic_water_heater","etag_releases":"W/\"8fa4706565b850a043e1c4d7e560f40429799a7c5f93a9e392fb4ec776087374\"","etag_repository":"W/\"ccccebb553719835c1d6d239e2b405b56a29a883c174c0f9affc0eb0e86e88d2\"","full_name":"dgomes/ha_generic_water_heater","last_commit":"17689ac","last_updated":"2022-12-02T16:25:58Z","last_version":"0.0.3","manifest_name":"Generic Water Heater","open_issues":6,"stargazers_count":10,"topics":["home-assistant-integration"],"last_fetched":1706278432.704956},"229014136":{"manifest":{"name":"MyJDownloader"},"description":"myjdownloader integration for home assistant","domain":"myjdownloader","etag_releases":"W/\"8bc3469895720073d9b75538264f1a8b8e0f77958a4eef9cf49ffcdbc5a5092c\"","etag_repository":"W/\"e2755d4a1554680b2f695a38ed7ce44b64fbf7b0254a7455d57927f9c847145b\"","full_name":"doudz/homeassistant-myjdownloader","last_commit":"7602ca8","last_updated":"2023-04-20T05:00:59Z","last_version":"2.3.4","manifest_name":"MyJDownloader","open_issues":8,"stargazers_count":31,"last_fetched":1711628766.340434},"687451320":{"manifest":{"name":"Nintendo Switch Parental Controls"},"description":"Home Assistant integration for Nintendo Switch Parental Controls","downloads":216,"domain":"nintendo_parental","etag_releases":"W/\"f9de78c5759e3a19e962c9ee1262f88fd0e582312b2553700f1ea9161d9d1cb9\"","etag_repository":"W/\"7b3700203a3ef2e8da67070f549216b78f40d4446560f85d01eac50248ace8cb\"","full_name":"pantherale0/ha-nintendoparentalcontrols","last_commit":"8aace8c","last_updated":"2024-04-01T18:49:06Z","last_version":"2024.3.2","manifest_name":"Nintendo Switch Parental Controls","open_issues":3,"stargazers_count":57,"topics":["api","nintendo-switch","parental-control","parental-control-tool"],"last_fetched":1712002820.565136},"553010184":{"manifest":{"name":"Span Panel"},"description":"SPAN Integration for HomeAssistant/HACS","domain":"span_panel","etag_releases":"W/\"a2815306c574627b704f18549e1a121eb626615f8500c524d330e87834c15d9d\"","etag_repository":"W/\"ad5880e979686cf599e01b0b553c6fe2dd4d46f6f3f3a4acc584a400d2c14e6b\"","full_name":"gdgib/span","last_commit":"833a2ff","last_updated":"2024-04-04T02:59:41Z","last_version":"v0.0.8","manifest_name":"Span Panel","open_issues":11,"stargazers_count":14,"topics":["span"],"last_fetched":1712204410.197398},"255139072":{"manifest":{"country":["PT"],"name":"Entidade Reguladora dos Servi\u00e7os Energ\u00e9ticos"},"description":"Home Assistant Custom Component for ERSE","domain":"erse","etag_releases":"W/\"476a75480225194d410bef9ad0327598b8cfd81bfbd2edbc89d3d996bb7c6a11\"","etag_repository":"W/\"23a98181e8999771038242d933cf8e3e9ef41e8cee363dd8d5723158257750c3\"","full_name":"dgomes/ha_erse","last_commit":"e2c7cd4","last_updated":"2024-03-15T22:48:06Z","last_version":"2.2.2","manifest_name":"Entidade Reguladora dos Servi\u00e7os Energ\u00e9ticos","open_issues":5,"stargazers_count":41,"topics":["home-assistant-component","utility-meters"],"last_fetched":1712024684.224604},"279184610":{"manifest":{"country":["AU"],"name":"Amber Electric"},"description":"Home Assistant Component to pull the latest energy prices from Amber Electric","domain":"amberelectric","etag_repository":"W/\"ca7a896bddd6f4b3ae9559a548716ca1afedb7ae5d7ff7ccd67edaff0b4a1687\"","full_name":"madpilot/hass-amber-electric","last_commit":"b900ed8","last_updated":"2021-10-07T09:01:00Z","manifest_name":"Amber Electric","open_issues":4,"stargazers_count":24,"topics":["amber-electric","electricity-market","electricity-prices"],"last_fetched":1710469471.842115},"164841067":{"manifest":{},"description":"A custom component for Home Assistant to get messages from krisinformation.se","domain":"krisinformation","etag_releases":"W/\"1b6b3a0bc955bac6cdfeba903cff1bc04cb465ca53e39b5127b0fee9401342f4\"","etag_repository":"W/\"653d35f85f8fd6dfb6931ff37800fbb797929b86dd7b08d87a82b6e95b4e6f57\"","full_name":"isabellaalstrom/sensor.krisinformation","last_commit":"e70f74a","last_updated":"2021-06-29T18:03:29Z","last_version":"v1.0.3","manifest_name":"Krisinformation","open_issues":7,"stargazers_count":29,"last_fetched":1703089113.827037},"273333188":{"manifest":{"name":"Daily Sensor"},"description":"Sensor for Home Assistant that gets reset at midnight","domain":"daily","etag_releases":"W/\"3fb08ac939557696c8251e481ad277678377c2d165dbad6b62f93a4d4e4ee623\"","etag_repository":"W/\"0d7e187de88b626c071f89c3271318eda9a9bfd251a48923f4afa44a098a48d5\"","full_name":"jeroenterheerdt/HADailySensor","last_commit":"36b301b","last_updated":"2024-04-03T06:35:48Z","last_version":"v2024.4.1","manifest_name":"Daily Sensor","open_issues":2,"stargazers_count":60,"topics":["aggregation","average","max","maximum","mean","median","min","minimum","standard-deviation","statistics","stdev","sum","var","variance"],"last_fetched":1712211608.816555},"336054515":{"manifest":{"name":"Open Charge Point Protocol (OCPP)"},"description":"Home Assistant integration for electric vehicle chargers that support the Open Charge Point Protocol (OCPP).","downloads":1432,"domain":"ocpp","etag_releases":"W/\"6b53eeab6f3fbc5b1ae4ebe4c14c827601d963086d9d7493b110ce48ca767c67\"","etag_repository":"W/\"b3c2aa7870fcc22d1897b9ec9a2f79ed447f4b4943d1f769acc736b573b84be3\"","full_name":"lbbrhzn/ocpp","last_commit":"47fa4b7","last_updated":"2024-04-02T15:35:23Z","last_version":"v0.5.2","manifest_name":"Open Charge Point Protocol (OCPP)","open_issues":21,"stargazers_count":184,"topics":["ocpp"],"last_fetched":1712082036.560273},"584257648":{"manifest":{"name":"TCL TV Remote"},"description":"This custom component will give you two new services for controlling TCL Smart TVs (Non android version). Tested on my S69 series TV. I have seen some reports about it working on other brands as well, mainly Thomson","downloads":1700,"domain":"tcl_tv_remote","etag_releases":"W/\"de77903aded24ef19a3e3e50c1ff0c2b59781fc0ebd3fbf4e219cc176954f326\"","etag_repository":"W/\"ea9d7d5ebe4f57cdc7d0e017a7fa8cf0915b571b5a2f2404612a8d6c83ba91b6\"","full_name":"popeen/Home-Assistant-Custom-Component-TCL-Remote","last_commit":"db8e01d","last_updated":"2023-09-23T10:39:23Z","last_version":"0.1.3","manifest_name":"TCL TV Remote","open_issues":1,"stargazers_count":10,"last_fetched":1711587687.518421},"224073673":{"manifest":{"name":"Calendarific"},"description":"Calendarific holiday sensor for Home Assistant ","downloads":1036,"domain":"calendarific","etag_releases":"W/\"3c2e9417151252174f350533b31f77f2b5bbc489ede5722e17b2cdfaea8f3c8a\"","etag_repository":"W/\"5053950f1ab422751e577a56524e877ee939532630e9e52f03794295f0bdde67\"","full_name":"pinkywafer/Calendarific","last_commit":"288f091","last_updated":"2024-04-03T02:00:30Z","last_version":"0.14.0","manifest_name":"Calendarific","open_issues":10,"stargazers_count":17,"topics":["api-client","calendarific","holidays"],"last_fetched":1712111204.315361},"219035415":{"manifest":{"country":["FR"],"name":"GeoRide integration"},"description":"GeoRide integration for Home Assistant","domain":"georide","etag_releases":"W/\"724ee55709a897b14de0503033d8848de3b9248279bfdf48f85a98137001d889\"","etag_repository":"W/\"6fff8cb524867e1a52a414df7a9e1bbac1db9a272becb14704aae418e6848ce2\"","full_name":"ptimatth/GeorideHA","last_commit":"6257b65","last_updated":"2023-10-29T12:26:04Z","last_version":"1.1.0","manifest_name":"GeoRide","open_issues":2,"stargazers_count":16,"last_fetched":1705011551.147871},"237880993":{"manifest":{"country":["CN"],"name":"Smartmi smart heater"},"description":"\u667a\u7c73\u667a\u80fd\u7535\u6696\u5668","domain":"miheater","etag_releases":"W/\"198130d0d58c2fc8132109bd82a5de333b10b685daf6e8de7d59b3d564c24249\"","etag_repository":"W/\"e25d36f4a874d74fccf55e1d20cb4ce7df204a230db5387a373281e38df786cf\"","full_name":"fineemb/Smartmi-smart-heater","last_commit":"e2f86fe","last_updated":"2022-12-20T03:16:37Z","last_version":"v1.24","manifest_name":"Smartmi Smart Heater","open_issues":6,"stargazers_count":18,"last_fetched":1708856076.34818},"319346850":{"manifest":{"name":"Snowtire Sensor"},"description":"Home Assistant sensor to predict if it's time to change car tires from summer to winter and vice versa.","downloads":430,"domain":"snowtire","etag_releases":"W/\"7d19d67b615d67151233f068696f9600bdbc9b2bca3df5abd2498bb10a411888\"","etag_repository":"W/\"0e99b885ba235a3165ce4a3a4c1b419d77f07752c1056298d087cc8a093613fe\"","full_name":"Limych/ha-snowtire","last_commit":"4093889","last_updated":"2024-03-20T21:28:37Z","last_version":"1.4.6","manifest_name":"Snowtire Sensor","open_issues":15,"stargazers_count":27,"topics":["car-winter-tires","home-assistant-component","tires"],"last_fetched":1711587583.221992},"258012818":{"manifest":{"name":"simpleicons"},"description":"Use Simple Icons in Home Assistant","downloads":8215,"domain":"simpleicons","etag_releases":"W/\"8b91cf6fb27fbd17d392768f162391c9e0cc9477152ba9f60118f50a68973120\"","etag_repository":"W/\"958f92f2d16b9da8ef77009cb5fe0e2c5246aa00959148d0b98b997e237f131f\"","full_name":"vigonotion/hass-simpleicons","last_commit":"47d2c0c","last_updated":"2023-10-16T18:57:39Z","last_version":"v2.2.0","manifest_name":"Simple Icons","open_issues":12,"stargazers_count":126,"topics":["simple-icons"],"last_fetched":1712061166.557268},"657410518":{"manifest":{"name":"Inverse"},"description":"Create an inverse switch from a Home Assistant switch entity using the UI","domain":"inverse","etag_releases":"W/\"7da93661631496244f9dcb9c9025d88eb1daa283119913091a244d3c730a595a\"","etag_repository":"W/\"5adcd8f024d2a388e6a8fe10c0679b72c81f2044a4cdcff530e0983eb7e60893\"","full_name":"disforw/inverse","last_commit":"96ef193","last_updated":"2023-12-10T20:11:35Z","last_version":"1.1","manifest_name":"Inverse Switch","open_issues":3,"stargazers_count":8,"topics":["switch"],"last_fetched":1710368045.989855},"356053801":{"manifest":{"name":"IMA Protect Alarm"},"description":"Home Assistant custom component for IMA Protect Alarm","domain":"imaprotect","etag_releases":"W/\"15ca1d51eda4f87075e69fd16030979c0fed0b4aa982b70dac90ba3b544b00b1\"","etag_repository":"W/\"f586e536006a712f5f99b95dba4f875e2f024424ae02690ceee1b0ef593e8cd0\"","full_name":"pcourbin/imaprotect","last_commit":"291e0a0","last_updated":"2024-04-04T05:03:55Z","last_version":"v1.0.5","manifest_name":"IMA Protect Alarm","open_issues":4,"stargazers_count":2,"topics":["alarm"],"last_fetched":1712211746.231954},"195594888":{"manifest":{"country":["CA"],"name":"Sinope GT125"},"description":"Sinope custom component for Home Assistant to manage Sinop\u00e9 devices directly via the GT125 gateway","domain":"sinope","etag_releases":"W/\"92967f2d117668271613f400ace67352a6c092f3435c4899b9bedadc15866508\"","etag_repository":"W/\"8923758640c8cd3fa343891bdc2867487d4c3a91fbe51e2863479a994c811b77\"","full_name":"claudegel/sinope-gt125","last_commit":"9492e65","last_updated":"2024-01-06T20:45:18Z","last_version":"v1.6.3","manifest_name":"Sinope GT125","open_issues":1,"stargazers_count":13,"topics":["sinope"],"last_fetched":1711231996.569536},"447307317":{"manifest":{"name":"Holidays"},"description":"\ud83d\udcc5 Custom Home Assistant integration for public holidays - also used for garbage_collection integration to automatically move scheduled events that fall on a public holiday (by an automation blueprint)","downloads":4686,"domain":"holidays","etag_releases":"W/\"83a94b20d92fb17b0c2d063137664dcfdb5b3fe0af78de7956907dc819b84118\"","etag_repository":"W/\"5d1e6b4cb1d464be8b72bf02323aa28af3363cdb2a64e951d5822caf78843d10\"","full_name":"bruxy70/Holidays","last_commit":"3211800","last_updated":"2023-12-28T13:12:10Z","last_version":"1.9.10","manifest_name":"Holidays","stargazers_count":42,"topics":["calendar","country-holidays","garbage-collection","holidays","public-holidays"],"last_fetched":1708280114.275993},"320324937":{"manifest":{"country":["FR"],"name":"Veolia"},"description":"Home Assistant custom component to retrieve information from Veolia ","domain":"veolia","etag_releases":"W/\"2cb177989fd635fb97c0998b2955e0bf4d18bbd88694f3fd99beb13cf4e57f45\"","etag_repository":"W/\"a341f45a0634410145741a85ea66c94cdf6d481180301c8c9ac2042d90abfd67\"","full_name":"tetienne/veolia-custom-component","last_commit":"636b104","last_updated":"2023-12-28T16:12:53Z","last_version":"v0.4.0","manifest_name":"Veolia","open_issues":4,"stargazers_count":6,"topics":["home-assistant-component","veolia"],"last_fetched":1711995823.112201},"450192057":{"manifest":{"country":["RU"],"name":"SkyKettle"},"description":"Redmond SkyKettle integration for Home Assistant","domain":"skykettle","etag_releases":"W/\"a35605db1a2e77de92e24638485af49ff05bc5c8d977b867d9b0dcca25c81011\"","etag_repository":"W/\"edbbe5cdbe49040d74b90ecd97a43c4880d07af7fb941df65ded0a88b655aca8\"","full_name":"ClusterM/skykettle-ha","last_commit":"5b2ac6e","last_updated":"2024-03-18T16:11:53Z","last_version":"v2.2","manifest_name":"SkyKettle","open_issues":23,"stargazers_count":80,"topics":["kettle","redmond","skykettle"],"last_fetched":1711858652.882269},"182915754":{"manifest":{"name":"Grocy custom component"},"description":"Custom Grocy integration for Home Assistant","downloads":4597,"domain":"grocy","etag_releases":"W/\"ea6e1fabf1f8691210d1b6af0e8b97f6bc7a421246caa2f593da802193e3df5d\"","etag_repository":"W/\"7120a30dd1ee37d4b232ba8e091fe54fafa5f114fe0a53bb353bf1108f9ecf40\"","full_name":"custom-components/grocy","last_commit":"de31430","last_updated":"2024-02-04T17:44:01Z","last_version":"v4.11.1","manifest_name":"Grocy","open_issues":38,"stargazers_count":140,"topics":["grocy"],"last_fetched":1712038697.467515},"568186049":{"manifest":{"country":["ES"],"name":"Aig\u00fces de Barcelona"},"description":"Custom component for Home Assistant to integrate data from Aigues de Barcelona","domain":"aigues_barcelona","etag_releases":"W/\"a75a3dc087e2676c368d78c427ab7fcbd5342f25292547aaced90baf6e14f8b9\"","etag_repository":"W/\"a28d22dc3faa9cfc84741b0542b1172e99c67a6c54f7cd6aaeb14ed83eec887c\"","full_name":"duhow/hass-aigues-barcelona","last_commit":"0105b22","last_updated":"2024-03-16T20:59:13Z","last_version":"0.4.1","manifest_name":"Aigues de Barcelona","open_issues":3,"stargazers_count":40,"topics":["barcelona","water-meter","water-monitoring"],"last_fetched":1710929725.96027},"462430932":{"manifest":{"country":["HU"],"name":"Fire Protection Hungary"},"description":"Fire protection integration for Home Assistant with data provided by N\u00c9BIH","domain":"fire_protection_hu","etag_releases":"W/\"acd447264b47e1cfe4b19d962bf9773cda6e74c17cc6cd5977176a76123970ce\"","etag_repository":"W/\"e7ad7d74dd5e111d8ce30fd2591f02a2b3875137dd4405335d4adad7fe002a19\"","full_name":"amaximus/fire_protection_hu","last_commit":"3d4ab61","last_updated":"2023-06-08T08:44:24Z","last_version":"0.2.0","manifest_name":"Fire Protection Hungary","open_issues":1,"stargazers_count":2,"topics":["homeassistant-custom-component","hungary"],"last_fetched":1691057595.601041},"597517839":{"manifest":{"country":["fr"],"name":"Orange \"Internet On the move\" Renault Home Assistant Integration"},"description":"Home Assistant integration for Orange Intenet on the move","domain":"orange_internet_on_the_move","etag_releases":"W/\"bc4ff7a2b57befa566f83022a15c5521a2f69a6b45081fa2577e0edc7780fb81\"","etag_repository":"W/\"927de98ae2e348abdcd5561707d08d9e4dfcd894f06180badf832056c5a67f0f\"","full_name":"rexave/hass-orange-internet-on-the-move","last_commit":"0f2e7d5","last_updated":"2023-05-06T16:49:32Z","last_version":"0.1.2","manifest_name":"Orange Internet on the move","open_issues":1,"last_fetched":1690143481.634725},"326352749":{"manifest":{"country":["US"],"name":"MasterLink Gateway"},"description":"This components integrates Bang & Olufsen Master Link Gateway and Beolink Gateway to Home Assistant, the open-source home automation platform.","domain":"mlgw","etag_releases":"W/\"fc6b1bc9d9bea0eccca0f4f59631a2148c9f963312da869beb649742690011b3\"","etag_repository":"W/\"0a0ee9bab08f7c8f7cbb5c007690d773c0102c7d210bb62f83c9798bbc1b9ea7\"","full_name":"giachello/mlgw","last_commit":"dd14850","last_updated":"2024-03-08T06:11:30Z","last_version":"v2023.2.3","manifest_name":"MasterLink Gateway","open_issues":5,"stargazers_count":24,"topics":["bang-olufsen","beolink-gateway","masterlink-gateway","mlgw-configuration"],"last_fetched":1710348375.801717},"612978245":{"manifest":{"name":"Dyson"},"description":"Home Assistant custom integration for Wi-Fi connected Dyson devices","domain":"dyson_local","etag_releases":"W/\"2e6d54d9329e740c20d6d687ddee4a14160727870b0c1f11dcd0bf675c761d11\"","etag_repository":"W/\"dfd7d6cb873463ddb1350f02f09a5a3ac3dacfb4fb8af8ca152ea7f81e374728\"","full_name":"libdyson-wg/ha-dyson","last_commit":"e61637f","last_updated":"2024-04-01T14:03:58Z","last_version":"v1.3.11","manifest_name":"Dyson","open_issues":23,"stargazers_count":179,"topics":["dyson","dyson-devices","dyson-fan","dyson-link","dysonlink"],"last_fetched":1712218897.685961},"190260955":{"manifest":{"country":["NL"],"name":"MIND Mobility"},"description":"Add support for Mind Mobility vehicles in Home Assistant","domain":"mind","etag_releases":"W/\"ec40b9e6fd0465daac456979701434035f74205050f8ee3f466b39b0f19855a1\"","etag_repository":"W/\"f45222a7632edbcfaa9eb11b53fdf883e69648193635ab153ec4e48171c83b05\"","full_name":"bramkragten/mind","last_commit":"2acbc8f","last_updated":"2021-05-07T13:37:44Z","last_version":"v1.2.1","manifest_name":"MIND Mobility","open_issues":3,"stargazers_count":9,"last_fetched":1697753530.07617},"539629703":{"manifest":{"country":["ES"],"name":"MeteoGalicia"},"description":"A Home Assistant integration that gives you weather info from MeteoGalicia, the meteorological agency for Galicia, Spain","downloads":3,"domain":"meteogalicia","etag_releases":"W/\"41afa07846b9f7e9aa4a27a9462442778d76599f0aa7b8142c3ac4a2c2bb978d\"","etag_repository":"W/\"cdbf5b43a90bf0918b9d5de8f0afbcf73a02f4536f37d8b20546d644807b40e2\"","full_name":"Danieldiazi/homeassistant-meteogalicia","last_commit":"3fc1a69","last_updated":"2024-02-27T17:40:04Z","last_version":"2024.2.1","manifest_name":"MeteoGalicia","stargazers_count":8,"topics":["meteogalicia","weather","weather-forecast","weather-station"],"last_fetched":1709713133.482635},"586474647":{"manifest":{"name":"Pixometer"},"description":"Home Assistant custom component HACS for Pixolus Pixometer app meter reading integration.","domain":"pixometer","etag_releases":"W/\"f3fc51ba0a8aca4a6f60deffb1703bad0ef14f893c6d3cf95dc910d63ddb53ea\"","etag_repository":"W/\"600b07d1a73c20a8f33c60bd10edf8237fcea95a224a2d38e301c9e0f379d871\"","full_name":"myTselection/pixometer","last_commit":"c46f546","last_updated":"2024-03-10T12:25:25Z","last_version":"2.1.2","manifest_name":"Pixometer","stargazers_count":3,"topics":["meterreading","pixometer"],"last_fetched":1710080249.106134},"574693804":{"manifest":{"country":["GB","AU"],"name":"Hypervolt Charger"},"description":"Home Assistant integration for Hypervolt EV charger","domain":"hypervolt_charger","etag_releases":"W/\"c740bff536192595d88b5f19a041ee55d378c4182431e3d4395913575d8d13a4\"","etag_repository":"W/\"c012a11176452584d7de31e342dc293b4dd8a64c205997e6d58fcec202366f9e\"","full_name":"gndean/home-assistant-hypervolt-charger","last_commit":"3fedec7","last_updated":"2024-04-01T21:36:42Z","last_version":"v1.3.1","manifest_name":"Hypervolt Charger","open_issues":12,"stargazers_count":40,"topics":["ev-charger","ev-charging","hypervolt"],"last_fetched":1712067301.536697},"455174197":{"manifest":{"name":"Watchman"},"description":"Home Assistant custom integration to keep track of missing entities and services in your config files","domain":"watchman","etag_releases":"W/\"6a77fa81b6c9d7f73462d47b052e91d9533fbced197d836722e2b4645240111e\"","etag_repository":"W/\"0d0393852317702d5b08335a51882b2900272d127e1fd0496f14d8b10d8dc64a\"","full_name":"dummylabs/thewatchman","last_commit":"23298fa","last_updated":"2024-02-09T14:51:19Z","last_version":"v0.6.1","manifest_name":"Watchman","open_issues":62,"stargazers_count":391,"topics":["automation"],"last_fetched":1712153677.966488},"471478227":{"manifest":{"name":"ChargePoint"},"description":"Home Assistant ChargePoint EV Charger Integration","domain":"chargepoint","etag_releases":"W/\"5ce8348af32d2fb58c71d0d351a0d0877097fb04ecd8fa82d5e3697e9645fef9\"","etag_repository":"W/\"7e4bf65391205b3235260a9665526e1a41f2a6a84cfe1d4cffdef11f30074117\"","full_name":"mbillow/ha-chargepoint","last_commit":"62407aa","last_updated":"2024-02-26T04:33:03Z","last_version":"v0.7.0","manifest_name":"ChargePoint","open_issues":11,"stargazers_count":42,"topics":["chargepoint","hassio-integration"],"last_fetched":1712060971.191727},"193371566":{"manifest":{"name":"Burze.dzis.net sensor"},"description":"This integration uses official API to get weather warnings for Poland and storm warnings for Europe from https://burze.dzis.net.","downloads":1248,"domain":"burze_dzis_net","etag_releases":"W/\"94deabaa22aa488ed37891836b2f000817d2cf4c6ea1bf9c89c622deea5a49a9\"","etag_repository":"W/\"5d5143252c9e951cc79ffc03d0fbdc2f1c12e9420e391956173a2fe89b90d488\"","full_name":"PiotrMachowski/Home-Assistant-custom-components-Burze.dzis.net","last_commit":"c9d9c21","last_updated":"2024-02-11T02:59:31Z","last_version":"v2.0.1","manifest_name":"Burze.dzis.net","open_issues":2,"stargazers_count":33,"topics":["hazard","lightning","radiation","storm","warnings","weather"],"last_fetched":1711304603.210687},"620855349":{"manifest":{"name":"Lightener"},"description":"Magically control the state and brightness of lights in Home Assistant.","downloads":1972,"domain":"lightener","etag_releases":"W/\"30f47a09ee69c94472f0baf5046cd9d6da8826d56b1e181d2c112581dd0ffe36\"","etag_repository":"W/\"2a39568c471e8611316a1ff2b4fdc33b3f8831dbef366cbc1449b5f2fa06ea5f\"","full_name":"fredck/lightener","last_commit":"fb1a760","last_updated":"2024-03-06T09:32:43Z","last_version":"v2.3.0","manifest_name":"Lightener","open_issues":4,"stargazers_count":84,"topics":["brightness","light"],"last_fetched":1711815521.965832},"307586942":{"manifest":{"name":"Bureau of Meteorology"},"description":"Custom component for retrieving weather information from the Bureau of Meteorology.","domain":"bureau_of_meteorology","etag_releases":"W/\"632646742ca9ab0e964937d9ae8b41242ed70dd336f7370f2ab11c0451e23523\"","etag_repository":"W/\"4c5d4be00023e16b6c7743224a9a54c1e3cd05a1a9136d1a46e73b19435f3887\"","full_name":"bremor/bureau_of_meteorology","last_commit":"ae0f69a","last_updated":"2024-03-24T06:09:36Z","last_version":"1.3.0","manifest_name":"Bureau of Meteorology","open_issues":9,"stargazers_count":158,"topics":["bom","bureau","forecast","meteorology","observations","weather","weather-information"],"last_fetched":1711851819.961879},"669130167":{"manifest":{"name":"Andrews & Arnold Quota"},"description":"A Home Assistant integration to retrieve quota details of an Andrews & Arnold Broadband account","downloads":22,"domain":"andrews_arnold_quota","etag_releases":"W/\"d490ba56e28638931d68c7a704723e606b15de29a7f24a11d5d730d5cb593006\"","etag_repository":"W/\"dbbc49fa8c226a2731cc8f8de2f08e560c2702319b852109358d4692094d6e24\"","full_name":"andrew-codechimp/HA-Andrews-Arnold-Quota","last_commit":"eb155d3","last_updated":"2024-04-02T06:28:22Z","last_version":"2.1.1","manifest_name":"Andrews & Arnold Quota","stargazers_count":5,"last_fetched":1712045784.672953},"656992550":{"manifest":{"name":"Dreo Smart Device Integration"},"description":"Dreo Smart Device Integration for Home Assistant","domain":"dreo","etag_releases":"W/\"f62a178161410589db5579fa9b60d1be7fb55d72bebe9442e174167f7dd66721\"","etag_repository":"W/\"5f4666abefceae6d8471460e7ee6c53466b8fdcaa4b2c7725dbf5d9c571c7fce\"","full_name":"JeffSteinbok/hass-dreo","last_commit":"c0bb56a","last_updated":"2024-03-18T03:43:52Z","last_version":"v0.6.2","manifest_name":"Dreo","open_issues":14,"stargazers_count":72,"topics":["dreo"],"last_fetched":1710809897.020201},"439467929":{"manifest":{"name":"Midea Air Appliances (LAN)"},"description":"This Home Assistant custom component adding support for controlling Midea air conditioners and dehumidifiers on local network. ","domain":"midea_dehumidifier_lan","etag_releases":"W/\"383eab320dda58e45952f31e06956cd47f77cb5067ad01de9c48558fdb92566a\"","etag_repository":"W/\"15c87b6339401b2a87746286ce35579f88519f544ff3173fbae6e80fe4c87675\"","full_name":"nbogojevic/homeassistant-midea-air-appliances-lan","last_commit":"7af69ed","last_updated":"2024-03-20T17:37:00Z","last_version":"v0.9.2","manifest_name":"Midea Air Appliances (LAN)","open_issues":8,"stargazers_count":226,"topics":["air-conditioner","airconditioning","dehumidifier","midea"],"last_fetched":1711822922.400248},"236358405":{"manifest":{"name":"Broadlink s2c and s1c sensors"},"description":"Broadlink s2c and Broadlink s1c sensors for Home Assistant","domain":"broadlink_s1c","etag_repository":"W/\"fdc62e9127249f062f8b2da11a4ca394e5af6074aca5fb274b6ad2ab82fc558e\"","full_name":"nick2525/broadlink_s1c_s2c","last_commit":"f8f2b1b","last_updated":"2023-06-09T13:38:22Z","manifest_name":"Broadlink s1c and s2c","open_issues":6,"stargazers_count":10,"topics":["broadlink","hacz","s1c","s2c"],"last_fetched":1710361121.246239},"441920613":{"manifest":{"name":"Thermia Heat Pump"},"description":"Thermia Heat Pump Integration for Home Assistant","domain":"thermia","etag_releases":"W/\"2a2c5fea22b3efe7214f947ce739767512f39f8b525fb0db1cf3a8fd3b6218c9\"","etag_repository":"W/\"70733b021e8224d9afa69c4d105b0695d3b46861d1aeb9ca023cfcf3050b54fb\"","full_name":"klejejs/ha-thermia-heat-pump-integration","last_commit":"b1f7e78","last_updated":"2024-01-08T16:50:03Z","last_version":"3.3.1","manifest_name":"Thermia Heat Pump","open_issues":9,"stargazers_count":28,"topics":["heat-pump","thermia"],"last_fetched":1711621068.996285},"314593331":{"manifest":{"country":["CA"],"name":"Satellite Tracker (N2YO)"},"description":"Using the N2YO API, this Home Assistant integration will provide visible satellite passes (general) and to add specific satellites for monitoring.","domain":"satellitetracker","etag_releases":"W/\"9e049701501b1d1ea917e38ad674a134ad62dffc056f10fa1819f7250099ad2a\"","etag_repository":"W/\"d219459bcab1eb461ac846eeba4d1ea283c6c5500d8451c0bbbbd3e61874aa1c\"","full_name":"djtimca/hasatellitetracker","last_commit":"fe293ea","last_updated":"2024-01-13T19:47:06Z","last_version":"0.0.9","manifest_name":"Satellite Tracker (N2YO)","stargazers_count":17,"topics":["international-space-station","iss","satellite","satellite-tracker","starlink","tracking-satellites","visible-passes"],"last_fetched":1711664064.348014},"192086849":{"manifest":{},"description":"GoodWe SEMS MQTT-componenent for Home Assistant","domain":"sems2mqtt","etag_releases":"W/\"da59f7d47b78af31771914fb8682084b3d067d86c28a69e49257d3672981ee30\"","etag_repository":"W/\"a11147d809ee68a63852de38a0a37e73c895eb2b8f6d86a1a4e3548b532123c5\"","full_name":"bouwew/sems2mqtt","last_commit":"8043eea","last_updated":"2023-03-31T18:23:01Z","last_version":"v0.4.9","manifest_name":"Goodwe SEMS API to MQTT sensor","open_issues":1,"stargazers_count":9,"last_fetched":1711484078.885135},"508800396":{"manifest":{"country":["PT"],"name":"Coverflex Card"},"description":"Coverflex - Custom Component for Home Assistant","domain":"coverflex","etag_releases":"W/\"ebed5d320109cb5c63af80e01204ff1e692e23f3d2807c2f1bec3a9acf4ba0a7\"","etag_repository":"W/\"9daa7b63a05412fa837d13ff284111b91749e8c2db000b6daec5f89a15295676\"","full_name":"netsoft-ruidias/ha-custom-component-coverflex","last_commit":"3bfe9b8","last_updated":"2022-11-10T14:45:17Z","last_version":"v1.1.1","manifest_name":"Coverflex Benefits Integration","stargazers_count":3,"topics":["coverflex","meal-card"],"last_fetched":1689070824.810206},"603834302":{"manifest":{"name":"ldata"},"description":"Home Assistant Integration for Levition LDATA","domain":"ldata","etag_releases":"W/\"d349a36d53b8f4ed85124c095f52b22ac84b19d7dfe03ac43d8fcf876c05e32e\"","etag_repository":"W/\"3b8846d2333116f9dc1ad36da83f910aad6aaeb5dd17b8dfcffbf3dd97c64d57\"","full_name":"rwoldberg/ldata-ha","last_commit":"3f75597","last_updated":"2024-02-22T01:28:47Z","last_version":"v1.1.2","manifest_name":"Leviton LDATA","open_issues":1,"stargazers_count":23,"topics":["ldata","leviton"],"last_fetched":1710649320.132946},"606471314":{"manifest":{"country":["ALL"],"name":"SENEC.Home V2.x/V3/V4 Systems"},"description":"SENEC.Home V2.x/V3/V4 Integration for Home Assistant that will work with the recent changes introduced by SENEC (supporting https) - successfully tested with latest MCU Version: 0827 (Feb 2024).","domain":"senec","etag_releases":"W/\"c75c2618edd0846d6c97740947cde71fd16dc53c8a6ce325adc07585caeafa8d\"","etag_repository":"W/\"e633896d68f1761bd577bc50c81fbc2dee2c3dc841452a3198b7d211f1159f3a\"","full_name":"marq24/ha-senec-v3","last_commit":"8fa92bf","last_updated":"2024-03-28T06:58:48Z","last_version":"2024.3.0","manifest_name":"SENEC.Home","open_issues":2,"stargazers_count":44,"topics":["home-assistant-integration","senec"],"last_fetched":1711614055.041917},"204700563":{"manifest":{"name":"Momentary Switch Component"},"description":"Momentary Switch Component for Home Assistant","domain":"momentary","etag_releases":"W/\"7bc55ace159eabeed69362b01c9ea9ae64d811e052e79505a8f1366aa853918f\"","etag_repository":"W/\"e4018c5feb49e96c39c381a76931ce4a42f096b5686fb2b0b33a2beccccf78e6\"","full_name":"twrecked/hass-momentary","last_commit":"d278468","last_updated":"2024-02-04T14:25:26Z","last_version":"v0.6.3","manifest_name":"Momentary Switch Component","open_issues":8,"stargazers_count":41,"last_fetched":1710930059.160019},"307503425":{"manifest":{"country":["IT"],"name":"INGV Earthquakes"},"description":"INGV - National Institute of Geophysics and Volcanology [Istituto Nazionale di Geofisica e Vulcanologia] Terremoti Italia.","downloads":3,"domain":"ingv_centro_nazionale_terremoti","etag_releases":"W/\"5e03db2d2d0c0ae1cbe52d88148dc69f619be97007ae8bdc7ca2748f080de6bf\"","etag_repository":"W/\"0782b6a7244b90d45660b550272e380aebd2c42d764d99439be069dca9d721c9\"","full_name":"caiosweet/Home-Assistant-custom-components-INGV","last_commit":"a1edf2c","last_updated":"2024-02-18T17:24:06Z","last_version":"2024.02.0","manifest_name":"INGV Earthquakes","open_issues":1,"stargazers_count":19,"topics":["assistant","geofisica","home","ingv","terremoti","vulcanologia"],"last_fetched":1708280119.429392},"516625225":{"manifest":{"name":"Sutro"},"description":"This component integrates Home Assistant with Sutro (https://mysutro.com/), a device that enables automated remote monitoring of the temperature as well as the chlorine/bromine, pH, and alkalinity levels.","domain":"sutro","etag_releases":"W/\"b3ab69c1b6ca9d375e1c30b9144f5eda2b9d9600f38c35ebe5f8b6f49724b98e\"","etag_repository":"W/\"7640485bd2e3f67c25572bbc9cbe62b9aeb78eec9fd5a919012d22a5627a7827\"","full_name":"ydogandjiev/hass-sutro","last_commit":"888432f","last_updated":"2024-01-20T01:01:12Z","last_version":"v0.0.7","manifest_name":"Sutro","open_issues":11,"stargazers_count":9,"topics":["sutro"],"last_fetched":1705724667.658819},"269588712":{"manifest":{"name":"Philips Hue Play HDMI Sync Box"},"description":"Custom integration for Home Assistant to control the Philips Hue Play HDMI Sync Box","downloads":28,"domain":"huesyncbox","etag_releases":"W/\"9a29cfa3a7325d7e6522caa7cabada42c471a68a9314b36b9fc93510b965dfbb\"","etag_repository":"W/\"3ea5bbcb7573602d6e96187e5f89087f66c7d5a77847b74f3e67ff2a98f1fe0f\"","full_name":"mvdwetering/huesyncbox","last_commit":"59dfb4a","last_updated":"2024-02-02T19:43:19Z","last_version":"v2.0.1","manifest_name":"Philips Hue Play HDMI Sync Box","open_issues":6,"stargazers_count":95,"topics":["hue-entertainment","huesync","philips-hue"],"last_fetched":1712175631.91998},"480281490":{"manifest":{"name":"Lektrico Charging Station"},"description":"Manage your Lektrico EV Charger","domain":"lektrico_custom","etag_releases":"W/\"94ef847423e738ac683ae0cd32989f58153c5646cbaa47c100c56e50eabdc07f\"","etag_repository":"W/\"78daff2721874a235bc3258a08fe14cc96f9f945a44731126c91d66434da3931\"","full_name":"Lektrico/ha_lektrico","last_commit":"70aea33","last_updated":"2023-07-10T15:11:58Z","last_version":"v1.2","manifest_name":"Lektrico Charging Station","open_issues":3,"stargazers_count":12,"topics":["lektrico"],"last_fetched":1710757145.574124},"413798425":{"manifest":{"name":"UI Lovelace Minimalist"},"description":"UI-Lovelace-Minimalist is a \"theme\" for HomeAssistant","downloads":46689,"domain":"ui_lovelace_minimalist","etag_releases":"W/\"cacb42c51e0ba6a391e7b1c65a988821e22ae5a83ce0fd6ef70cc09f26d159c4\"","etag_repository":"W/\"5a8c3d9e9125542f4c54ea40a0d537fd19d172db0bfe183042d74e0ae1ebabaa\"","full_name":"UI-Lovelace-Minimalist/UI","last_commit":"77424a7","last_updated":"2024-04-01T14:01:24Z","last_version":"v1.3.9","manifest_name":"UI Lovelace Minimalist","open_issues":213,"stargazers_count":1497,"last_fetched":1712168646.266936},"146510412":{"manifest":{"name":"ICY E-thermostaat"},"description":"E-Thermostaat (ICY) component for Home Assistant","downloads":68,"domain":"e_thermostaat","etag_releases":"W/\"90855a27c84e8aaa69531544eef121db534c0f636ebaea1b54891d84dcec3a33\"","etag_repository":"W/\"8fa13cd17d58b227a5cf0a62c9203a3b362b8b7132c8b9972991c12c6f4c3894\"","full_name":"custom-components/climate.e_thermostaat","last_commit":"4820bee","last_updated":"2023-02-06T21:02:40Z","last_version":"0.4.3","manifest_name":"ICY E-thermostaat","stargazers_count":3,"topics":["e-thermostaat","icy"],"last_fetched":1704903525.008593},"290436986":{"manifest":{"country":["CN"],"name":"\u5f69\u4e91\u5929\u6c14"},"description":"\u7528\u4e8eHASS\u7684\u5f69\u4e91\u5929\u6c14\u7ec4\u4ef6","domain":"colorfulclouds","etag_releases":"W/\"a122d6cfe2a7d093a4ea7191fe7ad3e34cdea5a1c0c7e44ca68467b872d5daf7\"","etag_repository":"W/\"f4f475c3c094ee7ba3d4f067feb3f300f3557342aa8ead12b3823ea2e7359f9f\"","full_name":"fineemb/Colorfulclouds-weather","last_commit":"95430f1","last_updated":"2023-05-19T01:22:07Z","last_version":"v1.2.8","manifest_name":"colorfulclouds","open_issues":16,"stargazers_count":114,"topics":["weather"],"last_fetched":1711224950.440873},"497322735":{"manifest":{"name":"Plex recently added sensor"},"description":"\u25b6\ufe0f Plex component to feed Upcoming Media Card.","domain":"plex_recently_added","etag_releases":"W/\"8b7294d99851b83bc49668a22f8dd0294d6ebf68ce0d85d96c2eb093fbdc2bc0\"","etag_repository":"W/\"609a805f0c676eae72e689372995a8506e777f701b5e06c0d018a8befd701ec3\"","full_name":"NemesisRE/sensor.plex_recently_added","last_commit":"9c0e616","last_updated":"2023-03-14T10:16:26Z","last_version":"0.3.9","manifest_name":"Plex Recently Added","open_issues":7,"stargazers_count":13,"last_fetched":1712111172.790003},"612717689":{"manifest":{"name":"Retry"},"description":"Home Assistant Integration with Retry Service","downloads":1218,"domain":"retry","etag_releases":"W/\"8ee31d5da4018aa2ad42909b4c91a9828323451a1c2ca3c2379f69b63076faa4\"","etag_repository":"W/\"f58994921b01d4ec694bd71e717451748066b61c3382f72dcb62ef7e5a028ecf\"","full_name":"amitfin/retry","last_commit":"ad116ed","last_updated":"2024-04-01T06:03:35Z","last_version":"v2.7.0","manifest_name":"Retry","stargazers_count":73,"topics":["homeassistant-custom-component"],"last_fetched":1711959485.179548},"468666097":{"manifest":{"name":"Stromer E-Bike"},"description":"Stromer custom_component for Home Assistant","domain":"stromer","etag_releases":"W/\"acf9795573de4ea0695acc965047afac8a92a4d5197b6163510094508dd37200\"","etag_repository":"W/\"550eb556e596f6a0ce212a5b10bf68e111aaef9f1b363853285828907911198d\"","full_name":"CoMPaTech/stromer","last_commit":"6789893","last_updated":"2024-04-03T19:14:29Z","last_version":"v0.3.1","manifest_name":"Stromer e-bike","open_issues":6,"stargazers_count":10,"topics":["e-bike","ebike","pedelec","stromer"],"last_fetched":1712175368.30216},"642225418":{"manifest":{"country":["RU","BY"],"name":"Turkov Ventilation Systems"},"description":"Turkov integration for Home Assistant","downloads":1,"domain":"turkov","etag_releases":"W/\"64d5e953560b6c62f0d7cf2607bdf5dd8ce401892eaa325afcccca869f57138f\"","etag_repository":"W/\"79e384f7159589731553efb0d9263ef1a94208579787c4d593172999a786d2b6\"","full_name":"alryaz/hass-turkov","last_commit":"61a30ab","last_updated":"2023-11-09T13:42:08Z","last_version":"v2023.9.0","manifest_name":"Turkov","open_issues":1,"stargazers_count":5,"topics":["hvac-control","turkov","ventilation"],"last_fetched":1707958479.444163},"135166048":{"manifest":{},"description":"Home-Assistant image classification using Machinebox.io","domain":"classificationbox","etag_releases":"W/\"ff1ab12c20e3dc69dba166729fd5aafe28036e389317f44ec155fc5baf970ed1\"","etag_repository":"W/\"430bb7822ef8bc3c2a9c3bb0dec6b22070ae72d855f772527db1af7b776e2287\"","full_name":"robmarkcole/HASS-Machinebox-Classificationbox","last_commit":"4ea59ac","last_updated":"2022-07-05T04:19:34Z","last_version":"v0.7","manifest_name":"classificationbox custom component","open_issues":3,"stargazers_count":20,"topics":["computer-vision","deep-neural-networks","machinebox"],"last_fetched":1707726204.212209},"144888844":{"manifest":{},"description":null,"domain":"ovapi","etag_releases":"W/\"125a17fc3759c1873c0733d786141d7553ef05dc72e0d3d3f1b389167df1a6d6\"","etag_repository":"W/\"c0e60317a231b604aa38778845726a549ec7ee9c814f168b25011647cdad26bb\"","full_name":"Paul-dH/Home-Assisant-Sensor-OvApi","last_commit":"bf72014","last_updated":"2023-06-05T21:33:45Z","last_version":"v1.4.3","manifest_name":"Sensor OvApi","open_issues":7,"stargazers_count":17,"last_fetched":1707646747.722801},"167885769":{"manifest":{"name":"Arlo Camera Support"},"description":"Asynchronous Arlo Component for Home Assistant","domain":"aarlo","etag_releases":"W/\"cf608ddcd0676595bb6c41e8a5c0ece2f2049166fcbc260a583792076bbb486f\"","etag_repository":"W/\"82c0d0d320e079a6a0289ca1026ce60f8c9f37cb902ebdde7031bc58fa53992e\"","full_name":"twrecked/hass-aarlo","last_commit":"c562303","last_updated":"2024-03-17T14:59:56Z","last_version":"v0.7.4.2","manifest_name":"Arlo Camera Support","open_issues":293,"stargazers_count":360,"topics":["arlo","netgear"],"last_fetched":1712082231.951172},"525954717":{"manifest":{"name":"HomeWhiz"},"description":"Home Assistant custom component for devices that can connect to HomeWhiz mobile app (Beko, Grundig, Arcelik)","domain":"homewhiz","etag_releases":"W/\"231004e798818bd0b193c15a7ff7be0f462f6ce90587d9e3e9dda048b3a6f21a\"","etag_repository":"W/\"da916063dba646168240fc622123d8267c20b90c50459dfa43c7943e1e2e05be\"","full_name":"home-assistant-HomeWhiz/home-assistant-HomeWhiz","last_commit":"8a072a6","last_updated":"2024-02-28T20:00:07Z","last_version":"v0.5.2","manifest_name":"HomeWhiz","open_issues":36,"stargazers_count":76,"topics":["homewhiz"],"last_fetched":1711894443.858157},"309195773":{"manifest":{"name":"vapix"},"description":"home-assistant service for control the vapix \ud83d\udeaa\ud83d\udd11","domain":"vapix","etag_releases":"W/\"e0e793f0aa611c3c258a62c9564fe001ddd7440438076b33708ea6e55946ca99\"","etag_repository":"W/\"609bb2e349d8c2a3baecbe95a3a333a52b607d7bb75c5531f9ccee65e2c186ee\"","full_name":"gtjadsonsantos/vapix","last_commit":"152bd7d","last_updated":"2021-06-22T11:49:49Z","last_version":"v2021.2.0","manifest_name":"vapix","stargazers_count":2,"topics":["axis","services"],"last_fetched":1706336242.261923},"228649088":{"manifest":{"country":["NL"],"name":"P2000 Sensor"},"description":":fire_engine: This component tracks P2000 emergency events in The Netherlands.","domain":"p2000","etag_releases":"W/\"9466cfa909b80e300ed1deb29fe540d0f70b5eaad9bce9e95a749beb82e5fa6c\"","etag_repository":"W/\"a9d16af3a390324e93868085b7e57701ce842d91ebe1130ae442cc340d753c5b\"","full_name":"cyberjunky/home-assistant-p2000","last_commit":"0eddf7b","last_updated":"2022-12-31T13:58:27Z","last_version":"1.0.23","manifest_name":"P2000 Sensor","open_issues":17,"stargazers_count":52,"topics":["emergency","p2000"],"last_fetched":1711815451.574798},"346474804":{"manifest":{"name":"Toyota Connected Services Europe"},"description":"Toyota Connected Services integration for Home Assistant.","downloads":1647,"domain":"toyota","etag_releases":"W/\"62eccba296af333276e38daecdb603a3cd42aa8be3c430649a32aba9d2205393\"","etag_repository":"W/\"0038b03d3b64fddf887df5ec98b06e388ca803a7e95ca9a5a89a855760a8a563\"","full_name":"DurgNomis-drol/ha_toyota","last_commit":"84c7f69","last_updated":"2024-04-04T07:04:33Z","last_version":"v2.0.2","manifest_name":"Toyota Connected Services","open_issues":12,"stargazers_count":122,"topics":["car","toyota","vehicle"],"last_fetched":1712218750.616704},"254253124":{"manifest":{"country":["US"],"name":"Noonlight - Alarm Monitoring"},"description":"HomeAssistant integration for Noonlight","domain":"noonlight","etag_releases":"W/\"93e44f2738725e7bfdd6ba0daec7b256ac3ef72ca67336e69935da8c3a06f820\"","etag_repository":"W/\"ad81010ce3ba91b1c0b2db86534affdb9ce03b8aaf1aef8ae57338ae997004cc\"","full_name":"konnected-io/noonlight-hass","last_commit":"df714c5","last_updated":"2022-10-16T17:36:02Z","last_version":"v1.1.0","manifest_name":"Noonlight","open_issues":12,"stargazers_count":37,"topics":["alarm","monitoring","noonlight","security"],"last_fetched":1711587567.264501},"494545750":{"manifest":{"name":"Peaqhvac"},"description":"Home Assistant custom component to help hvac-systems stay below peak hourly energy levels and prioritize cheap hours to heat your home.","downloads":7,"domain":"peaqhvac","etag_releases":"W/\"1a32fed8adc52393af3bce1dc2e29d1abd9c2404024367ccbba76d9e61fa4aff\"","etag_repository":"W/\"96f33b28e7f23488c67752be51c483ff549292bbf3058de7c97f1980c784e538\"","full_name":"elden1337/hass-peaqhvac","last_commit":"fc3aba5","last_updated":"2024-03-28T20:53:40Z","last_version":"2.4.5","manifest_name":"peaqhvac","open_issues":16,"stargazers_count":7,"topics":["nibe","peak-shaving","smart-pricing"],"last_fetched":1711901789.791542},"612652228":{"manifest":{"name":"IMPC Energy"},"description":"\u901a\u8fc7\u5185\u8499\u53e4\u7535\u529b\u516c\u4f17\u53f7\u67e5\u8be2\u7535\u91cf\u7535\u8d39\u7684Home Assistant\u63d2\u4ef6","domain":"impc_energy","etag_releases":"W/\"86e9cdd47fc8cab9a0faab617bb4e203e3e0bcd5231db77faf2385ea3e1a3c5b\"","etag_repository":"W/\"024d8878c0c3b3cb5918ba961ac9c535e84f8d1614216957d23c8f8a9c65fd78\"","full_name":"NiaoBlush/impc_energy","last_commit":"aeecf8c","last_updated":"2023-04-27T09:26:46Z","last_version":"0.1.0","manifest_name":"IMPC Energy","stargazers_count":2,"topics":["electricity-consumption"],"last_fetched":1709605426.98411},"695521993":{"manifest":{"country":["BE"],"name":"MyEnergy"},"description":"Home Assistant custom component HACS integration to Belgium MijnEnergie.be (MonEnergie.be) sites to compare and save on your electricity and gas prices in Belgium,","domain":"myenergy","etag_releases":"W/\"35d76ad2d86855cd56b695f112ccebadac4a081ff01fb32fe32cc6a31cfa97cd\"","etag_repository":"W/\"4fd0e1355642aeadc57ddd953181c52fd864ae6a84599ce51f79bf2caf7c3677\"","full_name":"myTselection/MyEnergy","last_commit":"63ced04","last_updated":"2024-03-10T12:25:34Z","last_version":"2.4.1","manifest_name":"MyEnergy","open_issues":4,"stargazers_count":7,"last_fetched":1712061002.269409},"261277563":{"manifest":{"name":"Open Source Routing Machine"},"description":"OSRM travel time sensor for Home Assistant","domain":"osrm_travel_time","etag_releases":"W/\"930f03202f1f036ab93eb954e2a9fe1a45306a5bd5517f0f87ba6b99b06f1081\"","etag_repository":"W/\"5354f147f96f8f6d5aa79727b8e481a891a7db635dac2ab31d9f0f7a089c28af\"","full_name":"edekeijzer/osrm_travel_time","last_commit":"175d626","last_updated":"2022-03-11T11:58:30Z","last_version":"v0.3","manifest_name":"Open Source Routing Machine travel time","open_issues":2,"stargazers_count":8,"topics":["osrm","python3","self-hosted"],"last_fetched":1703465999.945674},"642982371":{"manifest":{"country":["BR"],"name":"Epic Games"},"description":"A custom component for home assistant","domain":"epic_games","etag_releases":"W/\"f032e26fac9e46cacb2ad808713f5000f1a2ac8ff503c730747c3cef2ed9bdb6\"","etag_repository":"W/\"538c9e4b9f84e057ae4afa3bab50d98952b4a1a95ac258ed4ecbe697e825b40e\"","full_name":"hudsonbrendon/ha_epic_games","last_commit":"c8eee6e","last_updated":"2024-02-09T02:35:18Z","last_version":"v0.1.6","manifest_name":"Epic Games","open_issues":1,"stargazers_count":7,"topics":["epic-games","free","games","store"],"last_fetched":1710291623.584359},"299556199":{"manifest":{"name":"Mercedes Me API"},"description":"Script to use Mercedes Me APIs.","domain":"mercedesmeapi","etag_releases":"W/\"c097c4112d71caa75c15be2ea9f0a42437abf42aa0ba2dfbe9c81ffe2612db98\"","etag_repository":"W/\"8cbae90ce0ed73bab83213bb4ddffafcf7dc517b66e0a6c6754358dcf7f318a6\"","full_name":"xraver/mercedes_me_api","last_commit":"a2339ef","last_updated":"2023-02-26T13:39:29Z","last_version":"v0.13","manifest_name":"Mercedes Me API","open_issues":14,"stargazers_count":53,"topics":["mercedes","mercedes-benz-car"],"last_fetched":1710951883.063547},"356385629":{"manifest":{"name":"Kia Uvo / Hyundai Bluelink"},"description":"A Home Assistant HACS integration that supports Kia Connect(Uvo) and Hyundai Bluelink. The integration supports the EU, Canada and the USA.","domain":"kia_uvo","etag_releases":"W/\"e1a614f7bcdd1ee9b2f1c5574309232da86ce2f3fc30a8380ecf1a8c654fce57\"","etag_repository":"W/\"4495f7850721d0126772367c8755ddf33e9d9418ee66356137eabd49b0747bf9\"","full_name":"Hyundai-Kia-Connect/kia_uvo","last_commit":"5e85f7b","last_updated":"2024-04-02T22:13:53Z","last_version":"v2.24.2","manifest_name":"Kia Uvo / Hyundai Bluelink","open_issues":72,"stargazers_count":348,"topics":["bluelink","car","hyundai","kia","uvo"],"last_fetched":1712211592.817668},"504664392":{"manifest":{"name":"PowUnity BikeTrax"},"description":"Custom component for the PowUnity BikeTrax integration for Home Assistant.","domain":"biketrax","etag_releases":"W/\"f0766871985bf1db897a44aad09c1b56625671f79a563d4bec8fe1b60875f425\"","etag_repository":"W/\"21158a2d5219c01350e01114182b1700dad91a37d93228ad7032b782cab79345\"","full_name":"basilfx/homeassistant-biketrax","last_commit":"e2a8e80","last_updated":"2024-03-06T12:34:53Z","last_version":"v1.1.2","manifest_name":"PowUnity BikeTrax","open_issues":5,"stargazers_count":5,"topics":["biketrax","powunity"],"last_fetched":1710505335.277254},"307678069":{"manifest":{"name":"Variables+History"},"description":"Home Assistant variables component","domain":"variable","etag_releases":"W/\"71563031c66fe0a80a2aa6fd2420a2ad1d4364435451520d09a58b038fd07830\"","etag_repository":"W/\"fcbd513f86502e9a6088e5c6c6592241f46a2d7a4865ad0f8a7062e34687c7a4\"","full_name":"enkama/hass-variables","last_commit":"372110f","last_updated":"2024-03-23T22:02:54Z","last_version":"3.4.3","manifest_name":"Variables+History","open_issues":1,"stargazers_count":79,"topics":["counter","keypad","last-motion","timer","variables"],"last_fetched":1712088936.562218},"572282256":{"manifest":{"name":"Govee LAN Control"},"description":"Control Govee lights via the LAN API from Home Assistant","domain":"govee_lan","etag_repository":"W/\"9aaf84e7639f6956e288e840ca6dd55276049d8a5674ef9ea9fe875e50ae2cd2\"","full_name":"wez/govee-lan-hass","last_commit":"59d4ef1","last_updated":"2024-01-21T04:14:36Z","manifest_name":"Govee LAN Control","open_issues":6,"stargazers_count":190,"topics":["govee","light"],"last_fetched":1710649375.032897},"268722568":{"manifest":{"name":"Media player template"},"description":"Template media_player for Home Assistant","domain":"media_player_template","etag_releases":"W/\"018e82178f213a4e9e2d0ca1bb26a8d0f536999a9fa73255f6f1b3a274d7de66\"","etag_repository":"W/\"7b26f48bd8747d71194f35ee3a7a63edeac45c4bc0bef16fbbb690afca9079f3\"","full_name":"Sennevds/media_player.template","last_commit":"9b80808","last_updated":"2024-01-06T20:14:30Z","last_version":"1.0.1","manifest_name":"Media player template","open_issues":11,"stargazers_count":107,"last_fetched":1710354151.497452},"312896602":{"manifest":{"name":"Skoda Connect"},"description":"Skoda Connect - A home assistant plugin to add integration with your car","domain":"skodaconnect","etag_releases":"W/\"0e5d44c47c66976286ae246d1f3b1a7cd40bd26ad5d6136beb8cbfe6c193b95e\"","etag_repository":"W/\"01b260275e17c147b9acd95b2942e991b6fd4f2b167df8bab21b63840bf28ac4\"","full_name":"skodaconnect/homeassistant-skodaconnect","last_commit":"323116a","last_updated":"2024-02-06T15:13:44Z","last_version":"1.2.9","manifest_name":"Skoda Connect","open_issues":11,"stargazers_count":201,"topics":["skoda-connect"],"last_fetched":1711570876.696801},"307098646":{"manifest":{"name":"Alarmo"},"description":"Easy to use alarm system integration for Home Assistant","downloads":24375,"domain":"alarmo","etag_releases":"W/\"43297ec0adaa53cc774fd10772b77c754034f26f9eee8175023fce8486d78dbe\"","etag_repository":"W/\"713ca224b578ab6ff5c64713b2b1726ee441dbc35c430cfff9cb1cf62f4ba38d\"","full_name":"nielsfaber/alarmo","last_commit":"42f49c8","last_updated":"2024-03-31T18:43:06Z","last_version":"v1.9.15","manifest_name":"Alarmo","open_issues":24,"stargazers_count":1140,"topics":["alarm","assistant","home","security"],"last_fetched":1712192538.689775},"318182014":{"manifest":{"name":"Xiaomi Miot Auto"},"description":"Automatic integrate all Xiaomi devices to HomeAssistant via miot-spec, support Wi-Fi, BLE, ZigBee devices. \u5c0f\u7c73\u7c73\u5bb6\u667a\u80fd\u5bb6\u5c45\u8bbe\u5907\u63a5\u5165Hass\u96c6\u6210","downloads":30282,"domain":"xiaomi_miot","etag_releases":"W/\"0c2865ecf3f5d7ea5dbb7ab2cfbf7da90b69cae7278262676ae65dd73d5da1ac\"","etag_repository":"W/\"658dd987b47531fe8d61b10980f4f3dbd4214c49e30d69dc0a3ce1a6fd27c40d\"","full_name":"al-one/hass-xiaomi-miot","last_commit":"0981e50","last_updated":"2024-04-02T15:16:11Z","last_version":"v0.7.17","manifest_name":"Xiaomi Miot Auto","open_issues":464,"stargazers_count":3761,"topics":["iot","miio","miot","miot-spec","xiaoai","xiaomi","xiaomi-miot"],"last_fetched":1712225587.908928},"265716369":{"manifest":{"name":"Minerstat"},"description":"Minerstat mining hashrate.","domain":"hacs-minerstat","etag_releases":"W/\"462ed32b0ebe15e46923750d66c4757a601294d901f1055a2690abeba7c23acd\"","etag_repository":"W/\"69d866ec5ebe8f19483c6fb137ceb618dd03cd5eff4a5094f20144e868e497f6\"","full_name":"gilsonmandalogo/hacs-minerstat","last_commit":"a06b028","last_updated":"2022-01-11T22:19:20Z","last_version":"1.1.1","manifest_name":"Minerstat","stargazers_count":4,"topics":["minerstat","mining"],"last_fetched":1687155599.35211},"272432260":{"manifest":{"name":"Floureon Thermostat"},"description":"Floureon (Broadlink based) thermostat integration for Home Assistant","domain":"floureon","etag_repository":"W/\"69d8d6ea5919ff9005c5e443208704141725479428d2fa656970f2f588e53380\"","full_name":"algirdasc/hass-floureon","last_commit":"1659c0f","last_updated":"2024-03-31T07:16:15Z","manifest_name":"Floureon Thermostat","open_issues":6,"stargazers_count":30,"topics":["broadlink","floureon","thermostat"],"last_fetched":1711879987.918022},"605635573":{"manifest":{"name":"Spook \ud83d\udc7b Not your homie"},"description":"Spook \ud83d\udc7b Your homie","downloads":7165,"domain":"spook","etag_releases":"W/\"ed5554b9eb83acc5846989159a6db52db7a457e579e8e5e9289de65b32b63c80\"","etag_repository":"W/\"3f7547c7c495cf27783341d7d631499630fd8cce6e482a48f63e540beea38140\"","full_name":"frenck/spook","last_commit":"bc0394c","last_updated":"2024-04-04T07:45:29Z","last_version":"v2.2.4","manifest_name":"Spook","open_issues":12,"stargazers_count":352,"topics":["home-assistant-component","home-assistant-config","home-assistant-configuration","home-assistant-integration","home-destruction","homeassistant-homie","homey","homie","powerful","powertools","random","spooky","toolbox"],"last_fetched":1712225761.830466},"191831638":{"manifest":{"name":"Meross Integration"},"description":"Custom component that leverages the Meross IoT library to integrate with Homeassistant","domain":"meross_cloud","etag_releases":"W/\"883b3a08085b0fb08c2f8a1a1f8ab10cba1c6f59ca70d43b2f56007f6093a70e\"","etag_repository":"W/\"08a1af69c1ad0e8e9a8ad427373e0437c9b1889267c40cbe0c93ea1b1b704703\"","full_name":"albertogeniola/meross-homeassistant","last_commit":"e88dfc0","last_updated":"2024-03-29T21:59:24Z","last_version":"v1.2.13","manifest_name":"Meross Cloud IoT","open_issues":35,"stargazers_count":662,"topics":["meross","meross-homeassistant"],"last_fetched":1712124954.258867},"701827966":{"manifest":{"name":"Cloudflare Tunnel Monitor"},"description":"Integration (custom_component) for Home Assistant that monitors the status of your Cloudflare tunnels.","domain":"cloudflare_tunnel_monitor","etag_releases":"W/\"5e5256b2e1f576c4f1a740115dde21217055e734d79ccc9e3698c06d85e106b8\"","etag_repository":"W/\"f3e02cad0a461371455f1b827bbccb179ef272b4fa55619794f278b3879da504\"","full_name":"deadbeef3137/ha-cloudflare-tunnel-monitor","last_commit":"0df0e1a","last_updated":"2024-02-17T13:39:02Z","last_version":"v2.1.6","manifest_name":"Cloudflare Tunnel Monitor","open_issues":1,"stargazers_count":8,"topics":["cloudflare","cloudflare-tunnel","homeassistant-custom-component"],"last_fetched":1712132299.521956},"373864423":{"manifest":{"name":"Lennox S30,E30,M30"},"description":"Home Assistant Lennox S40 / S30 / E30 / M30 integration","domain":"lennoxs30","etag_releases":"W/\"c56243ea102e4e2925cf15d894baf3c40e41fa27c8df6750fa2b6e6b9f2c14f3\"","etag_repository":"W/\"6c98906412284fa0e7258376deb2f7671291143075680f6993414a43da469335\"","full_name":"PeteRager/lennoxs30","last_commit":"b09035d","last_updated":"2024-03-07T01:20:00Z","last_version":"2024.3.0","manifest_name":"Lennox S30/E30","open_issues":3,"stargazers_count":73,"topics":["e30","lennox","m30","s30","s40"],"last_fetched":1712211750.583706},"170309600":{"manifest":{"name":"Atrea"},"description":"Custom component allowing control of Atrea ventilation units","domain":"atrea","etag_releases":"W/\"e13926678fb58ef4c365e80acaa2d65d6b40948ca334a81dbf77c459b5bb2a7d\"","etag_repository":"W/\"5ea09b2be87c0cb7452db8fd9fdd63d924a7016a0a8536db02768e3ceb38baf9\"","full_name":"JurajNyiri/HomeAssistant-Atrea","last_commit":"50c79e0","last_updated":"2024-01-13T06:37:18Z","last_version":"6.1.5","manifest_name":"Atrea","open_issues":3,"stargazers_count":22,"last_fetched":1707077788.471173},"381052530":{"manifest":{"country":["CN"],"name":"FordPass China"},"description":"\u798f\u7279\u6d3e\u7684Home Assistant\u96c6\u6210\u7ec4\u4ef6\uff0c\u901a\u8fc7Home Assistant\u8fdc\u7a0b\u76d1\u63a7\u6216\u8005\u63a7\u5236\u4f60\u7684\u798f\u7279/\u6797\u80af\u6c7d\u8f66","domain":"fordpass_china","etag_releases":"W/\"5e95d0375beec509d3d9a48e072f184f2599279ee40ed08248c7ae9d657b17dc\"","etag_repository":"W/\"fe4a1fb77c03b9282ef632bc8f3f590d876c83e6c605ae6b0857a246090e3f42\"","full_name":"georgezhao2010/fordpass_china","last_commit":"44261c8","last_updated":"2022-11-10T11:48:30Z","last_version":"v0.3.5","manifest_name":"FordPass China","open_issues":6,"stargazers_count":25,"topics":["china","ford","fordpass","lincoln","lincoln-way"],"last_fetched":1708028059.230594},"496755553":{"manifest":{"name":"Raspberry Pi 1-Wire via sysbus"},"description":"Home Assistant 1-Wire via sysbus","domain":"onewire_sysbus","etag_releases":"W/\"6956ccd859e49666982141b5213bf7ede8e510440993f1c11e8b048ecabdbce1\"","etag_repository":"W/\"d67ff4f20bb51eeccd4258d6e7980e1c2ab96cd888ab7b047f272087b327ebc5\"","full_name":"thecode/ha-onewire-sysbus","last_commit":"2c64d60","last_updated":"2024-03-27T07:03:04Z","last_version":"2024.3.0","manifest_name":"1-Wire SysBus","stargazers_count":24,"topics":["1-wire","raspberry-pi"],"last_fetched":1711974731.867437},"637172632":{"manifest":{"name":"Peaqnext sensors"},"description":"Utility sensors to help find the next best usage of your appliances","downloads":41,"domain":"peaqnext","etag_releases":"W/\"77e0706fb4840b8a975e91cb3c664f0fb321f7d467f47740b11236e650b12d43\"","etag_repository":"W/\"b65bebc440a35b53caaed864bce522a807674f94398d3f175def0ece5ea5a8e8\"","full_name":"elden1337/hass-peaqnext","last_commit":"754f5d7","last_updated":"2024-03-28T19:52:38Z","last_version":"0.5.6","manifest_name":"peaqnext, utility sensors","open_issues":4,"stargazers_count":7,"topics":["energidataservice","nordpool"],"last_fetched":1711901789.786568},"711170365":{"manifest":{"name":"Eeveemobility"},"description":"Home Assistant component for Eevee Mobility","domain":"eeveemobility","etag_releases":"W/\"92144e1889abaea59139f6dae5b46f490bb3d42ba96335156e20ad33e629a5ae\"","etag_repository":"W/\"11d1178d26b420579ad31a035da23de0a338cf4f38d0079c5d12fad85cd99fd8\"","full_name":"geertmeersman/eeveemobility","last_commit":"c1cb0a2","last_updated":"2024-03-25T12:56:10Z","last_version":"v0.10.9","manifest_name":"Eevee Mobility","open_issues":1,"stargazers_count":3,"topics":["eevee","mobility"],"last_fetched":1711376113.823722},"269113518":{"manifest":{"name":"xcomfort"},"description":"Eaton xComfort SHC integration for Home Assistant","domain":"xcomfort","etag_releases":"W/\"49fbfde5956795f47df7a3311d2cbd8805003bd446ef756e493798330baa8ecc\"","etag_repository":"W/\"f08ef6e0b26fad88d8281562913905f497ce5eccb869fce7afb3f28fefbe4a80\"","full_name":"plamish/xcomfort","last_commit":"6866055","last_updated":"2024-04-03T10:20:51Z","last_version":"1.3.5","manifest_name":"XComfort SHC","open_issues":15,"stargazers_count":17,"topics":["eaton","xcomfort"],"last_fetched":1712175679.3325},"335750566":{"manifest":{"country":["NL"],"name":"Brandstofprijzen"},"description":"Home Assistant component for fuel prices from United Consumers","domain":"brandstofprijzen","etag_releases":"W/\"28111cd2208d3993514ff982bccabd3741bb97aeb0610e7498536d4839d1fe8a\"","etag_repository":"W/\"8afe0a2a3321d084e8d80d6b3abd57cc096e56dca8f26433798288fe8a85f795\"","full_name":"metbril/home-assistant-brandstofprijzen","last_commit":"a89d988","last_updated":"2024-02-11T02:31:26Z","last_version":"v0.4.0","manifest_name":"Brandstofprijzen","open_issues":3,"stargazers_count":6,"last_fetched":1707625240.368194},"233090507":{"manifest":{"country":["NO"],"name":"meteoalarm"},"description":"meteoalarm sensor","domain":"meteoalarm_m","etag_repository":"W/\"f24c0284a8d230386f603f8bd14d07d0a021948655eded7b781b498a3953f149\"","full_name":"kodi1/meteoalarm","last_commit":"294bc3a","last_updated":"2021-12-31T18:00:45Z","manifest_name":"meteoalarm_m","open_issues":5,"stargazers_count":5,"topics":["meteoalarm"],"last_fetched":1707675576.364491},"269205129":{"manifest":{"name":"VIMAR By-Me Hub"},"description":"VIMAR by-me integration into home-assistant.io","domain":"vimar","etag_releases":"W/\"63afad227405863aa95cc643a497066fdf77a800c927caf24d0034ea3c768de3\"","etag_repository":"W/\"7b952c29f84bd5d3fb66ddc3f21816a5c984154f51b9fd9cd73abe854d27229c\"","full_name":"h4de5/home-assistant-vimar","last_commit":"ddd17c7","last_updated":"2023-10-14T05:47:43Z","last_version":"2023.8.0","manifest_name":"VIMAR By-Me Hub","open_issues":20,"stargazers_count":42,"topics":["vimar","vimar-platform"],"last_fetched":1708100322.186024},"261031401":{"manifest":{"country":["FR"],"name":"couchpotato"},"description":"\ud83c\udfa5 CouchPotato component to feed Upcoming Media Card.","domain":"couchpotato","etag_releases":"W/\"20c27e0a074cfafa68a82557035fafd0ecc72ccdafa291516b6c06cac2965582\"","etag_repository":"W/\"2aa18834cb5021110c54b4e071eba525d16b2ae884001534de1dff2bc937d08d\"","full_name":"youdroid/home-assistant-couchpotato","last_commit":"9e1fc10","last_updated":"2022-06-01T18:11:07Z","last_version":"V1.2.2","manifest_name":"couchpotato","stargazers_count":5,"topics":["couchpotato"],"last_fetched":1681827802.989148},"306822538":{"manifest":{"country":["AU"],"name":"NSW Rural Fire Service - Fire Danger"},"description":"Home Assistant Custom Component: NSW Rural Fire Service Fire Danger","domain":"nsw_rural_fire_service_fire_danger","etag_releases":"W/\"fd6be4e898ee4387f199c9825e70921ef7ecf9869f564359b4d99ee09cbd80a7\"","etag_repository":"W/\"f1e6d88ab9be154ff48f19430f470f87033ca78be376ec7e78e19c295160103a\"","full_name":"exxamalte/home-assistant-custom-components-nsw-rural-fire-service-fire-danger","last_commit":"f9c1844","last_updated":"2024-01-01T11:44:16Z","last_version":"v0.18","manifest_name":"NSW Rural Fire Service - Fire Danger","open_issues":1,"stargazers_count":7,"topics":["fire-danger","nsw","rural-fire-service"],"last_fetched":1707999848.78632},"203736221":{"manifest":{"name":"Uponor Uhome integration"},"description":"Custom Component to connect Home Assistant with Uhome Uponor Smatrix App","domain":"uhomeuponor","etag_releases":"W/\"153e3256f16f7167e97362e6af969d3826ee5a907f35aad014a5a0f094b4a610\"","etag_repository":"W/\"bf18d98b097d0ec3850bb2e039a21e808e148f4d8ef257322fa939a3988c0c7a\"","full_name":"dave-code-ruiz/uhomeuponor","last_commit":"73e8fdc","last_updated":"2024-02-26T09:20:06Z","last_version":"1.3.1","manifest_name":"Uhome Uponor","open_issues":1,"stargazers_count":18,"topics":["gateway","rest-api","setpoint","smatrix","smatrixwaveplus","thermostat","uponor"],"last_fetched":1708950256.434298},"532263303":{"manifest":{"name":"Met.no next 6 hours forecast"},"description":"Met.no next 6 hours forecast component for Home Assistant","downloads":799,"domain":"met_next_6_hours_forecast","etag_releases":"W/\"98de62551400ba830b15a1997ab6a65ad20605a7b88233089a62b62d8d129c39\"","etag_repository":"W/\"cb27d352d0324c944f0d229a26528e7bc234f6b2cb61e5fdf0ec71b587d78324\"","full_name":"toringer/home-assistant-met-next-6-hours-forecast","last_commit":"bbb4a7e","last_updated":"2023-11-26T19:02:11Z","last_version":"v1.1.1","manifest_name":"Met.no next 6 hours forecast","open_issues":1,"stargazers_count":3,"topics":["forecast","metno","weather","weather-forecast"],"last_fetched":1709151707.168239},"548811638":{"manifest":{"name":"Epson Projector Link"},"description":"Home Assistant Epson Projector Link","domain":"epson_projector_link","etag_releases":"W/\"443e28294cef12f2c2bad646d29615e47bca10705ce8d4a609f9fcc7359af568\"","etag_repository":"W/\"e4a60b9306d66adb56e028fcdea1266a93af7098a5baf811d218b64beaf1d608\"","full_name":"amosyuen/ha-epson-projector-link","last_commit":"1371a5d","last_updated":"2024-03-26T15:59:47Z","last_version":"v1.0.0","manifest_name":"Epson Projector Link","open_issues":8,"stargazers_count":8,"topics":["epson-projector"],"last_fetched":1711476957.228739},"207794683":{"manifest":{"name":"GoogleGeocode-HASS"},"description":"Google Location for HASS using the Google Geocode API","domain":"google_geocode","etag_releases":"W/\"ef247e16380f4b826f84214eecde6f9b562b51b89b7482fff4f4d3662a2f4ae2\"","etag_repository":"W/\"81b0025dd5b4f1e50a901e5c6db6d63bf8a1d4620c870caf481556a8d8bf518d\"","full_name":"gregoryduckworth/GoogleGeocode-HASS","last_commit":"83f88d6","last_updated":"2023-11-24T12:29:22Z","last_version":"0.1.9","manifest_name":"Google Geocode","open_issues":3,"stargazers_count":16,"topics":["google-geocode"],"last_fetched":1709050790.275035},"252926906":{"manifest":{"name":"Uponor Smatrix Pulse"},"description":"Uponor Smatrix Pulse heating/cooling system integration for Home Assistant.","domain":"uponor","etag_releases":"W/\"2e7988a3eff22af0542c92f18837cc4bbf3a5e8205abd6063e95472cc2bdfb1f\"","etag_repository":"W/\"d1bdcc279ba05e30940788195cb57ffee929d41b59742100656867649a2c02b1\"","full_name":"asev/homeassistant-uponor","last_commit":"a8a38a4","last_updated":"2024-02-06T20:41:36Z","last_version":"v0.8.3","manifest_name":"Uponor","open_issues":13,"stargazers_count":36,"topics":["heating-control","smatrix","uponor","uponor-smatrix-pulse"],"last_fetched":1709057775.119192},"316597224":{"manifest":{"country":["UA"],"name":"Budova Smart Home"},"description":"A Home Assistant Budova Smart Home integration","domain":"bsh","etag_releases":"W/\"bc085120430dceaa209d117f676c33cf7984e2fe091e512b5f7b7529b8138d7a\"","etag_repository":"W/\"f68c0d299ccc4e53e79a9f6460a373cc3f94950f66aec95f444ab1a2ae2e7088\"","full_name":"dphae/bsh","last_commit":"1c9ac28","last_updated":"2021-08-05T21:00:50Z","last_version":"v1.3.5","manifest_name":"Budova Smart Home","open_issues":1,"stargazers_count":3,"topics":["budova"],"last_fetched":1704903581.870527},"323346718":{"manifest":{"name":"AwoX MESH control"},"description":"AwoX mesh light integration for Home Assistant","domain":"awox","etag_releases":"W/\"902fb9999250f43bd077a2ce71b468f885b7dea8458a4d8fdba4b9e463c90681\"","etag_repository":"W/\"bb59c4098f73957633070ba0e73cfd8192f95571a435c16f1ee9bf065778bccb\"","full_name":"fsaris/home-assistant-awox","last_commit":"5a14ca6","last_updated":"2023-11-19T13:47:24Z","last_version":"0.1.5","manifest_name":"AwoX MESH control","open_issues":2,"stargazers_count":83,"topics":["awox","bluetooth","eglo"],"last_fetched":1707646548.046717},"151580533":{"manifest":{},"description":"High level health status of UniFi Security Gateway devices via UniFi Controller","domain":"unifigateway","etag_releases":"W/\"4b6e1b47545e0901d29a74d3c0b591917bbb2faf4df78cf9925e9dd00e20acac\"","etag_repository":"W/\"4ddaa2cb7f741c63da05068cc1392690589e5422327d2bedd853c3f7b23892e6\"","full_name":"custom-components/sensor.unifigateway","last_commit":"b6bb00c","last_updated":"2021-04-19T12:12:56Z","last_version":"0.3.3","manifest_name":"UniFi Gateway","open_issues":26,"stargazers_count":124,"last_fetched":1711974355.948595},"256709811":{"manifest":{"name":"JQ-300/200/100 Indoor Air Quality Meter"},"description":"JQ-300 Indoor Air Quality Meter Home Assistant Integration","downloads":1,"domain":"jq300","etag_releases":"W/\"4633fd33194c6b032dc9015923889d4079b7716f868ae8ef953a9bcbf533e283\"","etag_repository":"W/\"bf965ffb46114af89a82cd2fd3281ab47629565e1dc51dab735a34d38a5018f3\"","full_name":"Limych/ha-jq300","last_commit":"abc4152","last_updated":"2023-03-08T15:57:41Z","last_version":"0.10.6","manifest_name":"JQ-300/200/100 Indoor Air Quality Meter","open_issues":13,"stargazers_count":47,"topics":["air-quality","air-quality-measurements","air-quality-sensor","home-assistant-component"],"last_fetched":1706552387.185092},"610701268":{"manifest":{"name":"FoxESS - Modbus"},"description":"FoxESS inverter integration. Connect directly to your FoxESS inverter (no cloud!) for real-time status and control.","domain":"foxess_modbus","etag_releases":"W/\"c9dced5424059ef8acdc253bad3e2d9de9b464436a12ababc32bc838f5ebeef0\"","etag_repository":"W/\"e042fa67225629c6bc719a354bac5b362b18edcd7e19eb07b2dd7c2889ad4f5b\"","full_name":"nathanmarlor/foxess_modbus","last_commit":"93c3212","last_updated":"2024-03-27T21:34:11Z","last_version":"v1.10.1","manifest_name":"FoxESS - Modbus","open_issues":21,"stargazers_count":91,"topics":["energy","foxess"],"last_fetched":1712061007.546004},"527414830":{"manifest":{"name":"Eight Sleep Climate"},"description":"Climate entity for controlling eight sleep bed","domain":"eight_sleep_climate","etag_releases":"W/\"df9cf69cfc845a315b90eaba7f3a119a02094b58db59ba53a01e65a38d5c4561\"","etag_repository":"W/\"73e63358223c02ae5f536b473593e40a2844aef77e7fb5fe8bb7d628bae7aff1\"","full_name":"amosyuen/ha-eight-sleep-climate","last_commit":"10b0333","last_updated":"2024-04-01T17:36:18Z","last_version":"v3.0.0","manifest_name":"Eight Sleep Climate","open_issues":14,"stargazers_count":8,"topics":["eight-sleep","thermostat"],"last_fetched":1712002452.523166},"285560672":{"manifest":{"name":"Deutscher Wetterdienst"},"description":"Deutscher Wetterdienst integration for Home-Assistant","downloads":7832,"domain":"dwd_weather","etag_releases":"W/\"06962a3c510fe4b0057ab576cf83dcba19ea453519975b524db10fbbbc867ae5\"","etag_repository":"W/\"a6a709c0d9bd48e4a329b2c9b2c240eecb025df741290f049e41a898820f4805\"","full_name":"FL550/dwd_weather","last_commit":"84df7af","last_updated":"2024-02-08T15:09:29Z","last_version":"v2.1.2","manifest_name":"Deutscher Wetterdienst (DWD)","open_issues":6,"stargazers_count":139,"topics":["deutscher-wetterdienst","dwd","dwd-weather","weather","weather-entity","weather-forecast"],"last_fetched":1712045937.310158},"228579545":{"manifest":{"name":"Orbit BHyve"},"description":"Orbit BHyve custom component for Home Assistant","domain":"bhyve","etag_releases":"W/\"9118efd557e8bd976258a40e4bbf1e458538be8a45d80bb05eeb6922ed18e28f\"","etag_repository":"W/\"6a619a853e25aa8e16cadc41dc2cf0822787c39088c112ad06b3cee8e1f91a01\"","full_name":"sebr/bhyve-home-assistant","last_commit":"97c1195","last_updated":"2023-11-22T21:53:31Z","last_version":"3.2.2","manifest_name":"Orbit B-hyve","open_issues":23,"stargazers_count":230,"topics":["bhyve","home-assistant-component","irrigation","orbit","orbit-bhyve"],"last_fetched":1710577325.677078},"572278409":{"manifest":{"name":"IrrigationProgram Custom Component"},"description":"Irrigation custom component for Home Assistant","downloads":807,"domain":"irrigationprogram","etag_releases":"W/\"af31023b622d92326be4cdc7231864e0999a6d49d6fb710e8e67c5fecc8469f6\"","etag_repository":"W/\"121a0bb982524d151d5183486f5730529157488a5c01583c004d5a068cf0c527\"","full_name":"petergridge/Irrigation-V5","last_commit":"496eb34","last_updated":"2024-04-03T02:59:59Z","last_version":"V5.4.9","manifest_name":"Irrigation controller","open_issues":3,"stargazers_count":50,"topics":["irrigation"],"last_fetched":1712118139.599129},"577080457":{"manifest":{"name":"Sensi"},"description":"HomeAssistant integration for Sensi thermostat","domain":"sensi","etag_releases":"W/\"6d46308ccefe51816c84f9389410f994fac27c77964d5df304e43fb8032583ce\"","etag_repository":"W/\"a42cff6713774985ae4772e8cfdbd4a678b9c6deed9c228297ae4a64dafa7dbe\"","full_name":"iprak/sensi","last_commit":"af9d7fa","last_updated":"2024-04-03T19:47:14Z","last_version":"v1.3.6","manifest_name":"Sensi","open_issues":7,"stargazers_count":28,"topics":["sensi"],"last_fetched":1712225814.399768},"456292486":{"manifest":{"country":["DK"],"name":"Dabbler.dk reader for Echelon/NES smart power meter"},"description":"Home Assistant integration for reading Echelon/NES smart power meter, by utilizing the Dabbler.dk MEP module ","downloads":3,"domain":"dabblerdk_powermeterreader","etag_releases":"W/\"aade152f178b45f7bde2ebe3f96d04d55999a13d59555eae615d7c6eda7968e7\"","etag_repository":"W/\"af31ed43c96eec64a044bc4e2c6ed224bca36b59b79b8d4c3b9631aca2c193e3\"","full_name":"jnxxx/homeassistant-dabblerdk_powermeterreader","last_commit":"4b5239b","last_updated":"2023-03-19T14:54:23Z","last_version":"v1.0.4","manifest_name":"Dabbler.dk reader for Echelon/NES smart power meter","open_issues":4,"stargazers_count":19,"topics":["83331-3i","dabbler-dk","echelon","energy","nes","powermeter"],"last_fetched":1710246364.687644},"283518438":{"manifest":{"name":"RHVoice"},"description":"Home Assistant integration for RHVoice - a local text-to-speech engine.","domain":"rhvoice","etag_releases":"W/\"78a6f724a5b5eb691877b3917eb5457c932fcc7a20c9b5d118d3d72f6cb6d8b9\"","etag_repository":"W/\"eaca0a277d86e63afa5819285664c77d2f0961917cd6ea5974a290b79335f4cb\"","full_name":"definitio/ha-rhvoice","last_commit":"cdf2d3b","last_updated":"2024-02-17T16:56:35Z","last_version":"1.3.2","manifest_name":"RHVoice","stargazers_count":40,"topics":["rhvoice","tts"],"last_fetched":1708532280.359427},"162808336":{"manifest":{"name":"Lightwave RF"},"description":"Lightwave RF custom component for Home Assistant. Requires generation 2 (\"Link Plus\") hub, but will control both generation 1 (\"Connect Series\") and generation 2 (\"Smart Series\") devices.","domain":"lightwave2","etag_releases":"W/\"a17eb12e9c384e4b582d20abc66d74a87982b908b20bd1bfb59e5debc76cfa56\"","etag_repository":"W/\"16bacc73c068a5bb6c24c0f1a7b0ec2bd364ec96e3401800a719711544396b6f\"","full_name":"bigbadblunt/homeassistant-lightwave2","last_commit":"dbebaa8","last_updated":"2024-02-05T22:01:26Z","last_version":"v3.5.20","manifest_name":"Lightwave v2 (Smart Series) custom component","open_issues":6,"stargazers_count":41,"topics":["lightwave","lightwaverf"],"last_fetched":1709382063.645485},"140618233":{"manifest":{},"description":"Custom Gree climate component written in Python3 for Home Assistant. Controls AC's supporting the Gree protocol.","domain":"gree","etag_releases":"W/\"ca381af1bb52808355cbd5165e6b24b5f7577d3bde9f1edbd6bc2e992f96346e\"","etag_repository":"W/\"0a11ea6e3ba9ea27cb209a116435557fbc3e81b5e7a01664e16694e806988364\"","full_name":"RobHofmann/HomeAssistant-GreeClimateComponent","last_commit":"5ab82ca","last_updated":"2024-01-07T13:28:00Z","last_version":"2.6.0","manifest_name":"Gree A/C","open_issues":31,"stargazers_count":254,"last_fetched":1712053297.784198},"264490983":{"manifest":{"name":"Slack User"},"description":"Slack User sensor for Home Assistant","domain":"slack_user","etag_releases":"W/\"3989851d8bd8f83fc7d10d1353eb1a902894076b569657919c2110b43b5b1de4\"","etag_repository":"W/\"24aba23e2e1b1a1b30f70ee8f8c01adc6e43b9ccdfa6ea52265698918dfb25b8\"","full_name":"GeorgeSG/ha-slack-user","last_commit":"2912639","last_updated":"2022-12-01T14:00:43Z","last_version":"v0.5.0","manifest_name":"Slack User","open_issues":3,"stargazers_count":24,"topics":["home-assistant-component"],"last_fetched":1705021316.278712},"222292912":{"manifest":{"name":"iCloud3 v3 iDevice Tracker"},"description":"iCloud3 v3 Prerelease is now available, Enable Beta Versions in HACS. ---- iCloud3 is an advanced iDevice tracker that uses Apple iCloud account and HA Companion App data for presence detection and location based automations.","domain":"icloud3","etag_releases":"W/\"7b971e7beae7ab6f837419d747494e2342fbcbb64a20d3c059c493858265d6c8\"","etag_repository":"W/\"72bbd80e46e0b4f31983a03aead7b6cba0d3102d7fa9a5d4aa95bad43be3a7bf\"","full_name":"gcobb321/icloud3","last_commit":"fcf8fe5","last_updated":"2024-03-30T21:42:20Z","last_version":"v3.0.2a","manifest_name":"iCloud3 Device Tracker","open_issues":60,"stargazers_count":470,"topics":["device-tracker","ha-ios","icloud","icloud-account","tracking","zone","zones"],"last_fetched":1712147141.950911},"505598474":{"manifest":{"country":["PT"],"name":"Pre\u00e7os dos Combust\u00edveis - DGEG"},"description":"Pre\u00e7os dos Combust\u00edveis Online - DGEG","domain":"precoscombustiveis","etag_releases":"W/\"b2c0db951f5e3b0dc3eab07f3cff58abcbd29b1d04fa121d4d3455b9449d27bf\"","etag_repository":"W/\"987b491210a194883ceb674f215aac3609e72fbb0756c95e37c748a243a0cf5e\"","full_name":"netsoft-ruidias/ha-custom-component-precoscombustiveis","last_commit":"c4aa1c8","last_updated":"2023-10-16T15:10:52Z","last_version":"v1.4.2","manifest_name":"PrecosCombustiveis DGEG Integration","open_issues":2,"stargazers_count":17,"topics":["combustiveis","dgeg","fuel-prices","gas","portugal"],"last_fetched":1707395283.960937},"193371922":{"manifest":{"country":["PL"],"name":"Tauron AMIplus"},"description":"This sensor uses unofficial API to get energy usage and generation data from https://elicznik.tauron-dystrybucja.pl.","downloads":1436,"domain":"tauron_amiplus","etag_releases":"W/\"6d44fc7efe4784759b6be3ea8565266fe4f3a2576f03e4a32d3f5c48123f0645\"","etag_repository":"W/\"1b1c14144adcbdd219f3b8866f6a2e2e778489d4496215787c197faece62b2fe\"","full_name":"PiotrMachowski/Home-Assistant-custom-components-Tauron-AMIplus","last_commit":"3c58741","last_updated":"2024-02-09T17:56:39Z","last_version":"v2.6.0","manifest_name":"Tauron AMIplus","open_issues":4,"stargazers_count":120,"topics":["amiplus","elicznik","energy-monitor","tauron"],"last_fetched":1712132575.793147},"159025199":{"manifest":{},"description":"AEMET integration for Home Assistant","domain":"aemet","etag_releases":"W/\"25d654cf5c308b3217d630185771c5553d28a0b5ee49afe542c719ad8052982e\"","etag_repository":"W/\"7f44f4660af97b6ae2647e8031f6abccc8bf828efd4f7a41318295e8723ad9a8\"","full_name":"kalanda/homeassistant-aemet-sensor","last_commit":"53bc433","last_updated":"2022-06-03T06:00:18Z","last_version":"v1.4.0","manifest_name":"AEMET - Agencia estatal de meteorologia (Spain)","stargazers_count":21,"topics":["aemet"],"last_fetched":1686054711.110602},"577620239":{"manifest":{"name":"Cleanmate"},"description":"Let Home Assistant take controll over your Cleanmate vacuum","domain":"cleanmate","etag_releases":"W/\"1e1cb74cb1798c068f2c488d9be80a1897857f32f5dc8d8550c3a3733340ca53\"","etag_repository":"W/\"3bcf4a1103f81f5bfe8943874db92ce169730a62a619975730223b8c0f6f1bbd\"","full_name":"albinmedoc/ha-cleanmate","last_commit":"6059907","last_updated":"2023-09-25T07:46:40Z","last_version":"v.1.2.1","manifest_name":"Cleanmate","open_issues":1,"stargazers_count":3,"topics":["cleanmate","custom-integration"],"last_fetched":1706782426.592732},"710608974":{"manifest":{"name":"Yeelock BLE"},"description":"Add your Yeelock to Home Assistant with BLE","downloads":97,"domain":"yeelock","etag_releases":"W/\"a3758457385108e4db6396270c6cc681a1756faed9aba86c6b131518799c44ad\"","etag_repository":"W/\"1a2fd7a5e5c6e0ac0d8b2f4ab368e1c1ae0a1c2bcd346508d33ad94bde94c25e\"","full_name":"codyc1515/ha-yeelock","last_commit":"c13c882","last_updated":"2024-03-17T21:14:19Z","last_version":"v2.1.1","manifest_name":"Yeelock BLE","open_issues":6,"stargazers_count":10,"topics":["ble","bluetooth","yeelock"],"last_fetched":1711966546.773974},"261873234":{"manifest":{"name":"Sector Alarm"},"description":"Integration to Sector Alarm for Home Assistant","downloads":13,"domain":"sector","etag_releases":"W/\"e8c7f4d1c1e27a72d0caa625d74d523eb7b2f000b8698686e5e2f0f1b3b0c4ad\"","etag_repository":"W/\"98b3a91db4c1d8450def17621246a892b3c4b2016e9cb97ec1779e6cddb6da0f\"","full_name":"gjohansson-ST/sector","last_commit":"f9c50c4","last_updated":"2024-01-22T21:41:33Z","last_version":"v0.4.3","manifest_name":"Sector Alarm","open_issues":16,"stargazers_count":27,"topics":["alarm","alarm-control","alarm-control-panel","lock","sector","sector-alarm","temperature-sensor"],"last_fetched":1712081941.242586},"579801670":{"manifest":{"name":"JellyFish Lighting"},"description":"A Jellyfish Lighting integration for Home Assistant","downloads":135,"domain":"jellyfish_lighting","etag_releases":"W/\"b84616334975a29bfc758fd92210d6b91a16da76e625c515717c8bab0ee72cdc\"","etag_repository":"W/\"012eb8ebe35ef795fcb8eef0d8ed1f1b2ace6c169660015ad53bfa2cccec18c5\"","full_name":"bdunn44/hass-jellyfish-lighting","last_commit":"3a168b9","last_updated":"2023-05-24T21:34:01Z","last_version":"v1.2.0","manifest_name":"JellyFish Lighting","open_issues":1,"stargazers_count":8,"topics":["assistant","home","jellyfish","led","led-controller","led-strips","lighting"],"last_fetched":1709081643.707215},"384910725":{"manifest":{"name":"XMR Pool Statistics"},"description":"XMR Pool Statistics integration for Home Assistant","domain":"xmrpool_stat","etag_releases":"W/\"b4fe888cb5b9620e57be7c9b5350ce769193ca8c01eb94c61df98c7411d0c927\"","etag_repository":"W/\"eced45b8944ca32acbcc55b74bd4f55e0359ac2380bc58a8f2b6cfa80ba0f384\"","full_name":"hwmland/homeassistant-xmrpool_stat","last_commit":"d7cf41c","last_updated":"2023-07-04T16:36:08Z","last_version":"v0.2.2","manifest_name":"XMR Pool Statistics","open_issues":1,"stargazers_count":4,"topics":["cryptocurrency","home-assistant-integration","monero","xmr"],"last_fetched":1692944362.879944},"199888538":{"manifest":{"country":["DE"],"name":"Stadtreinigung Hamburg"},"description":"Stadtreinigung Hamburg - get garbage collection dates in Hamburg - custom component for Home Assistant","downloads":238,"domain":"stadtreinigung_hamburg","etag_releases":"W/\"26aade0da3a353ca905a778f54883d5e526bf3532e92dbc992892db217b6be0d\"","etag_repository":"W/\"33a1145eda058df48c3af5da64e0fd03fcf600dc00fd06494afe8a7c6cc34bf1\"","full_name":"custom-components/sensor.stadtreinigung_hamburg","last_commit":"431dbda","last_updated":"2023-05-21T10:19:20Z","last_version":"v1.1.3","manifest_name":"Stadtreinigung Hamburg","open_issues":1,"stargazers_count":22,"last_fetched":1711995431.227735},"283243425":{"manifest":{"name":"SoX"},"description":"A Home Assistant integration to turn your vacuum into an audio player.","domain":"sox","etag_releases":"W/\"0ea33fea2a34bc90fc54ecb639c9aedb604257489a4d6c2189ca868cbfa5c321\"","etag_repository":"W/\"24a1d6190b9af6aa0ecfe5baa624c11d8d6a5804fba269018e8dcf64b75106c7\"","full_name":"definitio/ha-sox","last_commit":"c6d1d7d","last_updated":"2024-03-16T16:53:56Z","last_version":"1.2.4","manifest_name":"SoX","stargazers_count":22,"topics":["audio-player","roborock","robot-vacuum","vacuum","xiaomi"],"last_fetched":1710613041.465685},"356827073":{"manifest":{"name":"OpenRGB"},"description":"OpenRGB integration for Home Assistant","domain":"openrgb","etag_releases":"W/\"5a5ab8a4136a4aa69d3f61cc1056dcc0b0971526476391447220cf142388693b\"","etag_repository":"W/\"ed70afb2d8a8aa99908df60d7f4a5da01e8cffe6ec10d9feb74701da7125aa15\"","full_name":"koying/openrgb_ha","last_commit":"f37f8fa","last_updated":"2023-03-19T08:28:10Z","last_version":"v2.3","manifest_name":"OpenRGB","open_issues":24,"stargazers_count":96,"topics":["light","openrgb"],"last_fetched":1710958795.148954},"530452578":{"manifest":{"name":"FlashForge Adventurer 3"},"description":"Home Assistant integration providing support for the FlashForge Adventurer 3 3D printer.","domain":"flashforge_adventurer_3","etag_releases":"W/\"b2e78a29f28d69b0119ad3011726eb7f0167348180694e93d4227f0c9a79b443\"","etag_repository":"W/\"7d5d42492ee83690c9de03e1fbd5d9e1492ebb548cea1b262210c50236cdcf7a\"","full_name":"modrzew/hass-flashforge-adventurer-3","last_commit":"1c6e360","last_updated":"2024-03-24T04:39:19Z","last_version":"v1.0.4","manifest_name":"FlashForge Adventurer 3","open_issues":10,"stargazers_count":17,"topics":["flashforge","flashforge-adventurer"],"last_fetched":1711556560.110736},"268118148":{"manifest":{"name":"Gardena Smart System"},"description":"Home Assistant custom component integration for Gardena Smart System","domain":"gardena_smart_system","etag_releases":"W/\"0240b6fdba26a43670de380f467efcf641919c0f9306b9e9dade0d0624fa4b42\"","etag_repository":"W/\"6de743649cffec7e876a3ef852a593afbd6e770f2874b1cbce50acd7b3ffd19b\"","full_name":"py-smart-gardena/hass-gardena-smart-system","last_commit":"f00a1b2","last_updated":"2024-03-17T18:45:07Z","last_version":"1.1.0","manifest_name":"Gardena Smart System integration","open_issues":61,"stargazers_count":175,"topics":["gardena","gardena-api","gardena-smart-system"],"last_fetched":1711988601.657041},"547177218":{"manifest":{"name":"cFos Powerbrain"},"description":"Custom Component for Homeassistant to integrate cFos Powerbrain devices","domain":"powerbrain","etag_releases":"W/\"7d65b32cb50e1a0108754052356ada5f7ec809bc29b31bc436eca1d4105209c2\"","etag_repository":"W/\"10e1149965f00df2247595fedf17ea6277d32176641872d7d94bc46fa64eefae\"","full_name":"mb-software/homeassistant-powerbrain","last_commit":"80213b2","last_updated":"2023-10-03T03:39:00Z","last_version":"0.7.0","manifest_name":"cFos Powerbrain","open_issues":12,"stargazers_count":12,"topics":["cfos","evse","homeassistant-custom-component","powerbrain","wallbox"],"last_fetched":1711959792.408263},"233089370":{"manifest":{"country":["NO"],"name":"esp_wd"},"description":"easyesp status sensor","domain":"esp_wd","etag_repository":"W/\"617356c8cebadf530dbb0ff5631e14cef19cab29def27f78bec9db7a27856d40\"","full_name":"kodi1/esp_wd","last_commit":"e2b4ce8","last_updated":"2022-02-23T01:23:48Z","manifest_name":"easy esp monitor","stargazers_count":3,"topics":["esp-easy"],"last_fetched":1707699557.827128},"534317237":{"manifest":{"name":"QR-Code Generator"},"description":"Custom Home Assistant integration to create a camera that displays a custom QR-Code","domain":"qr_generator","etag_releases":"W/\"ed71f2acf2e6693bd6353aff8ce7210a92bf9bc209ecf9b609774bfb1902b994\"","etag_repository":"W/\"6b398a304566d5e46bddeaa67a7a999ad91ec04acf6133ea79fb65314147a8e6\"","full_name":"DeerMaximum/QR-Code-Generator","last_commit":"0c186fe","last_updated":"2024-04-01T14:12:38Z","last_version":"v2.1.7","manifest_name":"QR-Code Generator","open_issues":1,"stargazers_count":32,"topics":["qrcode-generator"],"last_fetched":1711995457.994891},"618871749":{"manifest":{"name":"ElevenLabs TTS"},"description":"Custom TTS Integration using ElevenLabs API","downloads":829,"domain":"elevenlabs_tts","etag_releases":"W/\"80345468c5b22360d700727205d7e3171f2546b6b9a9fef4d72ac04f8565910c\"","etag_repository":"W/\"2fc01fa26d80270bea7cd68d200b3fec26791758ff358fa31d1d3536b3dad383\"","full_name":"carleeno/elevenlabs_tts","last_commit":"8cff21b","last_updated":"2024-03-11T02:25:08Z","last_version":"2.3.0","manifest_name":"ElevenLabs TTS","open_issues":8,"stargazers_count":71,"topics":["elevenlabs","text-to-speech","tts"],"last_fetched":1711916067.570828},"455217528":{"manifest":{"name":"systemd notifier"},"description":"systemd service for Home Assistant","domain":"sdnotify","etag_repository":"W/\"88206962aa7414bb1145da12833de0e97f8fef2eda55ccbb3206b7a52aac8dfa\"","full_name":"brianegge/home-assistant-sdnotify","last_commit":"e73ebfd","last_updated":"2022-05-29T10:15:45Z","manifest_name":"sdnotify","stargazers_count":17,"topics":["systemd"],"last_fetched":1707740601.295241},"529926820":{"manifest":{"name":"lelight"},"description":"LeLight integration for Home Assistant","domain":"lelight","etag_releases":"W/\"87f86ce9269e27b17d7a73c29f91d61d747c1db009acd7525fb6951b5cb0e79d\"","etag_repository":"W/\"f2aa0d564ab4a68a5de71c9b82cd220fa634b488ca2497a0a0861d7305ae1e46\"","full_name":"v1ack/lelight","last_commit":"0b8661c","last_updated":"2023-03-08T09:39:00Z","last_version":"0.2.0","manifest_name":"LeLight (IRALAN)","open_issues":5,"stargazers_count":6,"topics":["ble","iot","lelight"],"last_fetched":1710606093.612907},"389366750":{"manifest":{"name":"Rental Control"},"description":"Rental Control system for Home Assistant","downloads":409,"domain":"rental_control","etag_releases":"W/\"6370730122cd4b91b81847793df1b9cf92ffd735e5e94561837f7b585168d0e7\"","etag_repository":"W/\"92093c7db2fd8a73a8ed1b32c7e36fe43127bd274a436a4f0318f4d77ad7fcd1\"","full_name":"tykeal/homeassistant-rental-control","last_commit":"da59b06","last_updated":"2024-03-18T17:42:07Z","last_version":"v1.0.1","manifest_name":"Rental Control","open_issues":5,"stargazers_count":31,"topics":["airbnb","ical","locks"],"last_fetched":1712182781.304037},"152294445":{"manifest":{"name":"Remote Home-Assistant"},"description":"Links multiple home-assistant instances together","domain":"remote_homeassistant","etag_releases":"W/\"faaef231614f9d7d40709716c6893a8ec6bab4e40faebdc5d3bef1c13c0ef83e\"","etag_repository":"W/\"f67c6507324b751682fac4da4fd93b930033ec3e49b9ab6a37598091c90b8190\"","full_name":"custom-components/remote_homeassistant","last_commit":"c685d3f","last_updated":"2024-03-28T22:42:09Z","last_version":"3.11","manifest_name":"Remote Home-Assistant","open_issues":89,"stargazers_count":801,"last_fetched":1712139346.23792},"319820836":{"manifest":{"country":["US"],"name":"Coway IoCare"},"description":"Home Assistant custom component for monitoring and controlling Coway Airmega Purifiers","downloads":338,"domain":"coway","etag_releases":"W/\"d5129d3714bbc2fb5e16742345326ba7dc5f67e3e9805ddec88a039edffa7081\"","etag_repository":"W/\"799cf55bab5765436e81b0866d22d9c826f424115b54ed69a8cb9b6ee4e9f4b4\"","full_name":"RobertD502/home-assistant-iocare","last_commit":"12faddc","last_updated":"2024-04-01T15:49:30Z","last_version":"0.3.3","manifest_name":"Coway IoCare","open_issues":2,"stargazers_count":38,"topics":["coway","coway-iocare","home-assistant-component","iocare"],"last_fetched":1711995757.932392},"236146080":{"manifest":{"name":"Solaredge Modbus"},"description":"Home assistant Component for reading data locally from Solaredge inverter through modbus TCP","domain":"solaredge_modbus","etag_releases":"W/\"fafbf75e53f03bde4814fb70e4fe09dfafc32c4e5891e07f379bcaa180b90ed2\"","etag_repository":"W/\"71c768d07c6ca0d2db1ca58a704d97d0bcb761d49072c9278596d089d7d5aa32\"","full_name":"binsentsu/home-assistant-solaredge-modbus","last_commit":"9613797","last_updated":"2024-01-23T14:37:43Z","last_version":"V1.11.1","manifest_name":"SolarEdge Modbus","open_issues":69,"stargazers_count":248,"topics":["modbus","modbus-tcp","solaredge","solaredge-inverter"],"last_fetched":1711707268.299408},"453143227":{"manifest":{"country":["GB"],"name":"Juwel Helialux Smart Controller"},"description":"A custom component for Home Assistant to monitor your Juwel HeliaLux light states","domain":"juwel_helialux","etag_releases":"W/\"fe9e265aa4129b02062eb67939a2aa372b646dc23843098de09f5e9c7bbad923\"","etag_repository":"W/\"6954502876b9cf6efb2d5d0a1bd67ea4d0e1c80f7767db5128d8b2601d586825\"","full_name":"MrSleeps/Juwel-HeliaLux-Home-Assistant-Custom-Component","last_commit":"70941c5","last_updated":"2022-11-24T15:37:37Z","last_version":"v0.0.6.2","manifest_name":"Juwel Helialux","stargazers_count":7,"topics":["aquarium","home-assistant-component","lightning"],"last_fetched":1678387480.120739},"346329169":{"manifest":{"name":"MiWiFi"},"description":"MiWiFi for Home Assistant","domain":"miwifi","etag_releases":"W/\"e4caa0398085313d81abf03841a1a69f9652230dd8111f290e88153e99c90d49\"","etag_repository":"W/\"eb055b4307bf1b76a8fa065697c2e1432756a462cca54435048548bda79762b3\"","full_name":"dmamontov/hass-miwifi","last_commit":"8442d60","last_updated":"2023-12-18T08:11:20Z","last_version":"v3.0.0","manifest_name":"MiWiFi","open_issues":74,"stargazers_count":136,"topics":["mi","miwifi","redmi","xiaomi"],"last_fetched":1712060790.840903},"440617082":{"manifest":{"name":"NYC 311 Public Services Calendar"},"description":"Home Assistant integration for NYC trash collection, school, and alternate side parking schedules.","domain":"nyc311","etag_releases":"W/\"7693158a8e6ad033e2a7a6c837fff34372ccd70278fd01bc3376de0ba8d5d5ab\"","etag_repository":"W/\"ec339027d3c6ab71d594fb7ca78168751c7cde85f1830a77c9959f7a89c8d969\"","full_name":"elahd/ha-nyc311","last_commit":"faa6194","last_updated":"2024-03-25T17:03:12Z","last_version":"v0.1.5","manifest_name":"NYC 311 Public Services Calendar","open_issues":4,"stargazers_count":5,"topics":["community","government-data","nyc","nyc-opendata"],"last_fetched":1711390757.703679},"634325657":{"manifest":{"name":"GoXLR Utility"},"description":"Home Assistant Integration - GoXLR Utility","downloads":91,"domain":"goxlr_utility","etag_releases":"W/\"285ff1f6e69bda47c87bb5515b9d38a914495b53c12c330f9179dcd51d2cbc5d\"","etag_repository":"W/\"74cd262340b213b0641fed168fcd212c0a4fc6c8e90e25c8cff2c7342d84cea1\"","full_name":"timmo001/homeassistant-integration-goxlr-utility","last_commit":"a024672","last_updated":"2024-03-27T04:03:32Z","last_version":"1.3.3","manifest_name":"GoXLR Utility","open_issues":7,"stargazers_count":2,"topics":["goxlr-utility-api","home-assistant-integration"],"last_fetched":1712154011.596943},"296946072":{"manifest":{"name":"Kodi Recently Added Media"},"description":"Custom component to feed recently added tv shows and movies to the custom card \"Upcoming Media Card\" for Home Assistant. ","domain":"kodi_recently_added","etag_releases":"W/\"e5f82af4a21d0065b406de865954f255b223cf17240217bb8723145fae53823b\"","etag_repository":"W/\"47832d4eb254503038f76fbec239dc6c8521fa1167547abd6764d8ceb9932be5\"","full_name":"boralyl/kodi-recently-added","last_commit":"5433e49","last_updated":"2021-12-19T23:48:44Z","last_version":"v2.0.5","manifest_name":"Kodi Recently Added Media","stargazers_count":7,"topics":["kodi"],"last_fetched":1709928766.775231},"456340193":{"manifest":{"country":["CA"],"name":"Innova Heat and A/C"},"description":"Home Assistant Integration for Innova 2.0 Heat Pump and AirLeaf","domain":"innova","etag_releases":"W/\"2d743afa370f89200bf7dde798cc35bb49c30e9bfdf25d5fccae7672700c3db3\"","etag_repository":"W/\"126de4fcc1f93bcad7f61cd0b0b9a4ce5d5752fba73e7d1ab7de6e18951d4275\"","full_name":"danielrivard/homeassistant-innova","last_commit":"7fb7c73","last_updated":"2024-04-04T07:23:07Z","last_version":"v1.4.5","manifest_name":"Innova","open_issues":6,"stargazers_count":27,"topics":["airleaf","climate","fancoil","innova","innova-2point0","innovaenergie","twopointzero"],"last_fetched":1712225708.294268},"585050790":{"manifest":{"name":"tdarr"},"description":"Tdarr Home Assistant Integration","domain":"tdarr","etag_releases":"W/\"46d132bc6889f2d1544d32779e5b7c1c6984a3f2d8e09a2f4e9dff814117295f\"","etag_repository":"W/\"dcb76b1e6e9631c64a48e4444e6000960d9fc74f523c6e9d0135f8994c09eb8e\"","full_name":"itchannel/tdarr_ha","last_commit":"701b03a","last_updated":"2023-12-29T23:21:16Z","last_version":"1.13-Release","manifest_name":"Tdarr","open_issues":2,"stargazers_count":11,"topics":["assistant","home","tdarr","transcoding"],"last_fetched":1706026860.961157},"582608844":{"manifest":{"name":"Emu M-Bus Center"},"description":"Reads Values from a Emu M-Bus Center and exposes them to Home Assistant","domain":"emu_m_bus_center","etag_releases":"W/\"e7db416f0e3f05cbcedc15aee577ffefa2163399a896cf9e24b6419fc69e1b55\"","etag_repository":"W/\"cf2cc909ffa28b138ae2f2848791867fa5b1e2de5d46959128e6dc8440315487\"","full_name":"redlukas/emu_mbus_center","last_commit":"8586526","last_updated":"2024-04-04T01:51:43Z","last_version":"v1.1.1","manifest_name":"Emu M-Bus Center","open_issues":4,"stargazers_count":1,"topics":["m-bus","rest-client"],"last_fetched":1712197741.229962},"478078274":{"manifest":{"country":["RU"],"name":"SST Cloud integration"},"description":"Unofficial SST Cloud integration for Home Assistant","domain":"sst_cloud","etag_releases":"W/\"b38026d57cb05dad76516adb0d2b193d45457dd8e0b8bd217991a5ce3da23453\"","etag_repository":"W/\"1b90cf8a70f65ba2598a4fac6b03cdb0692afc2ad31936fbf561b4978fb9e035\"","full_name":"sergeylysov/sst_cloud","last_commit":"984bdf3","last_updated":"2024-02-01T09:46:25Z","last_version":"v0.1.31","manifest_name":"SST Cloud integration","open_issues":3,"stargazers_count":27,"topics":["iot","neptun","sst"],"last_fetched":1710483814.984273},"247070270":{"manifest":{"name":"SamsungTV Smart"},"description":"\ud83d\udcfa Home Assistant SamsungTV Smart Component with simplified SmartThings API Support configurable from User Interface.","domain":"samsungtv_smart","etag_releases":"W/\"a2a7461823be45ce9be168d25d185251f9ba31efcce8526d28f27f2675808078\"","etag_repository":"W/\"b099e033afc6e19de847492ac83cd6e50f67cfd94aee9d68be18217b1a424188\"","full_name":"ollo69/ha-samsungtv-smart","last_commit":"bda579b","last_updated":"2024-02-19T01:20:39Z","last_version":"v0.13.4","manifest_name":"SamsungTV Smart","open_issues":29,"stargazers_count":386,"topics":["samsung","samsung-smart-tv","samsung-tv","smartthings"],"last_fetched":1712175653.049214},"460392242":{"manifest":{"country":["SE"],"name":"Svensk Postutdelning"},"description":"Swedish Post Delivery integration for Home Assistant","domain":"swemail","etag_releases":"W/\"e9a9bbf9b1fb381efd48a8295226a756e3329956d5ee65ebd0d5fc58510a1306\"","etag_repository":"W/\"d88b4482dab5ecdd611d11ca96c27f531dedb2f7286b80cf5efc891f361012cf\"","full_name":"DSorlov/swemail","last_commit":"c16c165","last_updated":"2023-06-12T09:48:08Z","last_version":"v1.0.7","manifest_name":"Svensk Postutdelning","open_issues":2,"stargazers_count":30,"topics":["citymail","postnord"],"last_fetched":1711441075.989416},"224374747":{"manifest":{"country":["CN"],"name":"Phicomm DC1"},"description":"\u6590\u8bafDC1\u63d2\u6392\u63a5\u5165Home Assistant\u63d2\u4ef6\uff0c\u672c\u63d2\u4ef6\u539f\u4f5c\u8005NETYJ\uff0c\u6b64\u5904\u4ec5\u4e3aHACS\u5b89\u88c5\u65b9\u4fbf\u4e4b\u7528\u3002","domain":"phicomm_dc1","etag_repository":"W/\"b700d3f552ad095779ad037738f65bed17538c6073269f61ebb382edb48d19e5\"","full_name":"5high/phicomm-dc1-homeassistant","last_commit":"9328717","last_updated":"2021-06-04T14:08:17Z","manifest_name":"dc1","open_issues":3,"stargazers_count":14,"last_fetched":1711455792.54535},"279680951":{"manifest":{"country":["CS","DA","DE","EN","IT","NB","NL","SK"],"name":"Jablotron 100"},"description":"Home Assistant custom component for JABLOTRON 100+ alarm system","domain":"jablotron100","etag_releases":"W/\"2a9ca9b846547e20b9f48db3a07932d6b73ee4f7b23472e7e44e4ccf2ecffdf8\"","etag_repository":"W/\"e245cbb28bdaf0122984d54aabff6d98c82b7250a1110f3b43dc4b439d494098\"","full_name":"kukulich/home-assistant-jablotron100","last_commit":"6220840","last_updated":"2024-03-23T15:30:08Z","last_version":"3.23.1","manifest_name":"Jablotron 100","open_issues":5,"stargazers_count":62,"topics":["alarm","jablotron"],"last_fetched":1711527706.854201},"644033469":{"manifest":{"name":"Weather.com"},"description":"Home Assistant custom component/integration for Weather.com","domain":"weatherdotcom","etag_releases":"W/\"3cdb4995fe2f1cb611ed50a74241e0de2f28c9726dc4da1d284d6ccc9e0ecafa\"","etag_repository":"W/\"655d2f6ef2fb6567bf70153fbd199251b04cfb265ceb23e33e6312a1d15b146e\"","full_name":"jaydeethree/Home-Assistant-weatherdotcom","last_commit":"6f8d850","last_updated":"2024-02-25T00:10:47Z","last_version":"1.1.6","manifest_name":"Weather.com","open_issues":1,"stargazers_count":26,"topics":["hassio-integration","weather","weather-forecast"],"last_fetched":1711592779.479024},"695365328":{"manifest":{"country":["SE"],"name":"Luncha I Mj\u00e4rdevi"},"description":"A custom component that creates sensors for the restaurants in and around Mj\u00e4rdevi Science Park. The data is collected from my website Luncha I Mj\u00e4rdevi","downloads":2,"domain":"lunchaimjardevi","etag_releases":"W/\"329513985bcd013c162da44c2adbf38e8a96a9a7feda6537f2f9338ae8eca79d\"","etag_repository":"W/\"1da539bd5530ab68b1c030e2be1c43acdf8e13fb20c39c401d14dd1a064fa26c\"","full_name":"popeen/Home-Assistant-Custom-Component-Luncha-I-Mjardevi","last_commit":"0bc0e3b","last_updated":"2023-12-14T07:16:43Z","last_version":"2023.09.2","manifest_name":"Luncha I Mj\u00e4rdevi","last_fetched":1705256501.358807},"596993645":{"manifest":{"name":"Personio"},"description":"Integration with the Personio API for Home Assistant.","domain":"personio","etag_releases":"W/\"50fc93337de9f1d2600069eb3df59fb2c7be63540b4fc5b4b003248a56441661\"","etag_repository":"W/\"856ef5ec67317de2642b4785391e7212d8263df4e20e3c85e31980f5b68759b6\"","full_name":"Sese-Schneider/ha-personio","last_commit":"6766cec","last_updated":"2023-07-31T09:19:53Z","last_version":"v1.1.0","manifest_name":"Personio","stargazers_count":5,"topics":["hacs-custom","personio","personio-api"],"last_fetched":1697667497.450419},"452272431":{"manifest":{"country":["CN"],"name":"bemfa"},"description":"\u5c06 Home Assistant \u5b9e\u4f53\u540c\u6b65\u81f3\u5df4\u6cd5\u4e91\uff0c\u5e76\u4f7f\u7528\u5c0f\u7231\u540c\u5b66/\u5929\u732b\u7cbe\u7075/\u5c0f\u5ea6\u97f3\u7bb1\u63a7\u5236\u3002","domain":"bemfa","etag_releases":"W/\"9a5a1ac2864a4120e4bdd5302eb7da2b0ce63498bf77c7f8376160277c272fb5\"","etag_repository":"W/\"a229a0e87712af9366e08490d58eea6b87c156ceec4cdb6282820331234ba043\"","full_name":"larry-wong/bemfa","last_commit":"f87cb83","last_updated":"2023-04-29T12:55:00Z","last_version":"v1.4.0","manifest_name":"Bemfa","open_issues":20,"stargazers_count":322,"topics":["bemfa"],"last_fetched":1712046052.80342},"570874359":{"manifest":{"name":"Watchman SENSiT integration for Home Assistant"},"description":"Kingspan Connect Sensor integration for Home Assistant","domain":"kingspan_watchman_sensit","etag_releases":"W/\"c9d8200a83a1c996377b67935eabaa49b3ac9bfebde7afca52487b39f1d2dfb5\"","etag_repository":"W/\"4c13bb0f478d9a0524b6d291935622c7aacb80842c69e6dfc5baa3790627aaba\"","full_name":"masaccio/ha-kingspan-watchman-sensit","last_commit":"6585f20","last_updated":"2024-01-05T17:14:44Z","last_version":"v1.6.5","manifest_name":"Kingspan Watchman SENSiT","stargazers_count":8,"topics":["energy-monitor","iot","kingspan","monitoring","oil-sensor"],"last_fetched":1711275495.29965},"430818561":{"manifest":{"name":"Tekmar Gateway 482"},"description":"Home Assistant integration for the Tekmar Gateway 482","domain":"tekmar_482","etag_releases":"W/\"489e774c1691ca428d1c59f482b5af6338872a56d4b4feec16f1d4719e5e8a0b\"","etag_repository":"W/\"853916bf3309d7b02785c64b52c69980d160070c89141ef6d44f71d66dd67076\"","full_name":"WillCodeForCats/tekmar-482","last_commit":"b0b881d","last_updated":"2024-04-01T10:00:15Z","last_version":"v0.9.19","manifest_name":"Tekmar Gateway 482","open_issues":7,"stargazers_count":5,"topics":["tekmar"],"last_fetched":1712082232.775938},"503045365":{"manifest":{"name":"Senertec Energy System"},"description":"Home Assistant custom component integration for Senertec energy units.","domain":"senertec","etag_releases":"W/\"6395f53ae3e32bbb50a328233878c284825791e0d6dcb60af34123ae72dedb60\"","etag_repository":"W/\"3ba280721a7da976a784efd3c7e990f3e1d0001e43d98889e3580b8769b87824\"","full_name":"Kleinrotti/hass-senertec","last_commit":"06ab1f8","last_updated":"2023-05-25T16:27:07Z","last_version":"0.1.5","manifest_name":"Senertec Energy Systems","open_issues":1,"stargazers_count":1,"topics":["senertec"],"last_fetched":1711318648.970946},"246657442":{"manifest":{"name":"Current Cost"},"description":"CurrentCost Meter Reading Custom Component for Home Assistant ","domain":"currentcost","etag_releases":"W/\"cea6cab363d4015ce6a670e49d3c8d16e06ae5c64f21baf2bb7cd771ece07139\"","etag_repository":"W/\"bccbc9e8dd3fdf00b71dab5bbab1834cdbc6506773f33be1d6d3e02739f712c0\"","full_name":"lolouk44/CurrentCost_HA_CC","last_commit":"8302c7f","last_updated":"2023-06-29T21:12:28Z","last_version":"0.2.4","manifest_name":"Current Cost","open_issues":5,"stargazers_count":16,"topics":["cc128","current-cost","currentcost","envi","envir"],"last_fetched":1705810828.238209},"545025660":{"manifest":{"name":"Web Untis"},"description":"Custom component to access data from Web Untis in Home Assistant","downloads":373,"domain":"webuntis","etag_releases":"W/\"14bfbd894fd769800b64fc6b871ae59cfbb5c7ef9799f97eac56f667d07b3d8a\"","etag_repository":"W/\"a90624eb5c69ab339d00538778c44303cd3ac52db7661a943def94e6ebfb993f\"","full_name":"JonasJoKuJonas/homeassistant-WebUntis","last_commit":"3c89739","last_updated":"2024-03-20T17:16:31Z","last_version":"v1.0.6","manifest_name":"Web Untis","open_issues":8,"stargazers_count":36,"topics":["homeassistant-custom-component","school","webuntis","webuntis-api","webuntis-client"],"last_fetched":1710958763.829821},"283847957":{"manifest":{"name":"pyscript"},"description":"Pyscript adds rich Python scripting to HASS","downloads":18384,"domain":"pyscript","etag_releases":"W/\"891ff3887f4afce9e82c4ad86316267ddfe361cf432dfe69a30982a7f6923279\"","etag_repository":"W/\"a42a83b1619415ff70a3985740060fb5829ab658992b2e17e1072b96c2bf203e\"","full_name":"custom-components/pyscript","last_commit":"9ba1f43","last_updated":"2024-04-04T08:54:34Z","last_version":"1.5.0","manifest_name":"Pyscript Python scripting","open_issues":67,"stargazers_count":770,"topics":["jupyter"],"last_fetched":1712225682.130019},"125756318":{"manifest":{"country":["HU"],"name":"BKK Stop Information"},"description":"HomeAssistant custom component for Budapest public transportation","domain":"bkk_stop","etag_releases":"W/\"564de667a35d23b2268b06ecc4320b4eca8a2be62074fcf545727e6278acdfc9\"","etag_repository":"W/\"8639b21f60948e92ce856f36e7a9d706d18fb68817a77367e54aa36ccc9a2c8a\"","full_name":"amaximus/bkk_stop","last_commit":"1ab7187","last_updated":"2024-04-02T08:32:53Z","last_version":"2.9.10","manifest_name":"BKK Stop Information","open_issues":1,"stargazers_count":27,"topics":["bkk","budapest","hungary","transportation"],"last_fetched":1712052885.393495},"583896361":{"manifest":{"country":["PL"],"name":"ESA NASK Air Quality Sensor"},"description":"Home Assistant component for scrapping data from ESA NASK stations","domain":"esa_nask","etag_releases":"W/\"e3ad47da44dd1c7c4b9f61626a7d6e95cb4701c22edb315d8bb5cbe88ae602ec\"","etag_repository":"W/\"53d38d9ca15dd7ee46b83361bf7041b6df1997fe5e24e5d0a4c3c578852a92de\"","full_name":"Mr-Groch/HA-ESA-NASK-Air-Quality","last_commit":"c310ea3","last_updated":"2024-03-29T11:09:21Z","last_version":"1.0.2","manifest_name":"ESA NASK Air Quality Sensor","stargazers_count":4,"topics":["air-quality","esa","nask"],"last_fetched":1711715323.932722},"376390299":{"manifest":{"name":"KNMI"},"description":"Custom component that integrates KNMI weather service (via weerlive) in to Home Assistant","domain":"knmi","etag_releases":"W/\"0ce807f4174c8f736ddec405c1666afc5ee01ad91e7b75e954170f5f5410024c\"","etag_repository":"W/\"c4684997262fdb42c37085da6246998e70565003c4f16f5ce330816b2dc3197d\"","full_name":"golles/ha-knmi","last_commit":"02be2fd","last_updated":"2024-03-18T21:09:47Z","last_version":"2.0.1","manifest_name":"KNMI","open_issues":3,"stargazers_count":88,"topics":["home-assistant-component","home-assistant-integration","knmi","weather","weerlive"],"last_fetched":1712147152.7404},"392188182":{"manifest":{"country":["ru"],"name":"\u041b\u0438\u0447\u043d\u044b\u0439 \u043a\u0430\u0431\u0438\u043d\u0435\u0442 \u042d\u043d\u0435\u0440\u0433\u043e\u0441\u0431\u044b\u0422 \u041f\u043b\u044e\u0441"},"description":"\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u042d\u043d\u0435\u0440\u0433\u043e\u0441\u0431\u044b\u0422.\u041f\u043b\u044e\u0441 \u0434\u043b\u044f Home Assistant","domain":"energosbyt_plus","etag_releases":"W/\"e514e960332c1b018e0b7f434af87649983417b9fec308bc12aec34690d0e14b\"","etag_repository":"W/\"558405180af8aca70f472093c6f71d399dc33c16af2f691f0a5fd636ac7513e6\"","full_name":"alryaz/hass-energosbyt-plus","last_commit":"8a29919","last_updated":"2023-07-08T12:41:56Z","last_version":"v0.1.0","manifest_name":"Energosbyt Plus Personal Cabinet","open_issues":5,"stargazers_count":12,"topics":["energosbyt","energosbyt-plus"],"last_fetched":1705911485.484811},"521964078":{"manifest":{"country":["DE"],"name":"Rewe Discounts"},"description":"Rewe Discounts Homeassistant Integration","domain":"rewe","etag_releases":"W/\"e27a9764ae5aab02c964161682120cc6d47c1ac2dcae5a2689000509fa829e8b\"","etag_repository":"W/\"8131166c2a1fe5efc8ca5fd5b4f0204dcaf9a742696b3b0304778f28205b81b8\"","full_name":"FaserF/ha-rewe","last_commit":"9b3ee4f","last_updated":"2024-03-27T11:50:30Z","last_version":"2024.03.0","manifest_name":"Rewe Discounts","open_issues":5,"stargazers_count":16,"last_fetched":1711548929.359787},"243841075":{"manifest":{"name":"CS:GO game state"},"description":"CS:GO gamestate reporting to Home Assistant","domain":"csgo_gamestate","etag_releases":"W/\"a5d458dac2ae13280cf1f97e8a7255622515bd2edf3546deb3c89d1af294b71c\"","etag_repository":"W/\"e3dda8cc37ff38fceb573f6b7d1e78fce27af54d07719a27af92947e12ec6847\"","full_name":"lociii/homeassistant-csgo","last_commit":"47429d6","last_updated":"2023-01-31T09:51:08Z","last_version":"2.0.0","manifest_name":"CS:GO game state listener","open_issues":1,"stargazers_count":17,"last_fetched":1696645373.524021},"193588464":{"manifest":{"country":["PL"],"name":"Rozk\u0142adzik sensor"},"description":"This sensor uses unofficial API to get data from https://www.rozkladzik.pl and provide information about departures for chosen stop.","downloads":283,"domain":"rozkladzik","etag_releases":"W/\"4362b28cf0e6c48f4795cd121d5bd38782c25740d12a5b5c4018438a72a373e1\"","etag_repository":"W/\"b6f6654be54e1fd841a48ec2068e32bc71790d3643e1e26657ba14607c33e4a1\"","full_name":"PiotrMachowski/Home-Assistant-custom-components-Rozkladzik","last_commit":"27bc849","last_updated":"2023-09-18T16:14:28Z","last_version":"v1.1.5","manifest_name":"Rozk\u0142adzik","open_issues":6,"stargazers_count":10,"topics":["public-transport"],"last_fetched":1705328355.497709},"641757757":{"manifest":{"name":"Energy meter"},"description":"Provides extended features on top of utility-meter to track costs for each tariff as well as total costs","downloads":3109,"domain":"energy_meter","etag_releases":"W/\"b77a826a6134101c69181724d5bd4703ef8b04f0900027b9b879e439d0e461aa\"","etag_repository":"W/\"af1db82dd81262d2e52e0bdc40a4f005e75c0876c7712ce6e4ca1596a8215fbb\"","full_name":"zeronounours/HA-custom-component-energy-meter","last_commit":"6c3d1dc","last_updated":"2024-03-26T15:40:05Z","last_version":"v1.1.0","manifest_name":"Energy Meter","open_issues":7,"stargazers_count":15,"topics":["energy"],"last_fetched":1711477434.260775},"120696364":{"manifest":{"name":"OpenSprinkler integration for Home Assistant"},"description":"OpenSprinkler Integration for Home Assistant","domain":"opensprinkler","etag_releases":"W/\"573126833eda24ef6ed0cacf46206e8f45f44168ba03d5279c9de8f38f903b47\"","etag_repository":"W/\"cb9427bc08161bdfbc8f110c3747f3acb72e6dfb1baa08e3903a758481bc81ed\"","full_name":"vinteo/hass-opensprinkler","last_commit":"01f9156","last_updated":"2024-02-14T21:45:37Z","last_version":"v1.3.0","manifest_name":"OpenSprinkler","open_issues":16,"stargazers_count":181,"topics":["opensprinkler"],"last_fetched":1711729407.653813},"498861412":{"manifest":{"name":"Aquanta"},"description":"An unofficial Aquanta water heater controller integration for Home Assistant","downloads":113,"domain":"aquanta","etag_releases":"W/\"d0972685a43b7c643e645446e5a19712da353ea798c6c815e72a24a4c5995a1d\"","etag_repository":"W/\"121014f9364bc43b8438407f9097c76b9f6b3444458b0a258cd9fc4ccf46700e\"","full_name":"bmcclure/ha-aquanta","last_commit":"41e4013","last_updated":"2024-04-01T15:42:44Z","last_version":"v2.0.4","manifest_name":"Aquanta","open_issues":11,"stargazers_count":7,"topics":["hacs-custom","home-assistant-integration"],"last_fetched":1711988236.375597},"441942093":{"manifest":{"name":"keyatome"},"description":"Home Assistant component to handle key atome (linky) -conso live feature-","domain":"keyatome","etag_releases":"W/\"db0bf57d27301c1c0c9e113ee8f7baf03b5178c8dc711341a891c7356bf23844\"","etag_repository":"W/\"06f9ae45974be515d0786f5d484460a9ad5f6e60c19d0b9d5d446f58e42a1d6d\"","full_name":"jugla/keyatome","last_commit":"803b935","last_updated":"2024-02-26T23:25:04Z","last_version":"V7.4.2","manifest_name":"KeyAtome Linky","open_issues":4,"stargazers_count":24,"topics":["atome","keyatome","linky"],"last_fetched":1709842606.188162},"366713850":{"manifest":{"name":"Pirate Weather"},"description":"Replacement for the default Dark Sky Home Assistant integration using Pirate Weather ","domain":"pirateweather","etag_releases":"W/\"865f57b661c97ed0a5966ba2916c6ccdb9eaa3c437e5ea2326443684f5fcecc5\"","etag_repository":"W/\"7781c18a4d37381b5038d82f09fd71ec73a1b775576a9ea81c44003b3338f255\"","full_name":"Pirate-Weather/pirate-weather-ha","last_commit":"19de304","last_updated":"2024-04-01T21:56:17Z","last_version":"v1.4.5.1","manifest_name":"Pirate Weather","open_issues":9,"stargazers_count":315,"topics":["darksky-api","weather-api"],"last_fetched":1712082146.590727},"506356147":{"manifest":{"name":"Haier hOn"},"description":"Support of all Haier, Candy, Hoover appliances integrated in the official hOn mobile app. Direct access to all possible services and parameters","domain":"hon","etag_releases":"W/\"0a61a141fff9c1a15a951e40d88c5a35d3cda76743a6ed5b8a720fafa480bec7\"","etag_repository":"W/\"fefd2378194ff78e27b81e14b64011993ce6650cf78e410bc8818b297778692c\"","full_name":"gvigroux/hon","last_commit":"d607b52","last_updated":"2024-03-19T13:50:20Z","last_version":"0.6.16","manifest_name":"hOn","open_issues":7,"stargazers_count":116,"topics":["candy","haier","hon","hoover"],"last_fetched":1711635432.479053},"538235457":{"manifest":{"country":["ES"],"name":"ZTE tracker"},"description":"Device tracker for ZTE Routers in Home Assistant","domain":"zte_tracker","etag_releases":"W/\"f083508be4ecdd1f784835c9c89688dfc75b0e58dba3afd81fc7d4f93523434e\"","etag_repository":"W/\"c32b300348ab37683c988dc22e63a0519494aec71fed6ca1f15188336b31686e\"","full_name":"juacas/zte_tracker","last_commit":"eaf2f2a","last_updated":"2023-12-20T20:49:01Z","last_version":"v1.3.6","manifest_name":"ZTE router tracker","open_issues":3,"stargazers_count":11,"topics":["device-tracker","router"],"last_fetched":1708719525.504058},"279538782":{"manifest":{"name":"Ecodevices RT2"},"description":"Home Assistant custom component for GCE Ecodevices RT2","domain":"ecodevices_rt2","etag_releases":"W/\"e40a9a26a1004752e14fee4cb02948d2dcf1f6d60016760f71ee71b0c1a8ed99\"","etag_repository":"W/\"5b32213f8942518bfedfc33ce4d624adb80e41f38354f5f0ad6fa0f3b4a4a46b\"","full_name":"pcourbin/ecodevices_rt2","last_commit":"52ba80f","last_updated":"2023-10-31T09:09:04Z","last_version":"v2.2.7","manifest_name":"GCE Ecodevices RT2","open_issues":8,"stargazers_count":4,"last_fetched":1709634026.879216},"485281791":{"manifest":{"name":"HASS.Agent MediaPlayer"},"description":"HASS.Agent MediaPlayer integrations. Adds TTS and the ability to control local media to HASS.Agent - a Windows based client for Home Assistant.","domain":"hass_agent_mediaplayer","etag_releases":"W/\"eab54f6a495551070de8b5eb8ae7d274c8b2c380c32d8401cb5b06ad0ae5d12e\"","etag_repository":"W/\"e82cc14179c755d15041861f728076544c3c1edfd3b0189deb504ccef7a87813\"","full_name":"LAB02-Research/HASS.Agent-MediaPlayer","last_commit":"5d5559c","last_updated":"2022-11-17T13:28:30Z","last_version":"2022.10.26","manifest_name":"HASS.Agent MediaPlayer","open_issues":1,"stargazers_count":16,"last_fetched":1710944200.550218},"416059983":{"manifest":{"name":"Stiebel Eltron ISG"},"description":"Stiebel Eltron ISG integration for Home Assistant ","downloads":452,"domain":"stiebel_eltron_isg","etag_releases":"W/\"51cd7009091c8fb1156a562f74a612ef6926b6fb57929c9cca6b818c736e8058\"","etag_repository":"W/\"1cd379673c3d87dcd804b3fbd21300f38f1b28e0dca46fc4acec3e29ab65fb1a\"","full_name":"pail23/stiebel_eltron_isg_component","last_commit":"63d9627","last_updated":"2024-04-02T11:55:13Z","last_version":"2024.2.2","manifest_name":"Stiebel Eltron ISG","open_issues":9,"stargazers_count":35,"last_fetched":1712067481.502291},"442594482":{"manifest":{"country":["PL"],"name":"Kontomierz sensor"},"description":"A sensor that integrates all your bank balance gathered in kontomierz app","domain":"kontomierz_sensor","etag_releases":"W/\"dac6e7e09b1e75ca141cdfee4379edd0dac499c3c3b5cefb64dc9dd59ed87530\"","etag_repository":"W/\"155b1c2ad7fb0d372381bd7d2c0c7178ae2e2d1b4bae0f51c469dc9129002ae0\"","full_name":"pawelhulek/kontomierz-sensor","last_commit":"7e7862c","last_updated":"2022-03-10T06:49:41Z","last_version":"0.0.1","manifest_name":"Kontomierz Sensor","open_issues":2,"stargazers_count":6,"topics":["finance","financial-analysis","fintech","kontomierz"],"last_fetched":1705069114.878299},"232424544":{"manifest":{"name":"Bosch Smart Home Controller (SHC) integration"},"description":"Home Assistant component for accessing Bosch Smart Home Controller using boschshcpy python library.","domain":"bosch_shc","etag_releases":"W/\"892a4bbfcdb152c039c296b803f154279391eb15d43894986112c35433db18cb\"","etag_repository":"W/\"1abbc2a28ebd39079dc276002068000cd7673dc25104b9341d9a59642340c881\"","full_name":"tschamm/boschshc-hass","last_commit":"1d2aba9","last_updated":"2024-02-15T17:26:02Z","last_version":"0.4.88","manifest_name":"Bosch SHC","open_issues":32,"stargazers_count":141,"topics":["bosch-smart-home","boschshcpy","home-assistant-component"],"last_fetched":1712106144.840561},"566598076":{"manifest":{"name":"ikuai"},"description":"Home Assistant integration for iKuai Router","domain":"ikuai","etag_releases":"W/\"a1918260557cdd4ea503dc66e519b316b04348fd3bf805529330c04dfc2cc8c0\"","etag_repository":"W/\"9270335866ff0ccba82de6841583a5ebdce2d0345099e97bee1d95b978b1de4a\"","full_name":"dscao/ikuai","last_commit":"e6fa444","last_updated":"2023-09-12T18:33:46Z","last_version":"1.3.1","manifest_name":"ikuai","open_issues":1,"stargazers_count":43,"topics":["homeassistant-custom-component","ikuai"],"last_fetched":1711030484.003096},"691766596":{"manifest":{"name":"Venta"},"description":"Home assistant integration for Venta devices","domain":"venta","etag_releases":"W/\"d4786d7d3322743c31f6cd80509d746c88d6db98266b2d21cf9d962918c8e2fb\"","etag_repository":"W/\"e78a0ee6fbbbe82614c112a51d627b63051c2a0697b65b049b772743e815b71c\"","full_name":"Michsior14/ha-venta","last_commit":"a3ab203","last_updated":"2024-04-03T22:24:39Z","last_version":"v0.8.0","manifest_name":"Venta","stargazers_count":8,"topics":["venta"],"last_fetched":1712192501.657708},"552532860":{"manifest":{"country":["FI"],"name":"Seiverkot"},"description":"Add seiverkot consumption sensor to home assistant","domain":"seiverkot","etag_releases":"W/\"4e8251e23a129f30a0b7b09dd9befc291a430afd09bc4cd391138f19a4484167\"","etag_repository":"W/\"b160f1a007bdf4d78a1feb8aceca32758317697c696af80db059978421567eaf\"","full_name":"evantaur/seiverkot-consumption","last_commit":"624b575","last_updated":"2023-07-13T18:08:25Z","last_version":"v0.1.2","manifest_name":"Seiverkot","open_issues":1,"stargazers_count":3,"topics":["energy-consumption","energy-monitor","seinajoen-energia","seiverkot"],"last_fetched":1705529728.129845},"413680511":{"manifest":{"name":"Toyota (North America)"},"description":"Home Assistant integration for Toyota Motor (North America) connected services","downloads":387,"domain":"toyota_na","etag_releases":"W/\"5d6e5714d9c8529ac1fc7d3d98f9af77cae2d4ae37160ce358ee63e6acb313c1\"","etag_repository":"W/\"fc99b1665275e4ecb0cece553eb133a1b6df46a48b8c94d34d62ac6c01a905f4\"","full_name":"widewing/ha-toyota-na","last_commit":"290b286","last_updated":"2024-03-20T05:17:53Z","last_version":"v2.2.0","manifest_name":"Toyota (North America)","open_issues":27,"stargazers_count":56,"topics":["car","toyota","vehicle"],"last_fetched":1712192656.640306},"461906076":{"manifest":{"name":"Raspberry Pi RF"},"description":"Home Assistant Raspberry Pi GPIO RF Integration","domain":"rpi_rf","etag_releases":"W/\"7f8c88306930eaf3a09abf30d6177ec77b209683ffbd6ef69da08367c70b1978\"","etag_repository":"W/\"b9c0d89c270afb0cd5c5998c5920643a4117ae1a3fb51f27fed96be8f1b989cd\"","full_name":"markvader/ha-rpi_rf","last_commit":"1c3c3e6","last_updated":"2023-10-23T20:04:22Z","last_version":"2022.9.1","manifest_name":"Raspberry Pi RF","open_issues":10,"stargazers_count":29,"topics":["home-assistant-component","rpi-gpio","rpi-rf"],"last_fetched":1712046084.318205},"294037465":{"manifest":{"name":"Dual Smart Thermostat"},"description":"The `dual_smart_thermostat` is an enhaced verion of generic thermostat implemented in Home Assistant. It uses several sensors and dedicated switches connected to a heater and air conditioning under the hood.","domain":"dual_smart_thermostat","etag_releases":"W/\"0684d0d8999819a1536cd906a52dce5ab0f6c8d6530e23709bec5027442525ee\"","etag_repository":"W/\"3d5335ec4f242ecae4dc7a2bbaece85a4a57b123668f314356f8e08b657274ca\"","full_name":"swingerman/ha-dual-smart-thermostat","last_commit":"112eae2","last_updated":"2024-04-01T07:48:05Z","last_version":"v0.9.4","manifest_name":"Dual Smart Thermostat","open_issues":10,"stargazers_count":89,"topics":["thermostat"],"last_fetched":1712175753.251361},"201445202":{"manifest":{"country":["NL"],"name":"ACV garbage collection sensor"},"description":"\ud83d\uddd1\ufe0f Integration for bin/waste collection by acv-groep","domain":"acv","etag_releases":"W/\"4ff22ca5e08f73fd4c2ee0ee600fd0961935e172ecebe0099f9d20e27ceff71f\"","etag_repository":"W/\"6a0a102b450af87df095fcaab0db9c7c00e60f87352ab7a9c81da69bd563f1a4\"","full_name":"Cadsters/acv-hass-component","last_commit":"4d41aad","last_updated":"2022-05-30T13:17:35Z","last_version":"v0.24.4","manifest_name":"ACV garbage collection sensor","stargazers_count":4,"topics":["acv-groep","python3","trash","waste"],"last_fetched":1696702567.255732},"378010382":{"manifest":{"country":["ru"],"name":"\u041b\u0438\u0447\u043d\u044b\u0439 \u043a\u0430\u0431\u0438\u043d\u0435\u0442 \u0422\u041d\u0421 \u042d\u043d\u0435\u0440\u0433\u043e"},"description":"TNS Energo Integration","domain":"tns_energo","etag_releases":"W/\"02633287f8ab3f29784891cf7cfd2ac2aa7541d11e5b736049604e9d34bf63d7\"","etag_repository":"W/\"7ae8d30961ca372900c3872a1eaca39a843cbb1604d1c0489cffe6948fc888a2\"","full_name":"alryaz/hass-tns-energo","last_commit":"3b3254e","last_updated":"2023-06-19T07:51:16Z","last_version":"v0.1.1","manifest_name":"TNS Energo Personal Cabinet","open_issues":8,"stargazers_count":13,"topics":["moscow","tns-energo"],"last_fetched":1704767281.402114},"439944813":{"manifest":{"name":"Miele"},"description":"A modern integration for Miele devices in Home Assistant","downloads":5013,"domain":"miele","etag_releases":"W/\"78e5ed019df8c96fc747e43afbeba02b21448237c29676a4836cbc8881b9e92c\"","etag_repository":"W/\"94f08783dd223fb84518811e75be478115f0c98905305831cd3f3a63f07df664\"","full_name":"astrandb/miele","last_commit":"a830a6f","last_updated":"2024-03-25T15:42:08Z","last_version":"v2024.3.0","manifest_name":"Miele","open_issues":24,"stargazers_count":148,"topics":["miele"],"last_fetched":1712132202.935765},"202322117":{"manifest":{"name":"open_route_service"},"description":"Custom Component for Homeassistant Providing Travel Time Information using openrouteservice.org","domain":"open_route_service","etag_releases":"W/\"b11471e39703dbb8c1f602faaa2733531ea07223e33728a276e88d950052cea2\"","etag_repository":"W/\"d144157178a4e4e9ec978c3edf53b887afe8e947d1c7ca7d19cec97e193757fa\"","full_name":"eifinger/open_route_service","last_commit":"5e1a71b","last_updated":"2024-03-20T16:59:28Z","last_version":"v1.1.1","manifest_name":"Open Route Service travel time","open_issues":1,"stargazers_count":12,"topics":["open-route-service","python3"],"last_fetched":1711995486.280047},"522245338":{"manifest":{"name":"Checkly"},"description":"Home Assistant Integration for Checkly","domain":"checkly","etag_repository":"W/\"017c17cd7d0f45d07a9e10cb69a43bbc066047d166b16c52b300c9cf2826cb00\"","full_name":"ndom91/homeassistant-checkly","last_commit":"5ea1aae","last_updated":"2022-12-18T23:34:44Z","manifest_name":"Checkly","open_issues":1,"stargazers_count":6,"topics":["checkly"],"last_fetched":1709634005.687076},"257104502":{"manifest":{"country":["HU"],"name":"FKF Budapest Garbage Collection"},"description":"FKF Budapest Garbage Collection custom component for Home Assistant","domain":"fkf_garbage_collection","etag_releases":"W/\"c9399efdcb7c1cb87f8844898eb307e89e30e1b6c8ceba0fc11cff3b445e81e5\"","etag_repository":"W/\"d78f3d506bc7e5bf51fb7c08047778d6699b29956bf2e77c9fe8acd8f8402d39\"","full_name":"amaximus/fkf-garbage-collection","last_commit":"5273497","last_updated":"2024-04-02T08:35:40Z","last_version":"0.8.9","manifest_name":"FKF Budapest Garbage Collection","open_issues":2,"stargazers_count":21,"topics":["budapest","hungary"],"last_fetched":1712052885.620194},"154845921":{"manifest":{},"description":"SSH Generic Sensor","domain":"ssh","etag_releases":"W/\"1bea69b6756c3ae15644f9256ca2c90f004ed68a6338d75e44aa0d15b4bc4ec5\"","etag_repository":"W/\"984d25d2e014c1369a37d9e2fa82e10eede9ddfc0fd402f7b4b4471d35d4541c\"","full_name":"custom-components/sensor.ssh","last_commit":"6eb1bce","last_updated":"2023-06-20T20:26:28Z","last_version":"1.15","manifest_name":"ssh sensor","open_issues":15,"stargazers_count":42,"last_fetched":1708798578.846972},"291484700":{"manifest":{"name":"Xiaomi Gateway 3"},"description":"Home Assistant custom component for control Xiaomi Multimode Gateway (aka Gateway 3), Xiaomi Multimode Gateway 2, Aqara Hub E1 on default firmwares over LAN","domain":"xiaomi_gateway3","etag_releases":"W/\"a920af0777c3bf167d474ae64f5180716172c7d26a49ae3b293cb76596519978\"","etag_repository":"W/\"3184f3e50f35e2aea1887158753836b63a527dce958fcfa4c1544df8aea54ff7\"","full_name":"AlexxIT/XiaomiGateway3","last_commit":"23e0055","last_updated":"2024-04-04T08:51:20Z","last_version":"v4.0.1","manifest_name":"Xiaomi Gateway 3","open_issues":73,"stargazers_count":2287,"topics":["aqara","ble","matter","mesh","mihome","xiaomi","zha","zigbee","zigbee2mqtt"],"last_fetched":1712225593.103227},"261311061":{"manifest":{"name":"Ecowitt Weather Station"},"description":"Ecowitt Weather Station integration for homeassistant","domain":"ecowitt","etag_releases":"W/\"7d7b83112cbbedb9bd217281c471fa0e2e6e0d0a395799f73a2704b1425d327a\"","etag_repository":"W/\"e366a0c6aa2051d3c6c268b5d895f2b8e1af501551d374fa1388bea9449ea2f4\"","full_name":"garbled1/homeassistant_ecowitt","last_commit":"3ad3e03","last_updated":"2023-05-05T15:38:45Z","last_version":"0.7","manifest_name":"Ecowitt Weather Station","open_issues":84,"stargazers_count":141,"topics":["ecowitt"],"last_fetched":1711217838.808117},"326288498":{"manifest":{"name":"worldtidesinfocustom"},"description":"world tides info custom component for home assistant","domain":"worldtidesinfocustom","etag_releases":"W/\"155d2ae728a08ea0e909f7707c3cc9356a0c6b92c2f78e6f2bb20ad048ae72eb\"","etag_repository":"W/\"ea5d50d73115cbe12699f32df106f11d4712f6c527c0530e618685d0e466d0d0\"","full_name":"jugla/worldtidesinfocustom","last_commit":"a23196b","last_updated":"2024-02-26T22:58:40Z","last_version":"V13.0.0","manifest_name":"WorldTidesInfoCustom","open_issues":4,"stargazers_count":21,"topics":["tides","worldtides"],"last_fetched":1710419240.288628},"600885053":{"manifest":{"name":"MyVaillant"},"description":"Home Assistant component for the myVAILLANT API, controls Vaillant devices such as aroTHERM heatpumps and ecoTEC boilers","domain":"mypyllant","etag_releases":"W/\"c480e4d976f425a546252f72b7511a6b4d4ac886e33f89ace4c2b02efe8765ba\"","etag_repository":"W/\"3ee84291af942b68a1dbe99e81a4f11a833b22fd8087dcba28afa221dbdb484c\"","full_name":"signalkraft/mypyllant-component","last_commit":"ae2bec5","last_updated":"2024-03-25T10:19:15Z","last_version":"v0.8.2","manifest_name":"myVAILLANT","open_issues":22,"stargazers_count":93,"topics":["home-assistant-component","vaillant"],"last_fetched":1712082204.202451},"356030453":{"manifest":{"country":["US"],"name":"remote_syslog"},"description":"Home Assistant Custom Component - send Syslog message to remote server.","domain":"remote_syslog","etag_releases":"W/\"79639ec9b7d608e1b7dc4dd772769b81b6056e94ccb9df0cd732a23d07cb466f\"","etag_repository":"W/\"3249e2e0cad0d2ae6b8e44317ab5e1d4a2cb805f4c43ae3fde3feaf9f1b619a0\"","full_name":"TheByteStuff/RemoteSyslog_Service","last_commit":"bd5bb81","last_updated":"2023-02-23T15:41:24Z","last_version":"2022-11-16","manifest_name":"Remote Syslogger","open_issues":1,"stargazers_count":14,"topics":["syslog","syslog-client"],"last_fetched":1700497535.99731},"330644825":{"manifest":{"name":"Google Home"},"description":"Home Assistant Google Home custom component ","domain":"google_home","etag_releases":"W/\"536268ac7dc39f7c6ce125e4edca9f958c0bc2c1dd48ff75a7abfd5552597030\"","etag_repository":"W/\"c992fe94dd89f882c4bea52c4c9aeb5e3b644ee913761bee45b531a45b1dfc5e\"","full_name":"leikoilja/ha-google-home","last_commit":"e186ca7","last_updated":"2024-04-03T15:12:00Z","last_version":"v1.11.0","manifest_name":"Google Home","open_issues":25,"stargazers_count":394,"topics":["google-assistent","google-home"],"last_fetched":1712168448.451456},"552426092":{"manifest":{"name":"HeishaMon"},"description":"An integration for heatpumps handled by heishamon","domain":"aquarea","etag_releases":"W/\"0f7511b3505a5fee3ecf6982189e08dafcdf1fe04d9ced699eecbb64a9207b1f\"","etag_repository":"W/\"3e7f9f1b64141d63ea818272dbabbeaa5d5857d544a35f057782cf366131caab\"","full_name":"kamaradclimber/heishamon-homeassistant","last_commit":"0ac5769","last_updated":"2024-02-10T13:17:16Z","last_version":"1.7.3","manifest_name":"HeishaMon","open_issues":7,"stargazers_count":32,"topics":["heatpump","heishamon","mqtt"],"last_fetched":1711628887.833498},"316527506":{"manifest":{"name":"Winix Purifier"},"description":"Home Assistant component for C545 Winix Air Purifier","domain":"winix","etag_releases":"W/\"1b1ce25419ac63901ac0dfebf9a43a9af49760119474c84aa629eac5ffdc5a9a\"","etag_repository":"W/\"6d36ce26f37d34dfc4b15c58ff0caa4c1fe598a215a9f4e1f368ffde8e0b70b9\"","full_name":"iprak/winix","last_commit":"8c244ae","last_updated":"2024-02-17T23:40:43Z","last_version":"v1.1.5","manifest_name":"Winix Air Purifier","open_issues":3,"stargazers_count":88,"topics":["purifier","winix"],"last_fetched":1712161153.20176},"639503073":{"manifest":{"country":["fr"],"name":"Atmo France"},"description":"About Home assistant component to get air quality for french cities","domain":"atmofrance","etag_releases":"W/\"eb487cb6fee8c91c22cd745f6331a0009c5cddd820268649e436e8622bfb78db\"","etag_repository":"W/\"e1ff4aae01cf7d5672c62e37590f6f52853c45ebe77f4ae7a1babbab31662746\"","full_name":"sebcaps/atmofrance","last_commit":"bb635d2","last_updated":"2024-01-06T18:12:37Z","last_version":"v1.0.5","manifest_name":"Atmo France","open_issues":2,"stargazers_count":4,"topics":["pollution-levels"],"last_fetched":1712019902.397952},"379781545":{"manifest":{"name":"Netgear WAX"},"description":"Netgear Home Assistant Integration","domain":"netgear_wax","etag_releases":"W/\"9a2ff2b615bee4d31517e3ad273f3f5d85e8643acee646b7cba3e238d10bb6e1\"","etag_repository":"W/\"31d23244b23c1c55f8edac67bfd4fcf18c74fc1af70215b57b6116b4f3016c0f\"","full_name":"rroller/netgear","last_commit":"afe3bfc","last_updated":"2024-02-08T05:02:14Z","last_version":"0.1.6","manifest_name":"Netgear WAX","open_issues":2,"stargazers_count":13,"topics":["netgear","wax","wax-610","wax-620","wi-fi"],"last_fetched":1708755699.359987},"284006518":{"manifest":{"name":"Bonaire MyClimate"},"description":"Reverse engineered implementation of the Bonaire MyClimate app.","domain":"bonaire_myclimate","etag_releases":"W/\"ed1ca3eb464330fb41f0113261b9990c1676f317d214653dab9af1df89efa5c5\"","etag_repository":"W/\"6f41e77d2b68e21d2952072aa919e9aeeccda934135760f654263673acafaf03\"","full_name":"bremor/bonaire_myclimate","last_commit":"b94ea3b","last_updated":"2023-11-08T20:58:36Z","last_version":"1.2.1","manifest_name":"Bonaire MyClimate","open_issues":9,"stargazers_count":17,"topics":["bonaire","bonaire-myclimate","climate","myclimate"],"last_fetched":1706530995.026549},"159080189":{"manifest":{"name":"Drayton Wiser Integration for Home Assistant"},"description":"Platform and related climate/sensors to support the Drayton Wiser Home Heating System","downloads":1495,"domain":"wiser","etag_releases":"W/\"4e00cb8d076e686dc68a9b1d7ca89e0fab1d402e3f9425e2fcac44bae13bb3e9\"","etag_repository":"W/\"d4db4e4050f7b60e8a6671f07d31fcc80c0a7ee28bdaf7e7ed360df0a036f3c8\"","full_name":"asantaga/wiserHomeAssistantPlatform","last_commit":"8277c74","last_updated":"2024-03-10T13:51:06Z","last_version":"v3.4.6","manifest_name":"Drayton Wiser Integration for Home Assistant","open_issues":11,"stargazers_count":212,"topics":["drayton","heating","wiser"],"last_fetched":1712225619.343593},"536765576":{"manifest":{"country":["fr"],"name":"My EcoWatt by RTE"},"description":"A home assistant component for ecowatt api exposed by french company RTE","domain":"rte_ecowatt","etag_releases":"W/\"c6be5efbc51c3e23672997c2f3451953ecaefe8c93ac50785882203cfdb13205\"","etag_repository":"W/\"3a46f9fb946c77596a506f70ebefddb172623c6f2c72c84121aa49dddb3e9f45\"","full_name":"kamaradclimber/rte-ecowatt","last_commit":"1187c6c","last_updated":"2024-01-27T11:06:07Z","last_version":"0.9.2","manifest_name":"My EcoWatt by RTE","open_issues":2,"stargazers_count":60,"topics":["electricity","rte"],"last_fetched":1712009832.102873},"512213802":{"manifest":{"name":"Cecotec Conga 5290"},"description":"Cecotec Conga - Custom Component for Home Assistant","domain":"cecotec_conga","etag_releases":"W/\"6d64f8d3c2b1b6c946918a6f28e7e5e1c343299e203b3ace6288f921212a8f86\"","etag_repository":"W/\"1f40c8fe8d3a772d160b46d3ba5676951690c9d8bc5c29adff92430dcd002321\"","full_name":"alemuro/ha-cecotec-conga","last_commit":"97e1756","last_updated":"2023-07-01T09:09:09Z","last_version":"v0.10.0","manifest_name":"Cecotec Conga 5290","open_issues":7,"stargazers_count":6,"topics":["automation","cecotec","conga"],"last_fetched":1705839745.483418},"145777833":{"manifest":{},"description":"\ud83d\udcb5 Personal Capital Integration for Bank Account Monitoring","domain":"personalcapital","etag_releases":"W/\"c52475738cde278f456294d92790df50ff624b128023e416cb577ee8d028b589\"","etag_repository":"W/\"3c8b04f92569347c36165512670d92daa1c65d85372c07256e030a6ed3ef2be7\"","full_name":"custom-components/sensor.personalcapital","last_commit":"5aff625","last_updated":"2023-04-14T05:56:48Z","last_version":"0.1.2","manifest_name":"Personal Capital","open_issues":2,"stargazers_count":14,"last_fetched":1707267266.147778},"443905243":{"manifest":{"name":"Xplora\u00ae Watch"},"description":"Xplora\u00ae Watch Home Assistant Integration","downloads":613,"domain":"xplora_watch","etag_releases":"W/\"f0045e1a3ab33339c132492410f1644eef615d09d5222db15c6e02ab8c03bed9\"","etag_repository":"W/\"23739586f8131abf602c379fd1e44602061508c1b9982511ee9788569fb10f6c\"","full_name":"Ludy87/xplora_watch","last_commit":"f3e6cb6","last_updated":"2024-04-04T00:56:53Z","last_version":"v2.13.7","manifest_name":"Xplora\u00ae Watch","open_issues":5,"stargazers_count":44,"topics":["devicetracker","hassio-addons","hassio-integration","hassos","homeassistant-custom-component","notify","watch","xplora","xplora-watch"],"last_fetched":1712192480.533985},"398781181":{"manifest":{"name":"Candy Simply-Fi"},"description":"Unofficial Candy/Haier appliance integration for Home Assistant ","domain":"candy","etag_releases":"W/\"09ea58ff6e576ad50be39b862643ed27d216a0598e50d8fe550b4cd5e34aa83d\"","etag_repository":"W/\"189fd3b8c9811ff28cecc4a1bfc98279fd05d5f0bc178f8f6869afafade3b5aa\"","full_name":"ofalvai/home-assistant-candy","last_commit":"42e6f1c","last_updated":"2023-09-14T23:30:56Z","last_version":"0.8.2","manifest_name":"Candy","open_issues":21,"stargazers_count":115,"topics":["candy","haier","home-assistant-component","home-assistant-integration"],"last_fetched":1710944284.311213},"327695137":{"manifest":{"name":"Kodi Media Sensors"},"description":"Custom component to feed multiple sensors in Home Assistan and so custom cards can be to display those sensors. This repository is a fork of https://github.com/boralyl/kodi-recently-added","domain":"kodi_media_sensors","etag_releases":"W/\"237522df512e39ede0fae791f475bd26d18fa2883434c384d546b8d85454c6f8\"","etag_repository":"W/\"00087625eb7a509fa63f92fe6d990b17613bafedcf06fe1cb559357096854371\"","full_name":"jtbgroup/kodi-media-sensors","last_commit":"4db97bc","last_updated":"2024-02-08T05:59:13Z","last_version":"5.3.0","manifest_name":"Kodi Media Sensors","open_issues":2,"stargazers_count":11,"topics":["home-assistant-component","homeassistant-custom-component","kodi","playlist","playlists","pyth"],"last_fetched":1709928972.897212},"658074877":{"manifest":{"country":["DE","PT","SK","US"],"name":"IPv64"},"description":"IPv64.net | Free DynDNS2 & Healthcheck Service Home Assistant Integration","downloads":429,"domain":"ipv64","etag_releases":"W/\"6f916c9ca935216474faeed239d32ed56f847007748e4673363e0473946e693b\"","etag_repository":"W/\"fc700694fa108f1fda9431409d4efa7423a7bce4799451e9356e6c6f093f3a58\"","full_name":"Ludy87/ipv64","last_commit":"a37adf0","last_updated":"2024-04-04T00:33:31Z","last_version":"1.7.0","manifest_name":"IPv64","open_issues":2,"stargazers_count":6,"topics":["dyndns","hassio-integration","hassos","home-assistant-component","ipv4","ipv6","ipv64","rpicloud"],"last_fetched":1712192480.482725},"179347477":{"manifest":{"name":"Circadian Lighting"},"description":"Circadian Lighting custom component for Home Assistant","domain":"circadian_lighting","etag_releases":"W/\"651f35d98c680771ec66ac97294867a8034b23b1ffbae8d69241034bfad42ab6\"","etag_repository":"W/\"aa093f96d6fe1fd36d233f9e06dc03565e7389e14c07438d2b1bf6b2829fb17b\"","full_name":"claytonjn/hass-circadian_lighting","last_commit":"2f87bda","last_updated":"2024-03-29T00:53:55Z","last_version":"2.1.4","manifest_name":"Circadian Lighting","open_issues":99,"stargazers_count":742,"topics":["circadian","circadian-rhythms","lighting","sleep","wellness"],"last_fetched":1712009648.693528},"668344544":{"manifest":{"name":"Linktap Local"},"description":"A Custom Component that uses the linktap local HTTP API","domain":"linktap","etag_releases":"W/\"0125f23d1f886c7c961a9e8abe730a6984090ee1ddd146409b395991be0856b1\"","etag_repository":"W/\"776e02dc64fdbd967bf822b36a5f657369800a4001287b19d178ac41622c6226\"","full_name":"sh00t2kill/linktap_local_http_component","last_commit":"50b6371","last_updated":"2024-03-08T03:57:24Z","last_version":"v0.5.3","manifest_name":"Local HTTP API for Linktap","open_issues":1,"stargazers_count":18,"topics":["linktap"],"last_fetched":1711933652.01516},"334364176":{"manifest":{"name":"WEBFLEET"},"description":"Homeassistant WEBFLEET integration to be installed via HACS.","domain":"webfleet","etag_repository":"W/\"10f4acaecdda8a99f1255861e89dda1e773b5fb1a31c565a799e8672f7233d83\"","full_name":"tom-winkler/ha-webfleet-integration","last_commit":"c148d1f","last_updated":"2023-03-13T07:57:06Z","manifest_name":"WEBFLEET","open_issues":3,"last_fetched":1705522942.334909},"295123287":{"manifest":{"name":"Jewish Sabbaths Holidays / sensor"},"description":"Jewish Shabbat Yomtov and Holidays times and event","domain":"hebcal","etag_releases":"W/\"5da7719fba5a23029535e604cfc8c53b01bc9fbda81a1d6d1fb592441c3ac72c\"","etag_repository":"W/\"075d52a988fb1142397be77d27c3e07db58123aa0df77523b61198ee5e32b046\"","full_name":"rt400/Jewish-Sabbaths-Holidays","last_commit":"0f5c4a4","last_updated":"2024-03-19T14:28:48Z","last_version":"2.2.0","manifest_name":"Jewish Sabbaths Holidays","open_issues":1,"stargazers_count":6,"topics":["holidays","jewish","shabbat"],"last_fetched":1711456228.609127},"650965476":{"manifest":{"name":"Cupra WeConnect"},"description":"Cupra integration for Home Assistant","domain":"cupra_we_connect","etag_releases":"W/\"e467f052e2aca7f90091897d53c710fcda1e091c1f59b7327a2d6f5b37614125\"","etag_repository":"W/\"aecbd8dcdcb18f49d2df35fb970fd1c185b98f8d48605eae0716f6d289bfd777\"","full_name":"daernsinstantfortress/cupra_we_connect","last_commit":"3c624f5","last_updated":"2024-01-15T13:26:16Z","last_version":"v0.8.0","manifest_name":"Cupra WeConnect","open_issues":8,"stargazers_count":34,"topics":["born","car","cupra","ev"],"last_fetched":1712002549.203753},"228627470":{"manifest":{"country":["NL"],"name":"HVCGroep"},"description":":recycle: :wastebasket: This component fetches garbage pickup dates for parts of The Netherlands using HVC Groep's REST API.","domain":"hvcgroep","etag_releases":"W/\"1a9f9bc81ee83a123ea7e9431741d99613c95f3e6d3df504ffcb2103991655ba\"","etag_repository":"W/\"f74a9b9326528db0aea708440b893b79083328c49d63c0efbebf30385a27254a\"","full_name":"cyberjunky/home-assistant-hvcgroep","last_commit":"7706be1","last_updated":"2024-01-06T12:17:53Z","last_version":"1.0.12","manifest_name":"HVCGroep Sensor","open_issues":1,"stargazers_count":11,"last_fetched":1708683358.56127},"232299868":{"manifest":{"name":"Sentio"},"description":"Custom component for Sentiotec sauna controller","downloads":1,"domain":"sentio","etag_releases":"W/\"d020ddfb17f2cd9e72f14b5fd68ef6906f448b7fc3d773309ebcd8bf78ed4d77\"","etag_repository":"W/\"4efca66c19145034b8cce8cc02da761e5c303a6784b8f0f8809dabefadacb160\"","full_name":"astrandb/sentio","last_commit":"91f66f0","last_updated":"2024-03-06T18:45:34Z","last_version":"v2024.3.0","manifest_name":"Sentio sauna","open_issues":1,"stargazers_count":4,"topics":["sentio","sentiotec"],"last_fetched":1709756056.655072},"425931056":{"manifest":{"country":["US","CA"],"name":"HA Kia/Hyundai"},"description":"A Home Assistant HACS integration that supports Kia Connect(Uvo). The integration supports the USA.","domain":"ha_kia_hyundai","etag_releases":"W/\"114fd341ef32368877bb4f992b47afc039656f4ff304025fcbab28ea4151eec2\"","etag_repository":"W/\"cc00d4701e3d650749741a1df445e0278abb9eebbec34971450a90b4fc4d0638\"","full_name":"dahlb/ha_kia_hyundai","last_commit":"87f5eac","last_updated":"2024-04-01T21:25:21Z","last_version":"v1.8.11","manifest_name":"Kia/Hyundai","open_issues":1,"stargazers_count":16,"topics":["car","kia","python3","uvo"],"last_fetched":1712009680.814474},"386049746":{"manifest":{"name":"Virage Dashboard"},"description":"A Home Assistant integration to keep track of Virage Laboratories devices, and set up and properly label rf sensors and door contacts","domain":"virage_dashboard","etag_releases":"W/\"484026eafcc5110239e433d925b9f48aea678e9d6f29fcb1c728819071b96a10\"","etag_repository":"W/\"303a573beecc3cd6bffcf1288990debf3bc7398b64bea613c2bebed14327807d\"","full_name":"viragelabs/virage_dashboard","last_commit":"bca831a","last_updated":"2022-10-23T18:48:35Z","last_version":"v1.2.0","manifest_name":"Virage Dashboard","stargazers_count":1,"topics":["virage","viragelaboratories","viragelabs"],"last_fetched":1678387630.473059},"260410453":{"manifest":{"name":"Panasonic Comfort Cloud"},"description":"Panasonic Comfort Cloud - Home Assistant Component","domain":"panasonic_cc","etag_releases":"W/\"42bcef0d12d75edb8b2e453afb843c1fd21f48554ec4767aade66e4e5d27b85d\"","etag_repository":"W/\"609c33049a22f5bd86c5898d53356fdac22ce7e18e3b60d5550756ad4c85af58\"","full_name":"sockless-coding/panasonic_cc","last_commit":"dcc449f","last_updated":"2024-02-25T08:22:00Z","last_version":"v1.0.38","manifest_name":"Panasonic Comfort Cloud","open_issues":96,"stargazers_count":100,"last_fetched":1711974715.775578},"511504216":{"manifest":{"name":"Scinan Saswell Thermostat"},"description":"Home Assistant integration for Scinan Thermostats","domain":"scinan_thermostat","etag_releases":"W/\"21485b2cd493c202e7cc4047351077e3cd7b816d194575cf2bca76836195cdaf\"","etag_repository":"W/\"fe6aae1433f9ae3549fdc1d582dc07f1a12cfec03c9b142fa89b5f768ee7b555\"","full_name":"Skarbo/hass-scinan-thermostat","last_commit":"76361e6","last_updated":"2023-08-20T22:06:43Z","last_version":"v1.1.2","manifest_name":"Scinan Thermostat","open_issues":2,"stargazers_count":6,"topics":["saswell","scinan","thermostat"],"last_fetched":1710519823.841626},"416883534":{"manifest":{"name":"Micronova Agua IOT"},"description":"Home Assistant integration controlling heating devices connected via the Agua IOT platform of Micronova","domain":"aguaiot","etag_releases":"W/\"d8189f0b978d13b79755265602098b77912430e7022393dc7285349c72f30508\"","etag_repository":"W/\"e879619568595cc78476cd813f85ca6abb80470ffac3ed0fb08c2f3f46d95253\"","full_name":"vincentwolsink/home_assistant_micronova_agua_iot","last_commit":"7d5ed37","last_updated":"2024-03-11T18:45:40Z","last_version":"v0.4.2","manifest_name":"Micronova Agua IOT","open_issues":4,"stargazers_count":20,"topics":["agua-iot","hacs-custom","home-assistant-component","home-assistant-integration","micronova","micronova-agua-iot"],"last_fetched":1711556709.825355},"716211438":{"manifest":{"name":"Notion ToDo"},"description":"ToDo Integration for Notion and HomeAssistant","downloads":272,"domain":"notion_todo","etag_releases":"W/\"b7be3b2c95f15a2cf3fb7ce35247f23dda0b07c1bdd6c01ce27e6b0b2ca6fa9c\"","etag_repository":"W/\"cfef7aab8be4e8edb87acd8ecdafc1bb93266127455fa6bf8f8e31923afeb9a9\"","full_name":"JanGiese/notion_todo","last_commit":"b86f5d3","last_updated":"2024-04-01T21:43:00Z","last_version":"1.1.1","manifest_name":"Notion ToDo","open_issues":4,"stargazers_count":7,"topics":["home-assistant-custom-component","notion-database"],"last_fetched":1712024790.671697},"259739166":{"manifest":{"name":"Octopus Agile"},"description":"Octopus Agile custom component for Home Assistant","domain":"octopusagile","etag_releases":"W/\"9696303bba1ee21d0c2d8c084fb6cd402c0d97cbc6dc73bdbe56fc0d3bbf007e\"","etag_repository":"W/\"57cf1f0e664ecef914e0e6e5864ee8d4e98d78a9f6b78e17718d53c83b3e1311\"","full_name":"markgdev/home-assistant_OctopusAgile","last_commit":"ac81e4a","last_updated":"2024-01-20T06:51:48Z","last_version":"v0.1.1","manifest_name":"octopusagile","open_issues":29,"stargazers_count":83,"topics":["energy","octopus","octopus-agile","octopus-energy"],"last_fetched":1711650067.080198},"432434646":{"manifest":{"name":"Securitas Direct Alarm"},"description":"This repository contains the new securitas direct API that can be integrated in Home Assistant","domain":"securitas","etag_releases":"W/\"d0a4b14b08eee7d530a5898550c02d47d3355558bb01ce8bfa4fa83ae4d284ae\"","etag_repository":"W/\"4657bb945993733deadf8b3527b8f594628e4585a4ec81ce46b0bc94c190e4d3\"","full_name":"guerrerotook/securitas-direct-new-api","last_commit":"090f022","last_updated":"2024-03-29T00:33:45Z","last_version":"v2.7.4.2","manifest_name":"Securitas Direct","open_issues":30,"stargazers_count":70,"last_fetched":1712175479.023411},"533014913":{"manifest":{"name":"EV Smart Charging"},"description":"Electric vehicle smart charging for Home Assistant.","downloads":1400,"domain":"ev_smart_charging","etag_releases":"W/\"73e217db33ba1c35c31090c74bebe7abc5569945166c42134890da61a6755a5d\"","etag_repository":"W/\"51f88e90e90151bc2c1d8e3ad43eb87ee26c6d74642ac2f5fbdc44998fb7a84a\"","full_name":"jonasbkarlsson/ev_smart_charging","last_commit":"c24a33c","last_updated":"2024-03-11T20:28:48Z","last_version":"v1.10.0","manifest_name":"EV Smart Charging","open_issues":31,"stargazers_count":126,"topics":["ev-charging"],"last_fetched":1712074852.435319},"188698828":{"manifest":{"country":["RU","BY"],"name":"Yandex Smart Home"},"description":"Adds support for Yandex Smart Home (Alice voice assistant) into Home Assistant","downloads":10197,"domain":"yandex_smart_home","etag_releases":"W/\"e8ea3e5d66a0aef4ca231425455236760f711d2d505bdc45250c205b788691aa\"","etag_repository":"W/\"12226340200de66939b37e7bdbea3485b96ee3d50bf5927ccc0afbf40bff285d\"","full_name":"dext0r/yandex_smart_home","last_commit":"ca72642","last_updated":"2024-03-29T21:10:28Z","last_version":"v0.6.10","manifest_name":"Yandex Smart Home","open_issues":27,"stargazers_count":716,"topics":["alice","home-assistant-component","voice-assistant","yandex"],"last_fetched":1711760113.088928},"487536666":{"manifest":{"name":"Nilan"},"description":"Nilan integration for Home Assistant","domain":"nilan","etag_releases":"W/\"30c9d8e6088eeb67410eb1b402437d70322158dc7ac2e3a49123e46b5c4be5d0\"","etag_repository":"W/\"d7d707785ad0bb25dc42bfab36feac7a28a397849f808787bf816aac98c15617\"","full_name":"veista/nilan","last_commit":"7ccb0a2","last_updated":"2024-02-25T19:02:06Z","last_version":"1.2.12","manifest_name":"Nilan","open_issues":3,"stargazers_count":40,"topics":["iot","modbus-tcp"],"last_fetched":1711988673.771941},"354887961":{"manifest":{"country":["GR"],"name":"Abalin Name Day"},"description":"Home Assistant custom component for the abalin name day API","domain":"abalin_nameday","etag_repository":"W/\"e8145003802cd85b1b58fc5c7eabdb8076934e2e9b6b9317fa2b2ef379fcef00\"","full_name":"viktak/ha-cc-abalin-nameday","last_commit":"5c82481","last_updated":"2022-02-24T10:30:22Z","manifest_name":"Abalin Name Day API","open_issues":1,"stargazers_count":6,"topics":["namedays"],"last_fetched":1708928702.869869},"402612874":{"manifest":{"name":"WeatherAPI"},"description":"HomeAssistant custom integration to fetch data from weatherapi","domain":"weatherapi","etag_releases":"W/\"f478cf0a3d32fbba92a7f042c17101aef2a166289e95bf94d7458e4d7cf7b24d\"","etag_repository":"W/\"6280b67a67ed48847fc132917949bf452879c325062aed4d2dee4d9c5d6b72f9\"","full_name":"iprak/weatherapi","last_commit":"cf02b4d","last_updated":"2023-12-06T11:15:55Z","last_version":"v1.1.2","manifest_name":"WeatherAPI","stargazers_count":8,"topics":["custom","weather","weatherapi"],"last_fetched":1701865685.913067},"124688531":{"manifest":{"name":"UPnP Availability"},"description":"UPnP Availability sensor for Home Assistant","domain":"upnp_availability","etag_repository":"W/\"c7733486e5dbfe7e668aa2a577698ed652a41275b4cdd53a719b9598a92c1ae4\"","full_name":"rytilahti/homeassistant-upnp-availability","last_commit":"e989772","last_updated":"2024-03-25T16:57:20Z","manifest_name":"UPnP Availability Sensor","open_issues":1,"stargazers_count":19,"topics":["ssdp","upnp"],"last_fetched":1711391042.703989},"187201747":{"manifest":{},"description":"rokid webhook component for Home Assistant (\u82e5\u742aHA\u7ec4\u4ef6)","domain":"rokid_webhook","etag_releases":"W/\"34b66b77dc69fa16e1e30c087a3545c87c40d1c6a11d1b3ebc0eae5fcb7ba2ee\"","etag_repository":"W/\"fe510d56db38f1ddcadc130a0e4b893403a95474f9517b4a0884b01fcac203a5\"","full_name":"jihao/rokid-webhook-hass","last_commit":"219d0b2","last_updated":"2022-02-15T08:44:30Z","last_version":"0.1.4","manifest_name":"rokid webhook","stargazers_count":13,"last_fetched":1703931392.406696},"261970408":{"manifest":{"name":"Weatherbit Weather Forecast for Home Assistant"},"description":"The weatherbit integration adds support for the weatherbit.io web service as a source for meteorological data for your location.","domain":"weatherbit","etag_releases":"W/\"4fbefce6de8b0dd4a7717162ccdef6aa174b43791be4101ba740f5aebf8e62a6\"","etag_repository":"W/\"3cbb8e2281624bce928407ccbcc8d0456823e6372254f31132a125ccd0f4cc5e\"","full_name":"briis/weatherbit","last_commit":"f0538ea","last_updated":"2024-01-06T08:57:44Z","last_version":"v1.0.21","manifest_name":"Weatherbit","open_issues":6,"stargazers_count":34,"topics":["meteorological-data","weather-forecast","weatherbit"],"last_fetched":1707841045.905759},"424574671":{"manifest":{"name":"SP110E RGB LED BLE Controller Integration"},"description":"Control SP110E RGB LED BLE Controller from Home Assistant","domain":"sp110e","etag_releases":"W/\"b8eb7cee805d08b705bceb195d74f93364edab793d5f2ecd222e2aae0f294836\"","etag_repository":"W/\"724091f0895b26793ad66e0b6c1778b078f6f630a90ecbe7e7e32932f9a5127c\"","full_name":"roslovets/SP110E-HASS","last_commit":"a47d0c5","last_updated":"2022-09-04T12:58:32Z","last_version":"v1.0.2","manifest_name":"SP110E RGB LED BLE Controller","open_issues":4,"stargazers_count":13,"topics":["ble","rgb","sp110e"],"last_fetched":1712192596.756144},"149443194":{"manifest":{"country":["US","CA"],"name":"ADT Pulse"},"description":"ADT Pulse sensor for Home Assistant","domain":"adtpulse","etag_releases":"W/\"300723be224ba3b97f38ec1fc1b15176fa016c13e1d5e1d9e9863d4d06d50ca9\"","etag_repository":"W/\"59528409f7e72f64f817582e8ac66249ca6114142b2395f256607eae0d6937ee\"","full_name":"rsnodgrass/hass-adtpulse","last_commit":"3a8b444","last_updated":"2024-03-07T06:33:06Z","last_version":"0.4.4","manifest_name":"ADT Pulse","open_issues":3,"stargazers_count":13,"topics":["adt-pulse"],"last_fetched":1712175710.795198},"443297453":{"manifest":{"country":["CN"],"name":"hasslife"},"description":"\u5929\u732b\u7cbe\u7075\u3001\u5c0f\u7231\u540c\u5b66\u63a7\u5236HomeAssistant\u8bbe\u5907\u548c\u5c5e\u6027\u4e0a\u62a5\u67e5\u8be2","domain":"hasslife","etag_releases":"W/\"e8f5af4a2fe36cdff10d5a8c66c6a93e297e569a617e3f033a4056fc6ffb0a40\"","etag_repository":"W/\"31d243cbefec3dceb1161418bca7e7bfb3def363055e36f800a6054bc25d6b95\"","full_name":"Blear/HassLife","last_commit":"29408cb","last_updated":"2024-03-18T04:04:15Z","last_version":"v2.1","manifest_name":"hasslife","open_issues":1,"stargazers_count":118,"topics":["miiot","tmall","tmall-genie"],"last_fetched":1711736177.090123},"234875951":{"manifest":{"country":["SE"],"name":"Securitas Home"},"description":"A Home Assistant custom component for Securitas Home Alarm, for alarms bought in Sweden before 2018-12-01","domain":"securitas","etag_releases":"W/\"4f1ef43101b1fb5885539c41db6dbded8ef236de93c1926ff346e3fcde0aab1d\"","etag_repository":"W/\"1c6951c06470bba77970a44dbc586d440072c4e30e95cd0d8b22f7fcb46a4429\"","full_name":"vlumikero/home-assistant-securitas","last_commit":"7b8ca5d","last_updated":"2021-07-24T17:58:21Z","last_version":"1.0.2","manifest_name":"Securitas","last_fetched":1678379827.008064},"334523683":{"manifest":{"name":"Teufel Raumfeld"},"description":"Integration for Teufel smart speaker (aka Raumfeld Multiroom) into https://www.home-assistant.io/.","downloads":906,"domain":"teufel_raumfeld","etag_releases":"W/\"3d597a17ca3295f0cb3486c49e74c08d25de636ac2d460d9f2f814f1399ba246\"","etag_repository":"W/\"9af32e8619541730caa75916687a53bbf68cd0c2ccc14cf8929f82fbaab1b3ce\"","full_name":"B5r1oJ0A9G/teufel_raumfeld","last_commit":"8e0f9fb","last_updated":"2023-08-25T17:39:18Z","last_version":"v0.1.15-alpha3","manifest_name":"Teufel Raumfeld","open_issues":9,"stargazers_count":26,"topics":["hassfeld","multiroom","multiroom-audio","raumfeld","smart-speaker","teufel"],"last_fetched":1710678121.301039},"451209586":{"manifest":{"country":["DK"],"name":"Flagdays DK"},"description":"\ud83c\udde9\ud83c\uddf0 Official flagdays in Denmark with a lot of useful logic and attributes. It is possible to add your own anniversaries \ud83c\udf82 or special flags \ud83c\udff3\ufe0f\u200d\ud83c\udf08 \ud83c\udff4\u200d\u2620\ufe0f","domain":"flagdays_dk","etag_releases":"W/\"7e7696f43f23daf2c6cb21ffe8e87cb14f9ab6bd2c9fb32de00dc635afe1fa39\"","etag_repository":"W/\"a398d2bbed34feafb65bef7d05f14968b0d0f07036ff64a50f03f23b266bc1c3\"","full_name":"J-Lindvig/Flagdays_DK","last_commit":"71ab1f9","last_updated":"2023-02-07T15:39:45Z","last_version":"v3.2","manifest_name":"FlagDays DK","open_issues":4,"stargazers_count":5,"topics":["anniversaries","denmark","flagdays","pride"],"last_fetched":1707181079.888591},"390073284":{"manifest":{"country":["US"],"name":"Sonos Cloud"},"description":"Sonos cloud API integration for Home Assistant with improved TTS/alerts handling","domain":"sonos_cloud","etag_releases":"W/\"51ea8437ceb7f58d0f4e8093c300165e24f3e6d4efceac3a5b4ab29906cbc9c8\"","etag_repository":"W/\"148b2c59b1836b25a0624d0fed39876caba829077213c042dc4270725ebae3c0\"","full_name":"jjlawren/sonos_cloud","last_commit":"c879ab5","last_updated":"2023-02-23T04:27:28Z","last_version":"0.3.5","manifest_name":"Sonos Cloud","open_issues":9,"stargazers_count":115,"topics":["sonos"],"last_fetched":1710348428.550562},"625369698":{"manifest":{"name":"FreeDS"},"description":"FreeDS integration for Home Assistant (read-only clone of gitlab repo)","domain":"freeds","etag_releases":"W/\"44c610c8bb4522928485d0542902cdf1c7058a3428d9654cfd273f94c2afbc49\"","etag_repository":"W/\"d3a538082317d180ecf77834a857ada3be772e3c162a194c4e8df6150d680da8\"","full_name":"IvanSanchez/homeassistant-freeds","last_commit":"76963e6","last_updated":"2023-09-24T17:31:59Z","last_version":"v0.12.0","manifest_name":"FreeDS","stargazers_count":7,"topics":["freeds"],"last_fetched":1709072217.263402},"708363868":{"manifest":{"name":"Tuya cloud vacuum map extractor"},"description":"Tuya cloud vacuum map extractor for Home Assistant","domain":"tuya_cloud_map_extractor","etag_releases":"W/\"5ea816562b214d0b4a9791136fb77cc0ff101f94d38caddaf051a5740a86047a\"","etag_repository":"W/\"60e98ceb836a01c74c9f4abcdba3466b4d3a609e66aa748d5d4b5a214b04fe86\"","full_name":"oven-lab/tuya_cloud_map_extractor","last_commit":"6c98981","last_updated":"2024-02-28T15:37:07Z","last_version":"v1.2.1","manifest_name":"Tuya Cloud Map Extractor","open_issues":17,"stargazers_count":15,"topics":["tuya","tuya-cloud","vacuum","vacuum-map"],"last_fetched":1712211740.095934},"136170574":{"manifest":{"country":["CN"],"name":"Photo captcha on Ezviz Camera for Home Assistant"},"description":"HomeAssistant \u8424\u77f3\uff08ezviz\uff09\u7ec4\u4ef6","domain":"myezviz","etag_repository":"W/\"be562c7a9863d48131c9407fc0b6e7253157dbf052b6af8d9b46731a9e948cc4\"","full_name":"c1pher-cn/homeassistan-ezviz","last_commit":"0d30a94","last_updated":"2023-08-09T03:29:04Z","manifest_name":"EZVIZ camera","stargazers_count":63,"topics":["camera","ezviz","myezviz"],"last_fetched":1711369391.099563},"318359434":{"manifest":{"name":"keymaster"},"description":"Home Assistant integration for managing Z-Wave enabled locks","downloads":3373,"domain":"keymaster","etag_releases":"W/\"6295aeeea170dc7a0bda3ac17bc51cc1afb263075ff906f6ca4dee0c0252c356\"","etag_repository":"W/\"df1c0152a3893aa053c2d7599e090ae6b2af9f7b9f8a6e0891823e2abfbbbdd3\"","full_name":"FutureTense/keymaster","last_commit":"f4f1046","last_updated":"2024-01-31T23:21:09Z","last_version":"v0.0.88","manifest_name":"keymaster","open_issues":28,"stargazers_count":204,"topics":["keymaster","locks","zwave","zwave-enabled-locks"],"last_fetched":1711700316.743589},"357338258":{"manifest":{"name":"Temperature Feels Like"},"description":"Sensor of Temperature Feels Like for Home Assistant.","downloads":1342,"domain":"temperature_feels_like","etag_releases":"W/\"ca18dacf334056e5a965ea29d1d212c244385da0624bc865680fb4c9214e98be\"","etag_repository":"W/\"f5ef104d3221e4327b92195eef468bb1633fc26dc04be9087e15268ac01dcb7d\"","full_name":"Limych/ha-temperature-feels-like","last_commit":"c75a77a","last_updated":"2024-03-18T09:08:01Z","last_version":"0.3.9","manifest_name":"Temperature Feels Like","open_issues":13,"stargazers_count":78,"topics":["home-assistant-climate","home-assistant-component","home-assistant-temperature","home-assistant-weather"],"last_fetched":1710757151.237311},"595397764":{"manifest":{"name":"Custom Templates"},"description":"This integration adds possibility to use new functions in Home Assistant Jinja2 templating engine.","downloads":1097,"domain":"custom_templates","etag_releases":"W/\"3a8620ec4e31bca57158dfbb97384fa1fee4cb26477c2efc1968e092ce4c4fd2\"","etag_repository":"W/\"de00956456cfabef95f1b1e4756778065217fc32d0f7b42d6282384bc670d730\"","full_name":"PiotrMachowski/Home-Assistant-custom-components-Custom-Templates","last_commit":"f4ba6ec","last_updated":"2024-03-26T14:25:06Z","last_version":"v1.3.0","manifest_name":"Custom Templates","open_issues":3,"stargazers_count":31,"topics":["jinja2","jinja2-templates"],"last_fetched":1711470162.701016},"220661494":{"manifest":{"country":["FR"],"name":"Orange Livebox routeur"},"description":"Livebox Component for Home assistant","domain":"livebox","etag_releases":"W/\"1e57fdad5f65b75e4ea3b50b48428bbf20acb05d5e6234fc1775bc341018d612\"","etag_repository":"W/\"3a7c9303e467692de56e8be11b0c8fbdbba4aa3dcafc8c6c0ccc6f33205c7366\"","full_name":"cyr-ius/hass-livebox-component","last_commit":"f82d3f3","last_updated":"2024-02-05T17:56:05Z","last_version":"2.2.7","manifest_name":"Orange Livebox","open_issues":3,"stargazers_count":48,"topics":["livebox","orange"],"last_fetched":1711933313.218792},"464877047":{"manifest":{"name":"Brink-Home Ventilation"},"description":"Brink-home ebus emodule home assistant integration","domain":"brink_ventilation","etag_releases":"W/\"e9eabb016c60e1cab02369729fa7335f84b9fb2998898e4febb3ef1359bdd279\"","etag_repository":"W/\"da5b6fbf9e687f4cb7b243115c1bd78be0e1d0902f4c494a4e4912a67497d422\"","full_name":"samuolis/brink","last_commit":"41c4491","last_updated":"2023-11-16T15:26:55Z","last_version":"1.6.3","manifest_name":"Brink-home Ventilation","open_issues":1,"stargazers_count":12,"topics":["brink","brink-home","brinkrenovent","ebus","emodule","renovent","ventilation"],"last_fetched":1708093159.464461},"190378093":{"manifest":{"name":"Visonic/Bentel/Tyco Alarm System"},"description":"Visonic/Bentel/Tyco Alarm System integrtation for Home Assistant","domain":"visonicalarm","etag_releases":"W/\"1397afd681c566f6970e766798c3afe1b2238adb8a8c714fe06d0ad6b372c316\"","etag_repository":"W/\"7f59ad08355223da829cca2f261ff48303d9afc0dc0c6cf5e0d828fe0e5f54db\"","full_name":"And3rsL/VisonicAlarm-for-Hassio","last_commit":"41e4d70","last_updated":"2023-07-13T11:02:26Z","last_version":"3.0.5","manifest_name":"Visonic/Bentel/Tyco Alarm System","open_issues":7,"stargazers_count":20,"topics":["alarm","alarm-control-panel","bentel","tycomonitor","visonic"],"last_fetched":1702937545.985565},"222118751":{"manifest":{"name":"Sonoff LAN"},"description":"Control Sonoff Devices with eWeLink (original) firmware over LAN and/or Cloud from Home Assistant","domain":"sonoff","etag_releases":"W/\"26c21ebb858125c773aeedcdb274df8c795f8d42de39d1ff11fb74e060b92770\"","etag_repository":"W/\"183ed8d74a930c186903d305e5ba784cb8df9c92046ff5860be28b188a78daa1\"","full_name":"AlexxIT/SonoffLAN","last_commit":"21b0afa","last_updated":"2024-04-03T05:08:47Z","last_version":"v3.6.0","manifest_name":"Sonoff","open_issues":108,"stargazers_count":2471,"topics":["ewelink","sonoff"],"last_fetched":1712175284.420853},"197920457":{"manifest":{},"description":"This is a library to allow communicating to a Midea appliance via the Midea cloud.","domain":"midea","etag_repository":"W/\"7d638c94b7db474a5045c6d2d15bddb2b7f58774e2335182fe3a791a38b47e1b\"","full_name":"andersonshatch/midea-ac-py","last_commit":"f779f3b","last_updated":"2023-03-09T19:28:42Z","manifest_name":"Midea Aircon","open_issues":25,"stargazers_count":78,"topics":["midea"],"last_fetched":1710339144.38388},"505066911":{"manifest":{"name":"Intex Spa"},"description":"Home Assistant integration for Intex Spa","downloads":375,"domain":"intex_spa","etag_releases":"W/\"7991de2a92e30728081758bb2eebfc139b85eb343fbdda82184ee58806610aa0\"","etag_repository":"W/\"2073146dedb485fc1476cfdb35614c958cec7adea8bed3919a41adb7d5d30906\"","full_name":"mathieu-mp/homeassistant-intex-spa","last_commit":"67752df","last_updated":"2024-04-04T10:15:47Z","last_version":"0.3.0","manifest_name":"Intex Spa","open_issues":7,"stargazers_count":24,"topics":["climate","intex","purespa","spa","switch"],"last_fetched":1712225909.502113},"555675718":{"manifest":{"country":["GB"],"name":"Mastertherm"},"description":"Home Assistant Mastertherm Component, to communicate and control heat pumps from Mastertherm","domain":"mastertherm","etag_releases":"W/\"00009e70f82ebe7b945bdab727580930a49d8545abc9f8934407b64b55cc701d\"","etag_repository":"W/\"74ccb4f27e21ea18289e4f0010c636f1d2b1c556fa44f8b4a7085fcfd18c3067\"","full_name":"sHedC/homeassistant-mastertherm","last_commit":"0979082","last_updated":"2024-04-01T14:28:33Z","last_version":"1.1.12","manifest_name":"Mastertherm","open_issues":5,"stargazers_count":5,"topics":["heatpump","mastertherm","python3"],"last_fetched":1711995794.775469},"173564471":{"manifest":{"name":"File restore"},"description":"Improved file sensor component that let you read the whole last line content.","domain":"file_restore","etag_releases":"W/\"85b74c22e0c8f5833dc971a112eb8f33249345208ab9adba98677bad431f3c48\"","etag_repository":"W/\"1dcf33672c9148aa19d30f5046c0717a76b355db81fb377fb779430ab840f742\"","full_name":"custom-components/sensor.file_restore","last_commit":"13d55a3","last_updated":"2024-01-10T09:24:36Z","last_version":"4.2","manifest_name":"File Restore","open_issues":1,"stargazers_count":11,"topics":["file-resotre","file-sensor","helper","planning","planning-temperature","temprature","thermostat"],"last_fetched":1711253854.906781},"194971711":{"manifest":{},"description":"A WillyWeather Australian Bureau of Meteorology (BoM) integration for Home Assistant","domain":"willyweather","etag_releases":"W/\"7b6f6ef55d3ed296c3c93062c26ce2c1fd4b5a217d085cf8f0b9a2df07616d9c\"","etag_repository":"W/\"a4431fc140078b0e80784885a23c10c032edf820f7501dcd4682e04500271b3b\"","full_name":"safepay/sensor.willyweather","last_commit":"7f072c5","last_updated":"2022-08-12T23:15:46Z","last_version":"v1.5.7","manifest_name":"WillyWeather","open_issues":5,"stargazers_count":15,"last_fetched":1703917334.594125},"228685436":{"manifest":{"name":"Toon Boiler Status"},"description":"This component reads and displays the boiler status values from a rooted Toon thermostat.","domain":"toon_boilerstatus","etag_releases":"W/\"d4d1f5c0d07b4bc381a38271b6675ed6c99ec1c097c6ae0b77775bd9455f505e\"","etag_repository":"W/\"7a912cd84d39af9ff3293695b56fd72d27de9c9182f8924315570e904369f100\"","full_name":"cyberjunky/home-assistant-toon_boilerstatus","last_commit":"e235c53","last_updated":"2024-01-02T15:32:52Z","last_version":"1.0.15","manifest_name":"Toon Boiler Status","stargazers_count":10,"topics":["cv","opentherm","toon"],"last_fetched":1705443258.790324},"211393677":{"manifest":{"name":"Qubino Wire Pilot"},"description":"Home Assistant Component for Qubino Wire Pilot","domain":"qubino_wire_pilot","etag_releases":"W/\"548bed2b36cf18c9f9e3247fa3199c6566f71071838263a6360a08ad3425467b\"","etag_repository":"W/\"129f889e686c3faabcf3c8ca89d2dc1f79e79b2e99aa96297cc7a09165431f62\"","full_name":"piitaya/home-assistant-qubino-wire-pilot","last_commit":"4591c67","last_updated":"2024-02-19T17:14:45Z","last_version":"2.0.4","manifest_name":"Qubino wire pilot","open_issues":2,"stargazers_count":20,"topics":["climate","qubino","qubino-wire-pilot","thermostat"],"last_fetched":1711155574.125129},"417802358":{"manifest":{"name":"TooGoodToGo"},"description":"TooGoodToGo items stock as sensor in Home Assistant","domain":"tgtg","etag_releases":"W/\"608f97b3f35f16b4985649519605172addc388034173e86890eba5087c782ed8\"","etag_repository":"W/\"c9c3e6bc26c3ce8b378de53c9c59bf289ffe5c87f2530d79a56e813dc71ad45c\"","full_name":"Chouffy/home_assistant_tgtg","last_commit":"8840186","last_updated":"2024-03-26T07:32:50Z","last_version":"5.4.2","manifest_name":"TooGoodToGo","open_issues":9,"stargazers_count":58,"topics":["home-assistant-integration","python3","toogoodtogo"],"last_fetched":1711673785.801208},"468093553":{"manifest":{"country":["HU"],"name":"Radioactivity Hungary"},"description":"Radioactivity data for Hungary","domain":"radioactivity_hu","etag_releases":"W/\"873214823f31b1f2b1ca0142fd895d8d07961aec4bf17bbd38168fbf045eca31\"","etag_repository":"W/\"388f830b14365dda5238904ebcaacafbf8f8457e89bca1383f101fc1551bc099\"","full_name":"amaximus/radioactivity_hu","last_commit":"09b6d7a","last_updated":"2023-06-08T08:48:13Z","last_version":"0.4.0","manifest_name":"Radioactivity Hungary","stargazers_count":5,"topics":["homeassistant-custom-component","hungary"],"last_fetched":1709772264.455457},"459709817":{"manifest":{"name":"Tedee"},"description":"Control your tedee smart lock from Home Assistant","domain":"tedee","etag_releases":"W/\"69fe08b59c84bf97de401587b2872b69a8b0d2378e8055ca6e798c030b788174\"","etag_repository":"W/\"bc40808d7cfff6b9b9957180b535badeb3561a219e867af43c143c5f5b98de5a\"","full_name":"patrickhilker/tedee_hass_integration","last_commit":"37d5c9f","last_updated":"2024-01-10T20:32:09Z","last_version":"2024.1.0","manifest_name":"Tedee","open_issues":1,"stargazers_count":22,"topics":["customcomponent","lock","security","smart-lock","smartlock","tedee"],"last_fetched":1707985310.076119},"520066480":{"manifest":{"name":"Huawei Mesh Router"},"description":"Huawei mesh router component for Home Assistant","domain":"huawei_mesh_router","etag_releases":"W/\"f87bd382c0159a9b38ab61fdcfc19f0f3245d4afc441024d7f310c28a429d9ff\"","etag_repository":"W/\"ea7975db3067e985d06054b33c8635ce7ce45cae4dd41c620bb7add46a3a4f9d\"","full_name":"vmakeev/huawei_mesh_router","last_commit":"7e75390","last_updated":"2024-04-01T20:02:41Z","last_version":"v0.9.2.1","manifest_name":"Huawei Mesh Router","open_issues":4,"stargazers_count":45,"topics":["huawei-router","huawei-routers"],"last_fetched":1712002971.248393},"474172189":{"manifest":{"country":["US"],"name":"Anycubic 3D Printer"},"description":"Home assistant integration for Anycubic Printers. ","domain":"anycubic_wifi","etag_releases":"W/\"7af656e6506f34dcc3a6b4103becafad15b31a009fd49b0ee6b648594367e51d\"","etag_repository":"W/\"d625728874ae869d6fcc4a485342942388bf7495e2ad8276b07fc428b222322a\"","full_name":"adamoutler/anycubic-homeassistant","last_commit":"e200330","last_updated":"2024-01-27T18:12:59Z","last_version":"HACS-9","manifest_name":"Anycubic 3D Printer","open_issues":4,"stargazers_count":10,"topics":["3d-printing"],"last_fetched":1709828083.311725},"236611771":{"manifest":{"country":["US"],"name":"TDAmeritrade"},"description":"TDAmeritrade component for Home Assistant","domain":"tdameritrade","etag_releases":"W/\"65d9912ad46beae28ae50e93c7d4dfc144f65de663c5404654e3ef9f60685434\"","etag_repository":"W/\"cb34767243e0704a6cae82f09c59ee035d2a05831f81467a4906668d724a36ef\"","full_name":"prairiesnpr/hass-tdameritrade","last_commit":"eea443e","last_updated":"2022-07-07T02:15:03Z","last_version":"v0.4","manifest_name":"TDAmeritrade","stargazers_count":8,"topics":["tdameritrade"],"last_fetched":1706178051.352721},"531686897":{"manifest":{"name":"dolphin"},"description":"Home Assistant Integration for Dolphin Boiler - Smart Water Heating Control","domain":"dolphin","etag_releases":"W/\"58689a8d479e2e52f33031833c59574ada4b3001e2206193601bf861fb2f3adf\"","etag_repository":"W/\"d83a4dd1060650b0fada02cbb394a764cb4f680d68c1f11e8fb1aac0c6352136\"","full_name":"0xAlon/dolphin","last_commit":"b9e8da3","last_updated":"2023-01-09T11:11:30Z","last_version":"v0.0.6","manifest_name":"dolphin","open_issues":4,"stargazers_count":8,"last_fetched":1709382009.289501},"607493281":{"manifest":{"name":"NeoVolta"},"description":"NeoVolta integration for Home Assistant","domain":"neovolta","etag_releases":"W/\"0a23efd6110b56bc972b0bb24b8e260dc01f4819b30f7753ef25341a8315fe54\"","etag_repository":"W/\"c74f7cd6bdcdbcc13cc511a5c97625085f1a88a8152fad26e8ac6a469da2dbcc\"","full_name":"austinmroczek/neovolta","last_commit":"b642757","last_updated":"2023-04-15T23:57:41Z","last_version":"2023.3.0","manifest_name":"NeoVolta","stargazers_count":1,"topics":["battery-management-system","neovolta","solar-battery"],"last_fetched":1711995367.095715},"262803775":{"manifest":{"name":"Carbon Intensity UK"},"description":"Carbon Intensity UK Sensor for Home Assistant","domain":"carbon_intensity_uk","etag_releases":"W/\"487f79e12902a50e7e9fc8305d354238f76786b93ef08ad8b952cfa6b2ccd95e\"","etag_repository":"W/\"a5bdd7f938d7957b7681499f9377f555cbcf98a9594bb5f9e48a1cd8695fe536\"","full_name":"jscruz/sensor.carbon_intensity_uk","last_commit":"2f04bc0","last_updated":"2022-07-07T21:57:10Z","last_version":"0.0.3","manifest_name":"Carbon Intensity UK","open_issues":2,"stargazers_count":6,"topics":["carbon","custom-integration","energy","sensor-platform"],"last_fetched":1711995592.939784},"666816132":{"manifest":{"name":"iKamand"},"description":"Home Assistant integration - iKamand","domain":"ikamand","etag_releases":"W/\"ba86847e48991accb4c4c47d47438f707a83b23c28a718cc7f2e2d3e5de591ba\"","etag_repository":"W/\"02b6df628327bbc5386b7023f42d0732f14b9fd640816a1a150009b4cd02faa8\"","full_name":"plmilord/Hass.io-custom-component-ikamand","last_commit":"a497657","last_updated":"2024-02-25T20:07:02Z","last_version":"v2.0","manifest_name":"iKamand","open_issues":2,"stargazers_count":14,"topics":["ikamand","kamado-joe"],"last_fetched":1711289817.178312},"459761427":{"manifest":{"country":["PL"],"name":"PGNIG sensor"},"description":"This sensor is gathering gas usage data from PGNIG ebok page.","domain":"pgnig_gas_sensor","etag_releases":"W/\"9b04611b1b4f2b95b45312817b65d203a221f71ae850b00de780f6b59160297c\"","etag_repository":"W/\"9d7d1fafd30a8c2c6db5754064656ac1bc5bec4f3230a86243ddb84c0f18a915\"","full_name":"pawelhulek/pgnig-sensor","last_commit":"0b67ef8","last_updated":"2024-02-01T20:03:21Z","last_version":"v2.3.6","manifest_name":"PGNIG gas Sensor","open_issues":6,"stargazers_count":30,"topics":["gas-sensor"],"last_fetched":1710757232.712909},"286554328":{"manifest":{"name":"Kaco"},"description":"custom integration for kaco solar inverter","domain":"kaco","etag_repository":"W/\"b19aac70bfc2cc5f3e87b3e29e726b4601cf81f7f260bddf9788ea0c8fbfe666\"","full_name":"KoljaWindeler/kaco","last_commit":"964fda8","last_updated":"2023-02-03T11:49:57Z","manifest_name":"kaco","open_issues":5,"stargazers_count":11,"topics":["inverter","solar-energy"],"last_fetched":1711700414.606985},"209855666":{"manifest":{"country":["US"],"name":"UPS"},"description":"The ups platform allows one to track deliveries by the UPS","domain":"ups","etag_repository":"W/\"d039792c98702138f3b181b4e38c6515bcd055b9a86b6069306224b66cd6ce22\"","full_name":"custom-components/ups","last_commit":"f80b683","last_updated":"2021-05-19T10:28:06Z","manifest_name":"Ups","open_issues":1,"stargazers_count":6,"last_fetched":1711247074.122025},"378213601":{"manifest":{"name":"Argoclima"},"description":"Home Assistant integration for Argoclima (Argo) climate control devices","downloads":26,"domain":"argoclima","etag_releases":"W/\"0dc7f2d6c0e3b99a2e5b4a78875df5e93fbba01ccfed5b4e40697e5f510e6363\"","etag_repository":"W/\"e81760e2e01da4cfcef9c8e0eb5fc7a5109b76ef1d66a6ef833d35ce087714d3\"","full_name":"nyffchanium/argoclima-integration","last_commit":"0d0dcfa","last_updated":"2024-04-01T13:57:31Z","last_version":"v1.1.3","manifest_name":"Argoclima","open_issues":11,"stargazers_count":14,"topics":["argo","argoclima","climate-control"],"last_fetched":1711988558.677329},"527278013":{"manifest":{"country":["DE"],"name":"L\u00e4nder\u00fcbergreifendes Hochwasser Portal"},"description":"Home Assistant integration for L\u00e4nder\u00fcbergreifendes Hochwasser Portal","domain":"hochwasserportal","etag_releases":"W/\"0b75ce572d7e515db0263f82e3c55fc097e4586ff7bc51b97b3d272947dd1586\"","etag_repository":"W/\"0725dedcf4e7078ae3c71e7efd82634c93354471867e53b712cced701e760587\"","full_name":"stephan192/hochwasserportal","last_commit":"8982b19","last_updated":"2024-03-05T20:17:00Z","last_version":"v1.0.0","manifest_name":"L\u00e4nder\u00fcbergreifendes Hochwasser Portal","open_issues":2,"stargazers_count":18,"topics":["hochwasserportal"],"last_fetched":1709677151.604442},"523250759":{"manifest":{"name":"Seafile"},"description":"Seafile for Home Assistant","domain":"seafile","etag_releases":"W/\"f5911a0d884a94940a2785202768dd627f023b362bf2408af9c3ccc10e17bb62\"","etag_repository":"W/\"ddce79b69bd806a2c6daeb8f603f34b82b626e895e02d791cb4621c3fe17fa03\"","full_name":"dmamontov/hass-seafile","last_commit":"ffb24d1","last_updated":"2023-03-14T09:16:03Z","last_version":"v2.0.0","manifest_name":"Seafile","open_issues":2,"stargazers_count":7,"topics":["cloud","cloud-storage","file-sync","files","seafile","storage","sync"],"last_fetched":1700355798.981246},"377012187":{"manifest":{"name":"Weight Gurus"},"description":"This custom integration provides sensors for Weight Gurus API endpoints.","domain":"weight_gurus","etag_releases":"W/\"acc946a7b960d57640a537fef61a04cd53ab47ba612174b5afe05df19ec44787\"","etag_repository":"W/\"66ce5c8c9d1287fce2b8c350b3becb868bfbac7d24fec0e8687a207436d65a54\"","full_name":"jcgoette/weight_gurus_homeassistant","last_commit":"a891e0b","last_updated":"2021-12-18T04:00:33Z","last_version":"v2.0.2","manifest_name":"Weight Gurus","stargazers_count":3,"topics":["health","home-assistant-component","weight"],"last_fetched":1678379578.236465},"668937922":{"manifest":{"name":"AC Infinity"},"description":"AC Infinity integration for Home Assistant for UIS based controllers","downloads":276,"domain":"ac_infinity","etag_releases":"W/\"e7c5021fcdc184c80b0d8370aaa74cd00bc3421c62e1ef39c3685ca0ab37ee12\"","etag_repository":"W/\"1bade07fb2306e6702cc42fcf6fc166af78bbb8c146493d06f54cd4797341d3e\"","full_name":"dalinicus/homeassistant-acinfinity","last_commit":"7a90a35","last_updated":"2024-03-03T17:42:02Z","last_version":"1.4.2","manifest_name":"AC Infinity","open_issues":4,"stargazers_count":33,"topics":["acinfinity","grow","growlights","growtent","hvac","hydroponics"],"last_fetched":1711736239.777221},"292081477":{"manifest":{"name":"Shairport Sync Media Player"},"description":"A custom media player for Home Assistant that allows you to control and get updates from a Shairport Sync installation using MQTT.","domain":"shairport_sync","etag_releases":"W/\"e540a59d8417caeea3ab86a7e8ac023cf8aaf175fea08ffc4cc4bfafdbb120f1\"","etag_repository":"W/\"dd657af4375e4a3ee1733bd88f7ba96df286338c2fac1d6b0550ca464692b979\"","full_name":"parautenbach/hass-shairport-sync","last_commit":"3858734","last_updated":"2024-03-29T18:30:32Z","last_version":"v1.3.1","manifest_name":"Shairport Sync Media Player","open_issues":5,"stargazers_count":61,"topics":["airplay","mqtt","shairport-sync"],"last_fetched":1711743604.715113},"380330823":{"manifest":{"name":"Eldes Alarm"},"description":"Home Assistant custom component for Eldes Alarm system","domain":"eldes_alarm","etag_releases":"W/\"a525039d44b098aef1bba5045f0eaffdacab15c19f49abc6ce1b9bd41d04e3ef\"","etag_repository":"W/\"68462f656a181dc02ed539785570242eae097a4fb2f00639ab150370c9cf4a8a\"","full_name":"augustas2/eldes","last_commit":"138aaeb","last_updated":"2024-01-25T18:53:55Z","last_version":"v1.0.11","manifest_name":"Eldes Alarm","open_issues":7,"stargazers_count":13,"topics":["alarm","alarm-panel","alarm-system","eldes","esim364","esim384","output","pitbull-alarm-pro","switch"],"last_fetched":1712153566.8633},"207110572":{"manifest":{"country":["NOR"],"name":"Avfallsor"},"description":"Simple sensor for avfallsor","domain":"avfallsor","etag_releases":"W/\"e3a2aec27068a768caf717112b28b1e27dfb31860de53df72ac063c5d1fe083c\"","etag_repository":"W/\"6d65de4ca485a829d3804130e1de5353a70b9fdbd94fa3fc7175240dfcea50bd\"","full_name":"custom-components/sensor.avfallsor","last_commit":"ee27a37","last_updated":"2022-12-27T19:15:58Z","last_version":"0.0.6","manifest_name":"avfallsor","open_issues":5,"stargazers_count":8,"last_fetched":1704903531.286968},"706651591":{"manifest":{"country":["IL"],"name":"Oref Alert"},"description":"Israeli Oref Alerts","downloads":504,"domain":"oref_alert","etag_releases":"W/\"0f95dd2aac2a0f6be37732de09bcae9f6a09b7c584589f8f0a1d12b58dca9eee\"","etag_repository":"W/\"fbad087c6988f97e53e02087e2f10ef9a39742d7445e75a158a98ae561fe17fc\"","full_name":"amitfin/oref_alert","last_commit":"55ae828","last_updated":"2024-04-02T00:47:55Z","last_version":"v2.10.0","manifest_name":"Israel Pikud Haoref Alert","open_issues":1,"stargazers_count":45,"topics":["homeassistant-custom-component"],"last_fetched":1712182317.13603},"301509152":{"manifest":{"name":"Novus 300 Bus"},"description":"Home Assistant HACS component to readout values from a Paul Novus 300 ventilation system","domain":"novus300bus","etag_releases":"W/\"e5ec6ed631766ffe773bbce72789f18443e5854a1b83742cc4a9276d5527f1ff\"","etag_repository":"W/\"fdb2191bb59fa11740dff2ed57619140ef5d08457a8c401939fbe015c1b41ae4\"","full_name":"BenPru/novus300_Rs485","last_commit":"b6018f2","last_updated":"2023-01-30T22:06:47Z","last_version":"2021.09.20","manifest_name":"Paul Novus 300 RS-485 Bus","open_issues":1,"stargazers_count":6,"last_fetched":1707171271.968986},"239339530":{"manifest":{"country":["NL"],"name":"RAD Hoekschewaard Afval Kalender"},"description":"Home Assisant sensor component for RAD Hoekschewaard Afval Kalender","domain":"rad-afval","etag_repository":"W/\"d82b2ea89dd4470b964f19ef7a9ec272cef82c4eeffda56afd0e8eec91446906\"","full_name":"Johnwulp/rad-afval","last_commit":"ddcf8a1","last_updated":"2022-02-03T19:08:50Z","manifest_name":"RAD Hoekschewaard Afval Kalender","stargazers_count":3,"last_fetched":1685363434.396329},"384704004":{"manifest":{"name":"Trakt"},"description":"A Trakt integration for Home Assistant compatible with upcoming media card","domain":"trakt_tv","etag_releases":"W/\"1e68f3af9e4b9302df930850c215ee1fa825a3e520688af0a48ea16a83428c82\"","etag_repository":"W/\"e4aeba7f22bd49711b1cbe810108043a5f007e9375fdf6104c5ae45db8953d7a\"","full_name":"dylandoamaral/trakt-integration","last_commit":"bbb7c76","last_updated":"2024-03-20T07:52:09Z","last_version":"v0.9.0","manifest_name":"Trakt","open_issues":8,"stargazers_count":27,"topics":["custom","movie","show","trakt","upcoming-media-card"],"last_fetched":1710922704.052869},"488091347":{"manifest":{"name":"2minersInfo"},"description":"Provides data from 2miners.com on a specified miner.","domain":"2minersinfo","etag_releases":"W/\"9ab15925ae05fc6105db4d601643459216f74707bbcbc84d37e175a45e5ea8b0\"","etag_repository":"W/\"1df3a77ef4eaab46cc6aa81906adb91f286295722e165c30ae933db57db218ac\"","full_name":"ThomasPrior/2minersInfo","last_commit":"d27ac94","last_updated":"2022-05-24T18:49:52Z","last_version":"v1.1.1","manifest_name":"2minersInfo","stargazers_count":4,"topics":["2miners","2miners-api","miner","statistics"],"last_fetched":1678387607.715409},"647057223":{"manifest":{"country":["FR"],"name":"Pronote for Home Assistant"},"description":"Pronote integration for Home Assistant","domain":"pronote","etag_releases":"W/\"bef974bdf182851de0f9ef4107b551f97beeee3c3cd8969da6dd982850776f28\"","etag_repository":"W/\"7aed13291dd7e2a4c1a4fbd76dac775a1ff7b5ddc7afb191c1460eb3e049ed3b\"","full_name":"delphiki/hass-pronote","last_commit":"88be118","last_updated":"2024-02-18T11:41:34Z","last_version":"1.14.1","manifest_name":"Pronote","open_issues":26,"stargazers_count":42,"topics":["hassio-integration","pronote"],"last_fetched":1711873077.944247},"176018567":{"manifest":{"name":"gPodder"},"description":"\ud83c\udfa7 gPodder Integration for Podcast Feed Monitoring","downloads":497,"domain":"gpodder","etag_releases":"W/\"81cd0de89a19430719d4fe2a4b01ba8b10974136079dcda7b0d5f33f02af2b75\"","etag_repository":"W/\"d8afc30b69ef9faa8eb7daa59ca8c9adc425eb886357f13d5b05db3a0ac56e90\"","full_name":"custom-components/gpodder","last_commit":"d9288c8","last_updated":"2021-06-05T21:16:30Z","last_version":"2.0.1","manifest_name":"gPodder","open_issues":3,"stargazers_count":13,"last_fetched":1711760075.832704},"504935480":{"manifest":{"name":"Midea Smart AC"},"description":"Home Assistant custom integration to control Midea (and associated brands) air conditioners via LAN.","domain":"midea_ac","etag_releases":"W/\"2c1d5e236c1d88a8f5ea4b817ea642208d152215f655121c95e3b2893429223b\"","etag_repository":"W/\"83054dbe1d4e1c8de256071b7e9d408ca2567c3f2aae1bf65b8c3b3110c1979e\"","full_name":"mill1000/midea-ac-py","last_commit":"611f5e9","last_updated":"2024-03-17T01:53:12Z","last_version":"2024.3.2","manifest_name":"Midea Smart AC","open_issues":7,"stargazers_count":69,"topics":["air-conditioner","automation","climate","lan","midea"],"last_fetched":1712009902.239434},"195459345":{"manifest":{"name":"Climate Group"},"description":"Home Assistant Climate Group","domain":"climate_group","etag_releases":"W/\"a9e4ed54b218cc65016e7a9d6eb0d1c66d60aa123087a610d9a09c9bea1d596e\"","etag_repository":"W/\"3007caf0be9b78a2d74fca8162df407e6fd08ae57afeb064b444befb94f6f926\"","full_name":"daenny/climate_group","last_commit":"fca667c","last_updated":"2023-09-20T07:03:33Z","last_version":"0.6.0","manifest_name":"Climate Group","open_issues":18,"stargazers_count":125,"last_fetched":1711743335.27334},"594007512":{"manifest":{"name":"Moonraker"},"description":"Home Assistant integration for Moonraker, Klipper and Mainsail","domain":"moonraker","etag_releases":"W/\"17d94aad63eacfde35995bbe81ffae69ea535f2c8862184c1b36193e70b8d50d\"","etag_repository":"W/\"2c37e5b17e6e66edccd78fc5cdc53e288a14f0aa06d7b9696391cf42ae5ae818\"","full_name":"marcolivierarsenault/moonraker-home-assistant","last_commit":"593461d","last_updated":"2024-04-01T20:12:25Z","last_version":"1.1.1","manifest_name":"Moonraker","open_issues":19,"stargazers_count":177,"topics":["klipper","moonraker"],"last_fetched":1712153847.149484},"304573324":{"manifest":{"name":"SQL (with JSON detection)"},"description":"Updated SQL integration for Home Assistant that supports JSON attributes","domain":"sql_json","etag_releases":"W/\"a5047b3e9b39107f721309ff6af0852ecdcd2392168e9ea99f276070ad7e6906\"","etag_repository":"W/\"4b9736ffb4ffa602d571d52f4321a02e081e9b419a182ea9ae5ee770f2f32865\"","full_name":"crowbarz/ha-sql_json","last_commit":"74d719a","last_updated":"2023-04-17T09:10:21Z","last_version":"1.1.3","manifest_name":"SQL (with JSON detection)","open_issues":1,"stargazers_count":6,"topics":["json","sql"],"last_fetched":1696111923.492644},"693589195":{"manifest":{"name":"AICO HomeLINK"},"description":"Home Assistant AICO HomeLINK Integration","domain":"homelink","etag_releases":"W/\"260da90ff61714230c37cd2ad1061e7f999680b3aa2fe407074eace97f12d2c5\"","etag_repository":"W/\"23e8241ea7965c2d6ed92ecb1997e599eafe1d5f6ccdb3b49cfbcc5f09e7b264\"","full_name":"RogerSelwyn/AICO_HomeLINK","last_commit":"034e194","last_updated":"2024-03-06T14:11:45Z","last_version":"v1.4.1","manifest_name":"AICO HomeLINK","stargazers_count":4,"topics":["aico","homeassistant-custom-component","homelink"],"last_fetched":1709742138.511497},"206868881":{"manifest":{"name":"Gismeteo"},"description":"Gismeteo Weather Provider for Home Assistant","downloads":5122,"domain":"gismeteo","etag_releases":"W/\"752e4cef7cb8b7ec182fa1c1537cd7ebd1a926c924af1aa3b9c61d6bdac7c5da\"","etag_repository":"W/\"5a527fae30fceb277b3f5aea77e948b2f704d66af57475db34804c13be9f982a\"","full_name":"Limych/ha-gismeteo","last_commit":"f5369e2","last_updated":"2024-02-19T20:39:43Z","last_version":"2.5.2","manifest_name":"Gismeteo","open_issues":26,"stargazers_count":109,"topics":["forecast","gismeteo","gismeteo-weather","sensors","weather-provider"],"last_fetched":1711527717.577104},"587122619":{"manifest":{"country":["US"],"name":"Carrier Infinity Thermostat"},"description":"Carrier Infinity Integration for Home Assistant","domain":"ha_carrier","etag_releases":"W/\"cba9b3c3e74ec37dc22bafc1ccb5c36c0b61388263fa33a66583b479243d874e\"","etag_repository":"W/\"c33e1132730da337bcbfbdf01f4976b5e7411fa0210d646aa6c8038ff45ea372\"","full_name":"dahlb/ha_carrier","last_commit":"c7dd7b0","last_updated":"2024-04-01T21:27:03Z","last_version":"v1.21.4","manifest_name":"Carrier Infinity","open_issues":3,"stargazers_count":25,"topics":["carrier-integration"],"last_fetched":1712009676.09164},"146660369":{"manifest":{"name":"Bravia TV PSK"},"description":"Sony Bravia TV (Pre-Shared Key) component for Home Assistant","downloads":5622,"domain":"braviatv_psk","etag_releases":"W/\"421ae71b078a12d9559f042230903e7179979101c317a8038cd42000732880b8\"","etag_repository":"W/\"ae38a1fe67e1de34ce53041f477ff70842092ecebc7857af1856166f48ce7b12\"","full_name":"custom-components/media_player.braviatv_psk","last_commit":"ca37a72","last_updated":"2023-02-23T19:07:55Z","last_version":"0.4.2","manifest_name":"Bravia TV PSK","stargazers_count":104,"topics":["bravia","psk","sony"],"last_fetched":1709600126.525006},"225248441":{"manifest":{"name":"Mikrotik Router"},"description":"Mikrotik router integration for Home Assistant","downloads":9649,"domain":"mikrotik_router","etag_releases":"W/\"1bc54fdb8a86fe8926e1df6e685eb7386538e8000096af82276988063d3bc6e4\"","etag_repository":"W/\"e6bcc06db1b31eb20f165fd26b9a78460453c376a8eb661414737127fe41ae80\"","full_name":"tomaae/homeassistant-mikrotik_router","last_commit":"802c218","last_updated":"2024-03-31T12:00:15Z","last_version":"v.2.1.4","manifest_name":"Mikrotik Router","open_issues":28,"stargazers_count":270,"topics":["mikrotik"],"last_fetched":1711966950.102856},"531891521":{"manifest":{"name":"Revogi Petoneer Water Fountain"},"description":"A custom Home Assistant Component for WiFI enabled pet water fountains by petoneer","domain":"revogi","etag_releases":"W/\"ca4549eee5746fae2bd9b5a57a792f68331fce906e24ed40a11cf8c486b92db9\"","etag_repository":"W/\"7d9875d09d4c70f61b33a7a655b08eda46e3ffed77833e167028120195526807\"","full_name":"sh00t2kill/petoneer_custom_component","last_commit":"f3143d8","last_updated":"2024-02-07T23:52:43Z","last_version":"v1.0.4","manifest_name":"Revogi Petoneer Water Fountain","stargazers_count":1,"topics":["petoneer","revogi"],"last_fetched":1708655134.986398},"76125161":{"manifest":{"name":"iCal Sensor"},"description":"an iCal Sensor for Home Assistant","domain":"ical","etag_releases":"W/\"2e34d6d06d56aff79a8a30373d71565c9f501b1cb29aef70624e3f03fd8d78c0\"","etag_repository":"W/\"2ce22734424a5908fc105a8c19cc5988620954030b2cc435e1d04a28f9dc4505\"","full_name":"tybritten/ical-sensor-homeassistant","last_commit":"3ec8d2d","last_updated":"2023-08-30T18:17:55Z","last_version":"1.6.7","manifest_name":"ical Sensor","open_issues":52,"stargazers_count":92,"topics":["ical"],"last_fetched":1711362162.610438},"328361159":{"manifest":{"name":"ultimaker"},"description":"Home-Assistant component for Ultimaker printers (UM3, S3, S5)","domain":"ultimaker","etag_releases":"W/\"9ad5503f638f64dbcd5e2561bbbe770ef4ef05977b3ef30a1156c6efdf2fa019\"","etag_repository":"W/\"1715a2f6c070727dfb87a390d86eb7f271bb711cc117f0dd2260baace3ed71ea\"","full_name":"jellespijker/home-assistant-ultimaker","last_commit":"0c2c93a","last_updated":"2023-10-21T16:06:29Z","last_version":"V0.1.5","manifest_name":"Ultimaker","open_issues":11,"stargazers_count":15,"topics":["3d-printing","home-assistant-component","s3","s5","ultimaker","um3"],"last_fetched":1708827873.258896},"215825339":{"manifest":{"country":false,"name":"Hekr Component"},"description":"Hekr integration using python-hekr","domain":"hekr","etag_releases":"W/\"d2c0793c7c01167d0e013e2907e0ce905415c8279664a0113d2e191a6cb2ee41\"","etag_repository":"W/\"04a6ad6be26719fdf8dc817a6aa6c58b73a3f8dc417eef3984fd90dcdd0fdf76\"","full_name":"alryaz/hass-hekr-component","last_commit":"6b26bfd","last_updated":"2023-09-11T00:00:57Z","last_version":"v0.2.15","manifest_name":"Hekr","open_issues":6,"stargazers_count":34,"topics":["consumption","hekr","wisen-application"],"last_fetched":1704767276.139393},"441294260":{"manifest":{"name":"Auto Areas"},"description":"\ud83e\udd16 A custom component for Home Assistant which automates your areas.","domain":"auto_areas","etag_releases":"W/\"d968807787f5972cf8c3f2fdd6e9c763b2ba4ea1bc5a622a8a773c33b6d52423\"","etag_repository":"W/\"b478a3f7e67af8e968808c6dec3ea14feac1d31fc272c297ccfeb5c8f0859802\"","full_name":"c-st/auto_areas","last_commit":"3bcaf5d","last_updated":"2024-04-01T04:53:10Z","last_version":"v2.3.0","manifest_name":"Auto Areas","open_issues":7,"stargazers_count":23,"last_fetched":1711952290.222629},"261496794":{"manifest":{"name":"Plcbus integration"},"description":"a plcbus custom somponents for HomeAssistant","domain":"plcbus","etag_releases":"W/\"8ad64d85be376b43fdcef1be1a995c2ea65a5cdb54d4a5811f98b61c9565eb9c\"","etag_repository":"W/\"d5bb2ed75f5bc513f8fce9e59370e5ecdd0c4c7e30af721de71b3b731e97d222\"","full_name":"tikismoke/home-assistant-plcbus","last_commit":"5c1a19f","last_updated":"2023-01-02T22:17:56Z","last_version":"0.0.2","manifest_name":"Plcbus integration","stargazers_count":2,"topics":["plcbus"],"last_fetched":1678379799.387967},"403123516":{"manifest":{"name":"Ecowater Softener"},"description":"A Homeassistant custom component to integrate Ecowater water softeners","domain":"ecowater_softener","etag_releases":"W/\"e70669ae8821e52e451c4d9755a1247b442e15178ae525b317da6d4014350cd4\"","etag_repository":"W/\"b64c3e0401eed078ed2a89a841067d5feba2df074b1e892a5254563b83b050d7\"","full_name":"barleybobs/homeassistant-ecowater-softener","last_commit":"a90654a","last_updated":"2024-02-28T18:27:02Z","last_version":"v3.3.0","manifest_name":"Ecowater Softener","open_issues":5,"stargazers_count":27,"topics":["ecowater","iot","selfhosted","water-softener"],"last_fetched":1712045805.809901},"692375020":{"manifest":{"country":["DE"],"name":"Bayernl\u00fcfter"},"description":"Adds support for Bayernl\u00fcfter devices to Home Assistant as custom component.","domain":"bayernluefter","etag_releases":"W/\"05d418238f398f4f3af6807052f0820baa05a85e49abba2af9fa34ea9b4885dc\"","etag_repository":"W/\"f38044378dfdff3b0e0b3a20b875bcf00af58cf89b01d06fcfafcbee40d62c20\"","full_name":"mampfes/ha_bayernluefter","last_commit":"e22b987","last_updated":"2024-01-28T08:30:25Z","last_version":"1.2.3","manifest_name":"Bayernl\u00fcfter","open_issues":1,"stargazers_count":6,"topics":["bayernluefter","bayernluft","homeassistant-component","homeassistant-custom-component"],"last_fetched":1710512245.439237},"582143144":{"manifest":{"country":["NL"],"name":"OJ Microline Thermostat"},"description":"Home Assistant integration for an OJ Microline Wifi Thermostat","domain":"ojmicroline_thermostat","etag_releases":"W/\"d9da9979053f99066262b78ecdba31eecb4739673a2ad89cac70ec9222b82b3e\"","etag_repository":"W/\"189a3ddecaea3682b053767cc5a768316142c871a4defd99e8329c087472ecb1\"","full_name":"robbinjanssen/home-assistant-ojmicroline-thermostat","last_commit":"a15e49b","last_updated":"2024-04-02T03:59:46Z","last_version":"1.2.2","manifest_name":"OJ Microline Thermostat","open_issues":3,"stargazers_count":8,"topics":["climate","oj-electronics","oj-microline","owd5","thermostat"],"last_fetched":1712039018.716072},"683619534":{"manifest":{"name":"Garmin MapShare"},"description":"Home Assistant custom integration for Garmin MapShare feeds","domain":"garmin_mapshare","etag_releases":"W/\"d70d22084f4c13bf0b8f3b944279c57a1153454a92c4197c9de3611d95315ada\"","etag_repository":"W/\"7629022fadfcbf677961617cd8601d5971b1c1a7591679fa6c61558ce5434413\"","full_name":"BHSPitMonkey/homeassistant-garmin-mapshare","last_commit":"df71680","last_updated":"2024-01-14T19:37:27Z","last_version":"v1.1.1","manifest_name":"Garmin MapShare","stargazers_count":5,"topics":["custom-integration","garmin"],"last_fetched":1705270367.453652},"234514524":{"manifest":{"name":"Sonos Alarm"},"description":"HomeAssistant custom component to control your SONOS Alarm","domain":"sonos_alarm","etag_releases":"W/\"fb3edcd6cc7fe10e975efcc12fa8e6b955d0e628a84aa6b09492310044051aa8\"","etag_repository":"W/\"ea546ee8b2e5fce2babdd45a6fc403e57bec226ca81c99f0436c84e196a95818\"","full_name":"AaronDavidSchneider/SonosAlarm","last_commit":"5b9426d","last_updated":"2021-05-25T16:33:27Z","last_version":"1.3.1","manifest_name":"Sonos Alarm","stargazers_count":23,"last_fetched":1710879215.44789},"228690854":{"manifest":{"country":["NL"],"name":"TTN Gateway Sensor"},"description":"This components reads statistics from a The Things Network Gateway.","domain":"ttn_gateway","etag_releases":"W/\"4033d804eb3a2711640a4df7cae8b741ae00784f86cf8356c2306bbf91be9e65\"","etag_repository":"W/\"6084f0bdefbf6118efcba35e5c5d17f4e8d49ca0c9db3f1e08cf3f2b34f79f7f\"","full_name":"cyberjunky/home-assistant-ttn_gateway","last_commit":"0d805b8","last_updated":"2021-12-18T16:52:03Z","last_version":"1.0.7","manifest_name":"TTN Gateway Sensor","stargazers_count":2,"last_fetched":1678386364.755829},"692701325":{"manifest":{"name":"WeatherFlow Forecast and Sensor Integration"},"description":"Home Assistant integration for WeatherFlow Forecast","domain":"weatherflow_forecast","etag_releases":"W/\"5f93e4ae5ffec92e8a66958f08c5978ed79c3c53dffc7d335f6f315081dbed0a\"","etag_repository":"W/\"1ac66f3fafa7acd719430260fc37510061397354383f3b70a0ab971d0e17d7fd\"","full_name":"briis/weatherflow_forecast","last_commit":"9c5d4a1","last_updated":"2024-04-02T04:53:27Z","last_version":"v1.0.8","manifest_name":"WeatherFlow Forecast","open_issues":1,"stargazers_count":47,"topics":["home-assistant-component","weather-forecast","weatherflow"],"last_fetched":1712168220.462766},"265587564":{"manifest":{"name":"Kamstrup Multicall 66C"},"description":"Custom component that integrates the Kamstrup Multicall 66C heating system into Home Assistant","domain":"mc66c","etag_releases":"W/\"27c69545ef6769a9972fe8e5c7f25232ac232e6756798d7ff1ce0f2209cbe8f6\"","etag_repository":"W/\"8513ca71835c49f9eaac8bf7cb6e4e397e64711464298523632de8c7701848fd\"","full_name":"golles/Home-Assistant-Sensor-MC66C","last_commit":"8e19a30","last_updated":"2024-04-01T13:07:03Z","last_version":"1.1.0","manifest_name":"Kamstrup Multical 66C meter reader","stargazers_count":19,"topics":["home-assistant-component","home-assistant-integration","kamstrup","stadsverwarming"],"last_fetched":1711980951.22889},"264499592":{"manifest":{"name":"Cryptoinfo"},"description":"Provides Home Assistant sensors for all cryptocurrencies supported by CoinGecko","domain":"cryptoinfo","etag_releases":"W/\"49a17d17171c92a6ed43d247eeaa183e78f7cc312c1b64f42a28e9d56cd8ae03\"","etag_repository":"W/\"95e3d7018b7db98b0f24e6971564bd2de9fb1df899744368d9f2b31100a363e3\"","full_name":"heyajohnny/cryptoinfo","last_commit":"b6455c9","last_updated":"2024-03-10T20:52:16Z","last_version":"v0.1.7","manifest_name":"Cryptoinfo","stargazers_count":42,"last_fetched":1711434020.905688},"199291345":{"manifest":{},"description":"Adds ability to switch alternative speed in qBittorrent through Home Assistant.","domain":"qbittorrent_alternative_speed","etag_releases":"W/\"e044690eb77e6a7b8dc270cbc9397eaf59bb3b7327657530d04f97a5ad0c8bbd\"","etag_repository":"W/\"2a9d85f47abc5c8adb81b0ce6c6c5936f1f18c627a1026244a61faaa7151e5ef\"","full_name":"JurajNyiri/HomeAssistant-qBitTorrentAlternativeSpeed","last_commit":"d44e337","last_updated":"2022-07-07T10:39:14Z","last_version":"1.3.3","manifest_name":"qBittorrent alternative speed switch","open_issues":1,"stargazers_count":12,"last_fetched":1704889729.413205},"628038776":{"manifest":{"name":"Vantage InFusion"},"description":"Home Assistant integration for Vantage InFusion home automation controllers.","downloads":112,"domain":"vantage","etag_releases":"W/\"0ecd75444aa2ebc0f47c080e3c20c115c16ec945ccd44e4a25dd786ebf80d7e3\"","etag_repository":"W/\"3a8c91f4adc9431cd02fe6c592705561c716d3bccc7fd9d4482bf3896d36eb54\"","full_name":"loopj/home-assistant-vantage","last_commit":"c66bb0e","last_updated":"2024-03-25T17:57:46Z","last_version":"0.11.0","manifest_name":"Vantage InFusion","open_issues":14,"stargazers_count":6,"topics":["infusion","vantage"],"last_fetched":1711390908.370055},"210966517":{"manifest":{"name":"Zwift Sensors"},"description":"Zwift Sensor Integration for HomeAssistant","domain":"zwift","etag_releases":"W/\"92f27b26af283b2f1bbbf4eb12a06e85169176a1cfb0ad76f8b7ee74242bbba3\"","etag_repository":"W/\"448dac00dfeedd67f1500d1d2769dc6182fbcf1148034b1ffe4e336c9166e9bb\"","full_name":"snicker/zwift_hass","last_commit":"53c1b9f","last_updated":"2023-09-17T15:01:07Z","last_version":"v3.3.3","manifest_name":"Zwift Sensor","open_issues":7,"stargazers_count":44,"last_fetched":1711629089.1477},"637182469":{"manifest":{"country":["BE"],"name":"MIWA"},"description":"Home Assistant component for MIWA BE services","domain":"miwa","etag_releases":"W/\"e393528e67fadd05a0859aa61a16bc8bfa3c5f3e946c2885fb028d8443b4b787\"","etag_repository":"W/\"a816d6f64792487a4606cd66d1a02179e8f0f2370a255dfc401bcf09ee0738ad\"","full_name":"geertmeersman/miwa","last_commit":"722dddc","last_updated":"2024-03-25T09:12:32Z","last_version":"v0.5.3","manifest_name":"MIWA","topics":["miwa"],"last_fetched":1711361830.25588},"200073618":{"manifest":{},"description":"Add template binary_sensors from the UI.","domain":"templatebinarysensor","etag_repository":"W/\"99a7b4436b17a64987dbd1ee6dfab291e362668d601f5cd7416155314c7b275c\"","full_name":"dlashua/templatebinarysensor","last_commit":"48d6b86","last_updated":"2021-11-11T12:35:12Z","manifest_name":"UI Template binary_sensor configuration","stargazers_count":1,"last_fetched":1710620083.503887},"585689945":{"manifest":{"country":["SE"],"name":"Temperatur.nu"},"description":"A sensor for temperatur.nu and a service for reporting your current temperature","downloads":2,"domain":"temperatur_nu","etag_releases":"W/\"a2009bda500e5a71933e9065002a67b0d1192258a8edff563f1a527cd390f504\"","etag_repository":"W/\"97739252b52e2185b1e6ba5faa92af439aa7cdb75eb672e48379cfa7bc7e3cec\"","full_name":"popeen/Home-Assistant-Custom-Component-Temperatur-Nu","last_commit":"c61b4dc","last_updated":"2024-04-03T23:24:06Z","last_version":"2024.04.1","manifest_name":"Temperatur.nu","stargazers_count":2,"topics":["temperature"],"last_fetched":1712192578.708584},"229060565":{"manifest":{"name":"Xiaomi Mijia Multifunctional MJYSH01YM"},"description":"\u5c0f\u7c73\u517b\u751f\u58f6","domain":"health_pot","etag_releases":"W/\"86e0ca4d03f46d48ab62f33fa378002ef21cb25f4399cea16fd7cccbbe4fbb10\"","etag_repository":"W/\"4703af3a914f8307201bcbe0cd687fa4d4cc74fc69efe7b19fe87fd3f0dc476f\"","full_name":"fineemb/Xiaomi-Smart-Multipurpose-Kettle","last_commit":"f53ef76","last_updated":"2022-06-02T18:40:56Z","last_version":"v1.4","manifest_name":"Mi Smart Multipurpose Kettle","open_issues":7,"stargazers_count":6,"last_fetched":1709201849.083756},"233289477":{"manifest":{"country":["SE"],"name":"Greenely Sensors"},"description":"Custom component to get usage data and prices from Greenely for Home Assistant","domain":"greenely","etag_releases":"W/\"01572d4a30c3caa06163fd64737568f760112624f5883ac7cf72419bcbbbb02b\"","etag_repository":"W/\"d93a1fcb8b5998d68688547d56098219c7083d86a6095019b312abb30b9caf97\"","full_name":"linsvensson/sensor.greenely","last_commit":"fe81b8f","last_updated":"2023-01-02T21:20:56Z","last_version":"1.0.6","manifest_name":"Greenely Sensors","open_issues":24,"stargazers_count":49,"last_fetched":1712060949.699696},"160022220":{"manifest":{"name":"Amazon Rekognition"},"description":"Home Assistant Object detection with Amazon Rekognition","domain":"amazon_rekognition","etag_releases":"W/\"b5bf66f5dc642430c0204eb3c86fc791490c980943aab6115c476c607a1b7738\"","etag_repository":"W/\"741438168ba58f7e4ad406163d417a329dab6ad49faa4a8d6ad43288a41d3743\"","full_name":"robmarkcole/HASS-amazon-rekognition","last_commit":"b5ca776","last_updated":"2024-04-03T16:30:09Z","last_version":"v3.2","manifest_name":"Amazon Rekognition custom component","open_issues":16,"stargazers_count":85,"topics":["rekognition"],"last_fetched":1712168584.714508},"173563704":{"manifest":{"name":"Programmable Thermostat"},"description":"Programmable thermostat that let you have a smart thermostat on budget.","domain":"programmable_thermostat","etag_releases":"W/\"9436893c92df303842487dde54e683480a0b81d73971a264591efb10b21eac1c\"","etag_repository":"W/\"f22a13d7e0092f7312c452c33512e5b8bdbd3047c0471fd7f12cb5b75cbc7173\"","full_name":"custom-components/climate.programmable_thermostat","last_commit":"439a255","last_updated":"2024-01-10T09:36:04Z","last_version":"8.3","manifest_name":"Programmable Thermostat","open_issues":9,"stargazers_count":112,"topics":["programmable-thermostat","programming","smart-thermostat","thermostat","thermostats"],"last_fetched":1710526679.605308},"260264517":{"manifest":{"name":"ClimaCell Weather Provider"},"description":"Climacell weather provider integration is a custom component for Home Assistant. The climacell platform uses the Climacell API as a source for meteorological data for your location.","domain":"climacell","etag_releases":"W/\"4541ce0029715a60cb775e719acf4074f215b3d6ac5eb01d4c6756e5a25c73d9\"","etag_repository":"W/\"73a646676bb5f212b31909c7cb6fba2c0fbf21ab03556c0ef706de7e4a16f8fa\"","full_name":"r-renato/ha-climacell-weather","last_commit":"0fbc2b5","last_updated":"2023-06-14T20:17:22Z","last_version":"2.0.3","manifest_name":"Climacell weather","open_issues":33,"stargazers_count":46,"topics":["climacell","weather"],"last_fetched":1701858026.398265},"236123258":{"manifest":{"country":["US"],"name":"Camect Integration"},"description":"A HACS integration for the Camect smart home surveillance system","domain":"camect","etag_releases":"W/\"205843f0e2a9f05cc0224fedfcc6167010764cea3de73e09d918c38f6f605776\"","etag_repository":"W/\"5ee55eef6c8cbefede141e628106771790b5d48128c259705cf6699b6000594a\"","full_name":"pfunkmallone/HACS-camect-integration","last_commit":"608de66","last_updated":"2024-02-25T21:27:18Z","last_version":"2024.02.25","manifest_name":"Camect","open_issues":1,"stargazers_count":4,"topics":["camect"],"last_fetched":1709216469.056277},"373370853":{"manifest":{"name":"Helium Blockchain"},"description":"Helium blockchain sensors for Home Assistant","domain":"helium","etag_releases":"W/\"0ce335bc2445c4a29b7650a1d412d375ade374a6c9a22c7acd356096411975d8\"","etag_repository":"W/\"7bc20001e8f4a2573ca95220987ce447ad95a4bb50bbabc686f590147466cd7e\"","full_name":"rsnodgrass/hass-helium","last_commit":"4b3e7bc","last_updated":"2023-04-11T15:56:11Z","last_version":"0.3.8","manifest_name":"Helium Blockchain","open_issues":2,"stargazers_count":35,"topics":["helium","helium-blockchain","lorawan","lorawan-network"],"last_fetched":1708352393.036107},"334925385":{"manifest":{"name":"RCT Power"},"description":"A Home Assistant custom component to integrate with RCT Power inverters.","domain":"rct_power","etag_releases":"W/\"b3942387003f3aa547fdead007f534cf19ce7dda0151d849e8f1c591b2e566dc\"","etag_repository":"W/\"73cf43507046c93e3e4c0fea5dd7e3848721b087a5b7085a9fcf7dfe0e763fe7\"","full_name":"weltenwort/home-assistant-rct-power-integration","last_commit":"a8eb2c5","last_updated":"2024-03-25T17:42:08Z","last_version":"v0.13.1","manifest_name":"RCT Power","open_issues":23,"stargazers_count":58,"topics":["rct-power"],"last_fetched":1712002971.543934},"562402396":{"manifest":{"name":"Siku Fan"},"description":"Siku Fan Home Assistant Integration (Siku / Duka / Oxxify)","downloads":4,"domain":"siku","etag_releases":"W/\"bd75a50fd1b3a41d402a31df3bd48fac22cbaab2ef46e4e8d8a18e8e267350c6\"","etag_repository":"W/\"4b15364661c4798252f557849fd0a25bd587388a6f85c38aea3d3a1e72b6d13a\"","full_name":"hmn/siku-integration","last_commit":"012339c","last_updated":"2024-04-01T06:35:34Z","last_version":"v2.1.0","manifest_name":"Siku Fan","stargazers_count":9,"last_fetched":1711959681.502271},"235385658":{"manifest":{"name":"Xantech/Dayton Audio/Sonance Multi-Zone Amp"},"description":"Xantech Multi-Zone Matrix Audio for Home Assistant","domain":"xantech","etag_releases":"W/\"3175064f7298359786645031e9aecbd989bd1ecf78c9f39d311619fd25821a4f\"","etag_repository":"W/\"90b44bf44698aaaf72796e4fa591b3b3dd0cc0553bd24e41486a751045e379e9\"","full_name":"rsnodgrass/hass-xantech","last_commit":"50607ce","last_updated":"2024-02-26T05:28:33Z","last_version":"0.1.0","manifest_name":"Xantech/Dayton Audio/Sonance Multi-Zone Amps","stargazers_count":17,"topics":["audiophile","xantech"],"last_fetched":1710757287.292816},"436896679":{"manifest":{"name":"Weatherlink"},"description":"Weatherlink for Home Assistant","downloads":413,"domain":"weatherlink","etag_releases":"W/\"2f7b86f304f5506ca8ea66062cc371c3db967266d079649abc565f79a7295b85\"","etag_repository":"W/\"d52aa8ae6aaff6cb73736765fd6adaad20847c97381050489bcf8865435ecb38\"","full_name":"astrandb/weatherlink","last_commit":"5703632","last_updated":"2024-03-25T02:03:07Z","last_version":"v2024.1.1","manifest_name":"WeatherLink","open_issues":3,"stargazers_count":7,"topics":["davis","vantage","vue","weatherlink"],"last_fetched":1711340184.489764},"377060365":{"manifest":{"country":["ru"],"name":"\u041b\u0438\u0447\u043d\u044b\u0439 \u043a\u0430\u0431\u0438\u043d\u0435\u0442 \u0418\u043d\u0442\u0435\u0440 \u0420\u0410\u041e (\u042d\u043d\u0435\u0440\u0433\u043e\u0441\u0431\u044b\u0442)"},"description":"\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f Home Assistant \u0441 \u041b\u041a \"\u0418\u043d\u0442\u0435\u0440 \u0420\u0410\u041e\"","domain":"lkcomu_interrao","etag_releases":"W/\"327903df8d07688f484223e9ff1b6c0dc8d13312a7700100b074c05eb2f97140\"","etag_repository":"W/\"ef1850c6a1b6a21fd3e5e32fd51750d527aa7f10d1e4da0f139ebc60e09f599f\"","full_name":"alryaz/hass-lkcomu-interrao","last_commit":"d83e88a","last_updated":"2022-05-17T20:58:09Z","last_version":"v2022.05.02","manifest_name":"Inter RAO Personal Cabinet (Energosbyt)","open_issues":12,"stargazers_count":35,"topics":["altaienergosbyt","bashelektrosbyt","energosbyt","esbvolga","mosenergosbyt","sevesk","tambovenergosbyt","tomskenergosbyt"],"last_fetched":1710937331.345951},"85400693":{"manifest":{"name":"Padavan Tracker"},"description":"Device tracker component that uses Padavan-based router","domain":"padavan_tracker","etag_releases":"W/\"d50cc6edfaa06a9ba819c2be2bd1731a334b0aaabd2e54fbb4915c3dabc523e4\"","etag_repository":"W/\"4e02678762078e68fe59fc954d0d2ea9c7bc773f4460a800fa606b90dbb76aee\"","full_name":"PaulAnnekov/home-assistant-padavan-tracker","last_commit":"7d7d128","last_updated":"2022-05-18T17:01:17Z","last_version":"1.0.2","manifest_name":"Padavan Tracker","open_issues":2,"stargazers_count":46,"topics":["padavan","router","xiaomi"],"last_fetched":1698078141.579237},"132661981":{"manifest":{"name":"Elasticsearch integration"},"description":"Publish Home-Assistant events to Elasticsearch","domain":"elasticsearch","etag_releases":"W/\"e8495c6d3037ec896f668ad5dc66b4db13580a0b28af348897a84dd7560f2c9e\"","etag_repository":"W/\"d79473eae21a2fe7a1b55cd716c3784539b6ab0a72b843febe51e1e3572aeaec\"","full_name":"legrego/homeassistant-elasticsearch","last_commit":"1b0bd60","last_updated":"2024-04-02T23:10:42Z","last_version":"v0.6.1","manifest_name":"Elasticsearch","open_issues":17,"stargazers_count":135,"topics":["elasticsearch"],"last_fetched":1712105954.369247},"334284822":{"manifest":{"name":"AWS Codepipeline"},"description":"An integration to monitor and execute AWS Codepipeline projects within Home Assistant.","domain":"aws_codepipeline","etag_releases":"W/\"087e385b164e27c4a7c671f81cee276865d7f09f0e0659cf2eb454cf2e11eedb\"","etag_repository":"W/\"6216a60b17e01307008dc71bcffb380c2dd5dcf99e65b0425dc63c1bb14f4a75\"","full_name":"ohheyrj/home-assistant-aws-codepipeline","last_commit":"3b374af","last_updated":"2021-01-30T22:52:54Z","last_version":"v1.0.0","manifest_name":"AWS CodePipeline","stargazers_count":2,"topics":["aws","ci","cloud","codepipeline"],"last_fetched":1701879825.920445},"324913968":{"manifest":{"name":"Deutscher Wetterdienst (by hg1337)"},"description":"Custom component for Home Assistant that integrates weather data (measurements and forecasts) of Deutscher Wetterdienst (DWD).","domain":"dwd","etag_releases":"W/\"693af19aa7d4131e39afad025d5d6ff4226e3e497354b91cf12a41a8cceb71d1\"","etag_repository":"W/\"45cf5eb09ee4a5be2368e613a17075f667d8c118cccc6b4f2d2dc4215bd59253\"","full_name":"hg1337/homeassistant-dwd","last_commit":"38a313a","last_updated":"2024-01-13T00:40:04Z","last_version":"2024.1.0","manifest_name":"Deutscher Wetterdienst","open_issues":1,"stargazers_count":61,"topics":["deutscher-wetterdienst","dwd","hacs-custom","home-assistant-component","home-assistant-custom-component","home-assistant-integration","home-assistant-weather","homeassistant-component","homeassistant-custom-component","homeassistant-weather","weather","wetter"],"last_fetched":1712182511.870831},"583379046":{"manifest":{"name":"Mold Risk Index"},"description":"Calculate the level of risk of mold growth in a crawl space.","domain":"mold_risk_index","etag_releases":"W/\"d7682d5870f6c9d8f8c6c3a82446b06e437de7d417b3a32e4e5391e9f2e9c838\"","etag_repository":"W/\"ee92bae4f6b7ea76b5e6f972304a1bba05e1997f582db0badd53625403dbaa1c\"","full_name":"Strixx76/mold_risk_index","last_commit":"51dd03e","last_updated":"2024-01-11T15:16:56Z","last_version":"v1.1.0","manifest_name":"Mold Risk Index","open_issues":3,"stargazers_count":32,"topics":["python3"],"last_fetched":1710995039.912703},"200399989":{"manifest":{"name":"Clean up snapshots service"},"description":"Service to clean up your home assistant snapshots, so you don't manually have to.","domain":"clean_up_snapshots_service","etag_releases":"W/\"7a81400b7efba3542fa02b362b8e5ea333f1422d41fad3e08ea77c14ff516427\"","etag_repository":"W/\"7d3a95cb0a568e5e881c07e3313eb63f0362354e427a1f028f4da92065a07919\"","full_name":"tmonck/clean_up_snapshots","last_commit":"44aed46","last_updated":"2024-02-10T15:33:35Z","last_version":"0.10.3","manifest_name":"Clean up your snapshots","open_issues":2,"stargazers_count":18,"topics":["backups"],"last_fetched":1710771685.429268},"618101233":{"manifest":{"name":"Google Fit"},"description":"Home Assistant Google Fit Custom Component","downloads":3915,"domain":"google_fit","etag_releases":"W/\"34337b28f99948cd521c092cc2a12199b6a0215c58986edb7ed147350c649b8b\"","etag_repository":"W/\"47544ca02eebf80fa1b4d1242bbb76b98fe6965c5146f938777d7da58da24bf7\"","full_name":"YorkshireIoT/ha-google-fit","last_commit":"817b474","last_updated":"2024-04-03T23:39:29Z","last_version":"v4.0.0","manifest_name":"Google Fit","open_issues":9,"stargazers_count":84,"topics":["google-fit","home-assistant-integration"],"last_fetched":1712192657.137251},"365567023":{"manifest":{"country":["EN"],"name":"Nuvo multi-zone amplifier (serial)"},"description":"Custom component to control a Nuvo Grand Concerto/Essentia G multi-zone amplifier via serial connection","downloads":2,"domain":"nuvo_serial","etag_releases":"W/\"599e8403ffa7a72899ba7c2f0b35db2ce9389ddd5f1800cb776003696e236e57\"","etag_repository":"W/\"d84ddb7f0d20cdff12796f0c2115bc3a5ca64c28451ca6aab92e88b1078ecb83\"","full_name":"sprocket-9/hacs-nuvo-serial","last_commit":"afd1379","last_updated":"2023-08-31T16:27:58Z","last_version":"v2.0.3","manifest_name":"Nuvo multi-zone amplifier (serial)","stargazers_count":8,"topics":["home-assistant-component","home-assistant-integration"],"last_fetched":1704824489.655015},"545119372":{"manifest":{"name":"Camect"},"description":"Full Camect Hub integration for Home Assistant / HACS","domain":"camect","etag_releases":"W/\"7a5562b5366a8aa25454b8cb03db8235c70bd719caec20afcdec2b3a78321d75\"","etag_repository":"W/\"87d543cac7affc61e6b681a7989f2101f32b3b8695db19e889375453ab4ffda7\"","full_name":"Fr3d/camect-ha","last_commit":"80e8327","last_updated":"2023-05-12T09:17:41Z","last_version":"v1.0.1","manifest_name":"Camect","open_issues":1,"stargazers_count":6,"topics":["camect","home-assistant-integration"],"last_fetched":1709345958.235181},"675105585":{"manifest":{"name":"pulsatrix charger integration for Home Assistant using local MQTT"},"description":"Home Assistant custom component for pulsatrix EV charger","domain":"pulsatrix_local_mqtt","etag_releases":"W/\"60252d4d35f93a9c9c563c2b960a44827d28517e830639983d06f598eaed10c2\"","etag_repository":"W/\"2084c68d3f3099117e4ec6561ebb9b115d4e892ebeb184b33772146028e47e4a\"","full_name":"werthdavid/homeassistant-pulsatrix-local-mqtt","last_commit":"2397e62","last_updated":"2023-08-14T12:04:33Z","last_version":"1.0.0","manifest_name":"pulsatrix charger (MQTT)","stargazers_count":3,"topics":["charger","homeassistant-custom-component","pulsatrix"],"last_fetched":1706134839.290875},"591644026":{"manifest":{"name":"Google Photos"},"description":"Home Assistant Google Photos integration","downloads":4175,"domain":"google_photos","etag_releases":"W/\"9235d1938387e94b24645ca3167a6dbb3fc6b8491fce1c6d35a388e72488da67\"","etag_repository":"W/\"72e1fdfcdd131e8064169739c224138426168ee83f3a01d379f3e13c97c73178\"","full_name":"Daanoz/ha-google-photos","last_commit":"7c11dee","last_updated":"2023-10-06T07:46:41Z","last_version":"v0.6.2","manifest_name":"Google Photos","open_issues":3,"stargazers_count":69,"topics":["google-photos","home-assistant-integration"],"last_fetched":1711995441.393032},"127251446":{"manifest":{"country":["NL"],"name":"Afvalwijzer"},"description":"Provides sensors for some Dutch waste collectors","domain":"afvalwijzer","etag_releases":"W/\"5b92b10997f0121ddd72f7b7649fd35de2d036bd972304eb82af85cc6fa4aacd\"","etag_repository":"W/\"7eddf80a5710f36a5e85fbcc1804229c6645d3d1e3f846e0a1cfbae0a15bd075\"","full_name":"xirixiz/homeassistant-afvalwijzer","last_commit":"40ebb4a","last_updated":"2024-02-27T10:42:51Z","last_version":"2024.02.01","manifest_name":"Afvalwijzer","open_issues":2,"stargazers_count":165,"topics":["afvalwijzer","trash"],"last_fetched":1711966952.174674},"193371652":{"manifest":{"country":["PL"],"name":"Looko2 sensor"},"description":"This sensor uses official API to get air quality data from https://looko2.com.","downloads":139,"domain":"looko2","etag_releases":"W/\"11a49cbeab8cfcad23770dfdbd014b723c06b3cf6af6c71a9032148d4d65a2c8\"","etag_repository":"W/\"c1148a8e3d74c1c3baf8b2493c10c94a1e77e24f58c42f0de84a8fbf32a2d865\"","full_name":"PiotrMachowski/Home-Assistant-custom-components-Looko2","last_commit":"c488a65","last_updated":"2023-07-07T02:53:44Z","last_version":"v1.0.3","manifest_name":"LookO2","open_issues":4,"stargazers_count":5,"topics":["air-quality","weather"],"last_fetched":1711117165.363094},"97201395":{"manifest":{"name":"Xiaomi Mi Smart WiFi Socket Integration"},"description":"Xiaomi Mi Smart WiFi Socket integration for Home Assistant","domain":"xiaomi_miio_plug","etag_releases":"W/\"d3635293e3a1edef0d8fcf708a0200b85f4b17b9bdf13c3b4522de70b5045172\"","etag_repository":"W/\"3d6c900de4a3d0a4975ff449e7f24311afa2b30dd2737648fdb3fc6e5453170b\"","full_name":"syssi/xiaomiplug","last_commit":"9326f9e","last_updated":"2024-02-11T13:07:11Z","last_version":"2024.2.0.0","manifest_name":"Xiaomi Mi Smart WiFi Socket","open_issues":3,"stargazers_count":105,"topics":["miio","miio-device","miio-protocol","switch","xiaomi"],"last_fetched":1709612603.881592},"200927325":{"manifest":{"name":"Pool Math (Trouble Free Pool)"},"description":"Pool Math for Home Assistant","domain":"poolmath","etag_releases":"W/\"10cda4605e10eb7e14bcb37781a097cda4d3a4702e6159b5adf2798bd62a4207\"","etag_repository":"W/\"38799f98bbadb5396c80af3b125e25a1a1673b95200af334ff76897e2d20d3bc\"","full_name":"rsnodgrass/hass-poolmath","last_commit":"46d4d8b","last_updated":"2024-03-26T19:35:39Z","last_version":"0.2.5","manifest_name":"Pool Math (Trouble Free Pool)","open_issues":4,"stargazers_count":23,"topics":["pool","swimming-pool"],"last_fetched":1711491579.535148},"190927503":{"manifest":{"name":"Spa Client"},"description":"Home Assistant integration - Spa Client","domain":"spaclient","etag_releases":"W/\"1d3dcff8bf718f6c7ad63828e76fc64edbd66df9e8eb1e638f34c54ebb66876d\"","etag_repository":"W/\"0ae42187f0eea71b7da2f71cfe9a6ef7ca4e596b1fb93c2f5752b00c889fa44e\"","full_name":"plmilord/Hass.io-custom-component-spaclient","last_commit":"744339c","last_updated":"2024-02-10T19:05:48Z","last_version":"v2.82","manifest_name":"Spa Client","open_issues":4,"stargazers_count":47,"topics":["balboa","bwa","spaclient"],"last_fetched":1712096463.927885},"447878635":{"manifest":{"country":["RU"],"name":"Yandex weather"},"description":"Yandex weather intergration for Home Assistant","downloads":4694,"domain":"yandex_weather","etag_releases":"W/\"7d8153a003bbbf52a8af903d738902119a3c3ac5e0e06ad178c612735ba77202\"","etag_repository":"W/\"e6849d4f08899021a85f462ddefa18ea82528f153e0b2c1ca5798c141985e13d\"","full_name":"IATkachenko/HA-YandexWeather","last_commit":"f92b39c","last_updated":"2024-03-30T19:03:58Z","last_version":"v3.1.3","manifest_name":"Yandex Weather","open_issues":10,"stargazers_count":182,"topics":["weather","yandex-weather"],"last_fetched":1712218823.556191},"594842145":{"manifest":{"name":"NPM Switches"},"description":"Home Assistant HACs repository that provides switches to enable or disable Nginx Proxy Manager proxies.","domain":"npm_switches","etag_releases":"W/\"4993962cbac384cd73ce8577fe42110935bb3feb039174c27967c70546be5c67\"","etag_repository":"W/\"7df5973195529a9fe22be328c7a27154586a165f1ae3b35640e75bcd8284d0e7\"","full_name":"InTheDaylight14/nginx-proxy-manager-switches","last_commit":"983b981","last_updated":"2023-10-23T15:22:47Z","last_version":"v1.0.2","manifest_name":"NPM Switches","open_issues":2,"stargazers_count":13,"topics":["nginx-proxy-manager"],"last_fetched":1711995560.977088},"358585486":{"manifest":{"name":"Multiscrape"},"description":"Home Assistant custom component for scraping (html, xml or json) multiple values (from a single HTTP request) with a separate sensor/attribute for each value. Support for (login) form-submit functionality.","domain":"multiscrape","etag_releases":"W/\"54a7ad1e817049d3ff6b20f2096d7c79a090b6eae74127391e782d3aedf5520d\"","etag_repository":"W/\"7467bb498be73cfb8f98bc2600a6d020b3002e63952ce682cdf43c3401026075\"","full_name":"danieldotnl/ha-multiscrape","last_commit":"178dd1c","last_updated":"2024-04-04T07:55:55Z","last_version":"v7.0.0","manifest_name":"Multiscrape scraping component","open_issues":20,"stargazers_count":218,"topics":["rest","scrape","scraper","scraping"],"last_fetched":1712225703.61978},"319401286":{"manifest":{"country":["PT"],"name":"Rademacher HomePilot Bridge"},"description":"This custom integration provides access to Rademacher Devices connected to a HomePilot (or Start2Smart) bridge.","downloads":1961,"domain":"rademacher","etag_releases":"W/\"4b7256f609bccd99e4cd4f3853ffc4368fd3e20a0fdb25c6a5729a733af2eff4\"","etag_repository":"W/\"91f1020024c0975305ce0a4c396aa9f993c6cd6482a70c6deedc36b88231a05b\"","full_name":"peribeir/homeassistant-rademacher","last_commit":"723c537","last_updated":"2024-04-04T09:10:06Z","last_version":"v2.1.1","manifest_name":"Rademacher Homepilot","open_issues":16,"stargazers_count":48,"topics":["homepilot","iot","rademacher"],"last_fetched":1712225972.241827},"688502429":{"manifest":{"name":"JURA Coffee Machines"},"description":"Home Assistant custom component for control Jura Coffee Machines via Bluetooth module","domain":"jura","etag_releases":"W/\"0e34bad1832b67eacd1c5666c35623582144738154fddc21db7fea21e612bcd7\"","etag_repository":"W/\"8893f923ac514d95ea6b43665affcd5481a5c220cd0744f86629e2a666b947ec\"","full_name":"AlexxIT/Jura","last_commit":"72e83c2","last_updated":"2024-02-18T16:18:08Z","last_version":"v1.0.2","manifest_name":"JURA Coffee Machines","open_issues":6,"stargazers_count":37,"topics":["bluetooth","jura"],"last_fetched":1711304219.709961},"349455097":{"manifest":{"name":"Ubee Router"},"description":"This platform integrates Ubee Routers into Home Assistant.","domain":"ubee","etag_repository":"W/\"2ed738268a619498aad5bff5d66938350523e22794bf690df0a2215b8d5596d1\"","full_name":"KevinHaendel/ha-ubee","last_commit":"fe20966","last_updated":"2023-10-16T20:25:09Z","manifest_name":"Ubee Router","stargazers_count":2,"topics":["ubee"],"last_fetched":1697494568.814365},"419786466":{"manifest":{"name":"SolarEdge Modbus Multi"},"description":"Home Assistant integration for SolarEdge inverters with Modbus/TCP. For single or multiple inverters, meters, and batteries.","domain":"solaredge_modbus_multi","etag_releases":"W/\"0c7f6f0d93726024e3f7da69ea8e9d63d2cd5e941b85b9ce08f0d439c0b59ac6\"","etag_repository":"W/\"5f23cfffd8ab3dc776a91efa1d551a8dcec8f95f6c4cea2442d890462ffb9268\"","full_name":"WillCodeForCats/solaredge-modbus-multi","last_commit":"e20a177","last_updated":"2024-04-02T20:05:38Z","last_version":"v2.4.13","manifest_name":"SolarEdge Modbus Multi Device","open_issues":10,"stargazers_count":140,"topics":["modbus-tcp","solaredge","solaredge-inverter"],"last_fetched":1712096550.205526},"504880554":{"manifest":{"name":"CyclePay for ESD/Hercules Laundry Rooms"},"description":"Home Assistant Integration for ESD/Hercules CyclePay Laundry Rooms","domain":"cyclepay","etag_releases":"W/\"ae336524693a2c1934ca009a64f3568e296bee03c189cae128b580624ce8e983\"","etag_repository":"W/\"33c965d6bdf1a4a184a9c964fb129541ce3ec12ed6eac6cf22f42a2ff88221f1\"","full_name":"elahd/ha-cyclepay","last_commit":"e056e12","last_updated":"2024-03-25T17:03:02Z","last_version":"v0.1.8","manifest_name":"CyclePay for ESD/Hercules Laundry Rooms","open_issues":2,"stargazers_count":3,"topics":["laundry"],"last_fetched":1711390757.700634},"247566230":{"manifest":{"country":["FR"],"name":"Next Rocket Launch"},"description":"The Next Rocket Launch sensor platform allows you to monitor the next rocket launch from Teamup.","domain":"next_rocket_launch","etag_releases":"W/\"a159bcb5f6f97a6449fa411d19cfc948efac9120dd736c10f0e3c3ad72e96313\"","etag_repository":"W/\"5057c5a47c07fcff7ea75efb84107acbac5761cb42c3764fc43eba24683a81d3\"","full_name":"Verbalinsurection/next_rocket_launch","last_commit":"0c04dbe","last_updated":"2023-12-05T09:44:42Z","last_version":"V1.0.6","manifest_name":"Next Rocket Launch","stargazers_count":9,"topics":["rocket"],"last_fetched":1701771769.057722},"295627573":{"manifest":{"name":"Fortnite Stats"},"description":"This is a Home-Assistant custom component that pulls Fortnite stats using the python API library from the site fortnitetracker.com","downloads":22,"domain":"fortnite","etag_releases":"W/\"a2670284d3a60e2c429a90b99b60d8dab0016c3fc2b99934dd5bf40c9ea1cede\"","etag_repository":"W/\"0b3841475fb7d1fe3660fafaa0a49ceb6b31db621eb2cda7153bf81400daa236\"","full_name":"michaellunzer/Home-Assistant-Custom-Component-Fortnite","last_commit":"1b6effa","last_updated":"2021-11-03T06:00:38Z","last_version":"v0.1.2","manifest_name":"Fortnite Stats","open_issues":3,"stargazers_count":5,"topics":["fortnite","fortnite-api","fortnite-stats"],"last_fetched":1711995668.654894},"556789449":{"manifest":{"name":"WhatsPie"},"description":"Send HomeAssistant Notifications to WhatsApp using WhatsPie","domain":"whatspie","etag_repository":"W/\"81954ced46168ece3ee348030128617230e2eadddf27f17a51f21afbe8c973d0\"","full_name":"arifwn/homeassistant-whatspie-integration","last_commit":"1d6d4f1","last_updated":"2022-11-22T10:23:37Z","manifest_name":"Send WhatsApp Messages via WhatsPie","open_issues":3,"stargazers_count":3,"topics":["whatsapp","whatspie"],"last_fetched":1710464123.355107},"254203764":{"manifest":{"name":"Bunq balance sensor"},"description":"Home assistant custom component to provide monetary account balance sensors for Bunq","domain":"bunq","etag_repository":"W/\"55fa522e9fe71ddd2bf6667cbaee2d1eb6ebcedeba7c622bcd6aa9c9451bb6ad\"","full_name":"ben8p/home-assistant-bunq-balance-sensors","last_commit":"11bd99b","last_updated":"2024-02-23T12:55:29Z","manifest_name":"bunq","open_issues":2,"stargazers_count":15,"topics":["bunq","bunq-api"],"last_fetched":1712081794.237629},"712412324":{"manifest":{"country":["NO"],"name":"OSO Energy HACS"},"description":"This is an OSO Energy integration for the Home Assistant Community Store","domain":"osoenergy_community","etag_releases":"W/\"386bf97f5fc7eae408f48dbe16c29d5850371e260a63ce80e138e851ad79bbdb\"","etag_repository":"W/\"1122b47236ad57323c1cd8df562ce9681f63e171f64b510b5722fe3556c924ba\"","full_name":"osohotwateriot/osoenergy_community","last_updated":"2023-12-05T14:52:53Z","last_version":"v1.1.2","manifest_name":"OSO Energy HACS","stargazers_count":3,"topics":["osoenergy"],"last_fetched":1707675644.480171},"325755578":{"manifest":{"name":"MercedesME 2020"},"description":"Custom Component to integrate MercedesME devices into Home-Assistant","downloads":3076,"domain":"mbapi2020","etag_releases":"W/\"3628a267893877083fa599b7f2f97cd00c413c44a4b282df33f686c009fd456d\"","etag_repository":"W/\"104bfea7e8d2a4ce79266912360306f7419e9eb59e49ff058ec9482ee90c63c0\"","full_name":"ReneNulschDE/mbapi2020","last_commit":"c943d28","last_updated":"2024-04-04T10:13:13Z","last_version":"v0.12.0","manifest_name":"MercedesME 2020","open_issues":4,"stargazers_count":131,"topics":["car","home-assistant-component","lock","switch"],"last_fetched":1712226003.919672},"250688607":{"manifest":{"name":"Steam Wishlist"},"description":"A home assistant integration that monitors games on sale on your Steam wishlist.","domain":"steam_wishlist","etag_releases":"W/\"4631aa4e5034fbd28962d886ef5e63b5603008e1ae2e2dee4a6070299f501b69\"","etag_repository":"W/\"0d277e6c5fba80c76b5d42e74c1f87e87ca88b8047ebaf9d41906ab14c308222\"","full_name":"boralyl/steam-wishlist","last_commit":"c259465","last_updated":"2024-04-04T02:04:07Z","last_version":"v2.2.6","manifest_name":"Steam Wishlist","open_issues":4,"stargazers_count":20,"topics":["steam"],"last_fetched":1712197387.987301},"296028613":{"manifest":{"name":"D-Link Presence / device_Tracker"},"description":"A D-Link AP/router device tracker for Home Assistant","domain":"dlink_presence","etag_repository":"W/\"34bbac04e38f6a9ec47dc0e6ad2c7670c7f9b9ab99e3b5772e8cf21ad4035f9f\"","full_name":"ayavilevich/homeassistant-dlink-presence","last_commit":"1e273ca","last_updated":"2021-08-09T11:14:30Z","manifest_name":"D-Link Presence","open_issues":1,"stargazers_count":9,"topics":["d-link","dlink","presence-detection"],"last_fetched":1695025034.535666},"180651910":{"manifest":{"name":"Zaptec EV charger"},"description":"zaptec charger custom component for home assistant","domain":"zaptec","etag_releases":"W/\"a750a53d45d54a7c44e529f2efd58fd8642b199dded28acff84b5acb1405a4ee\"","etag_repository":"W/\"fde47dd6d1a5dad396e6454a3793c6e43faae80b232656422f53aac05add3587\"","full_name":"custom-components/zaptec","last_commit":"c0c4bd2","last_updated":"2024-03-26T21:13:31Z","last_version":"v0.7.1","manifest_name":"zaptec","open_issues":17,"stargazers_count":51,"topics":["api","zaptec"],"last_fetched":1712060753.554898},"362145464":{"manifest":{"name":"Multizone Controller"},"description":"Integration that creates a multi-zone volume controller for media_players in Home Assistant","domain":"multizone_controller","etag_releases":"W/\"c5045731d1c63536b0b63837430bafe31f623049c6921aa881d4449ee426120d\"","etag_repository":"W/\"fa2d94648ac4bcdeaf3743557bf19f92cf1e9a4fef32b37057db1ca7571537e1\"","full_name":"Petro31/ha-integration-multizone-controller","last_commit":"0593a22","last_updated":"2023-07-08T11:11:56Z","last_version":"1.3","manifest_name":"Multizone Controller","open_issues":2,"stargazers_count":14,"topics":["media-players","multizone-controller","volume-increment","zone-volume"],"last_fetched":1706595778.019491},"387116237":{"manifest":{"name":"XMRIG integration"},"description":"XMRIG integration for homeassistant","domain":"xmrig","etag_releases":"W/\"fc56bd7c35b40f0f4d23183f76c4636fbbd0acdae60b11c557eb96a0f05ad6a5\"","etag_repository":"W/\"12b01dbdb85d7bf7ab02d4ebeba1fcad9c266cb5b990d70a5adf68f94965c646\"","full_name":"hwmland/homeassistant-xmrig","last_commit":"3f83e94","last_updated":"2022-04-26T18:13:19Z","last_version":"v0.3.0","manifest_name":"XMRIG","open_issues":2,"stargazers_count":4,"topics":["cryptocurrency","monero-mining","xmrig"],"last_fetched":1701779274.546592},"524376939":{"manifest":{"country":["NL"],"name":"One Smart Control"},"description":"Home Assisttant integration for One Smart Control server","domain":"onesmartcontrol","etag_releases":"W/\"640fd50649c487b141c1e8697b576dcdeddab8ded3f0b2e2cda69869145a23a8\"","etag_repository":"W/\"117497fcb22e62f4b87f4dbe1f257d898b0d891889c2e53896c875030e50a08f\"","full_name":"PimDoos/onesmartcontrolha","last_commit":"25ab83b","last_updated":"2024-03-28T10:21:02Z","last_version":"v0.4.4","manifest_name":"One Smart Control","open_issues":3,"stargazers_count":4,"topics":["home-assistant-custom-component","one-smart-control","socket"],"last_fetched":1711629015.589979},"406939721":{"manifest":{"country":["EN"],"name":"Hik-Connect"},"description":"A Home Assistant integration to communicate with Hikvision smart doorbells via Hik-Connect cloud.","domain":"hikconnect","etag_releases":"W/\"e8e8d803869955931921ccdbe78dc2b3d18c9df693d28036c26b56b5688ce1d4\"","etag_repository":"W/\"9c236aac0e9028d8cce5cdd7e86e3456fcdb649f45a3c24fc0f0f2ae9a9a7bcb\"","full_name":"tomasbedrich/home-assistant-hikconnect","last_commit":"284893b","last_updated":"2023-10-12T06:41:07Z","last_version":"2.3.0","manifest_name":"Hik-Connect","open_issues":5,"stargazers_count":38,"topics":["hikvision"],"last_fetched":1711491627.618164},"410867791":{"manifest":{"name":"Microsoft Edge TTS"},"description":"\ud83d\udde3\ufe0f Microsoft Edge TTS for Home Assistant, no need for app_key","domain":"edge_tts","etag_repository":"W/\"e2a6eec85bc6ce7316e23e8e69dbf4821dd7d2c7d0bf907db188e94f3b9d629a\"","full_name":"hasscc/hass-edge-tts","last_commit":"7d129a5","last_updated":"2023-12-18T16:17:25Z","manifest_name":"Microsoft Edge TTS","open_issues":10,"stargazers_count":294,"topics":["tts"],"last_fetched":1712132381.529456},"234118477":{"manifest":{"country":["NL"],"name":"Afvalinfo"},"description":"Provides Home Assistant sensors for multiple Dutch waste collectors. The idea is to add more cities and features in the future.","domain":"afvalinfo","etag_releases":"W/\"e824087a1ec246f6a5a14bd2aebd45d5b357313437250ead673c0532dfeb4605\"","etag_repository":"W/\"7995879f0ae5be8668f701478ee4c569654045a00cf381580336998bd4277a62\"","full_name":"heyajohnny/afvalinfo","last_commit":"ee5c213","last_updated":"2024-01-25T08:24:05Z","last_version":"v2.0.8","manifest_name":"Afvalinfo","open_issues":3,"stargazers_count":91,"last_fetched":1712218813.127634},"403062943":{"manifest":{"name":"battery_consumption"},"description":"Home Assistant Component to compute battery consumption","domain":"battery_consumption","etag_releases":"W/\"e41dc3f338beb5375bfe32f44c0eb3def5423a4abd93a8fe8eca3d4c8fcc18a5\"","etag_repository":"W/\"883dc01c16c4896c2908de9fb62e50380cf6936be13d5714ba484874e2784748\"","full_name":"jugla/battery_consumption","last_commit":"88523bc","last_updated":"2023-05-13T21:56:34Z","last_version":"V1.0.4","manifest_name":"battery_consumption","stargazers_count":13,"topics":["battery","consumption"],"last_fetched":1708131460.46452},"362214884":{"manifest":{"name":"Redfin"},"description":"Redfin property estimate Sensor for Home Assistant","domain":"redfin","etag_releases":"W/\"fd1946f0a17da553ca8c821c8fbb0fb6ae4d6f0a4735d387a9894ae50a7dcdf5\"","etag_repository":"W/\"2aa4af0500a0f07ace3775def4d6cb1bf2582484d491346639233e4fd8e8758a\"","full_name":"dreed47/redfin","last_commit":"ae9c263","last_updated":"2023-08-19T01:57:33Z","last_version":"v1.1.5","manifest_name":"Redfin","open_issues":4,"stargazers_count":15,"topics":["real-estate","redfin"],"last_fetched":1711916136.177266},"442225646":{"manifest":{"country":["GB"],"name":"London TfL"},"description":"Simple sensor for Home Assistant to retrieve departures from Transport for London stations.","domain":"london_tfl","etag_releases":"W/\"6ccb3bd1be48376051d30e195e323d069ca304620968b2cef83703861d05edfd\"","etag_repository":"W/\"0eb87a8c637ec1c7918ecc7136388e5a03a1a232bbaf440ba1650117bd739a61\"","full_name":"morosanmihail/HA-LondonTfL","last_commit":"37bf6a8","last_updated":"2023-10-18T16:49:13Z","last_version":"v0.4.2","manifest_name":"London TfL","stargazers_count":17,"topics":["london","tfl","transport"],"last_fetched":1707070934.741946},"262017793":{"manifest":{"name":"Switchbot_press"},"description":"This is a simple project that manage the Switchbot ( https://amzn.to/3dnliBD ) that has only the \"press\" ability in Home Assistant.","domain":"switchbot_press","etag_repository":"W/\"499ddb62c8a0581cac6c85a19d95fe294b770548aa0cb9216d3881f07db48ae4\"","full_name":"cagnulein/switchbot_press","last_commit":"dcf4cff","last_updated":"2022-07-11T07:32:35Z","manifest_name":"SwitchBot_press","open_issues":1,"stargazers_count":14,"topics":["python3","switchbot"],"last_fetched":1705918554.035462},"580805288":{"manifest":{"country":["NO"],"name":"N\u00e5r kommer posten"},"description":"Posten integrasjon som trigger dagen n\u00e5r posten kommer: https://www.posten.no/levering-av-post","domain":"posten","etag_releases":"W/\"1de4b12783f56d53f09910911f2bd4e7b599286fa0955e33ba0e8aadca8cbca6\"","etag_repository":"W/\"8f58fd10f02af288129a7b31bff22794f52036aef67d822a260711eaa0c0d1b4\"","full_name":"BobTheShoplifter/HomeAssistant-Posten","last_commit":"42933a3","last_updated":"2024-03-27T05:12:18Z","last_version":"v0.1.8","manifest_name":"N\u00e5r kommer Posten","open_issues":2,"stargazers_count":35,"topics":["posten","posten-packages"],"last_fetched":1711520217.5124},"348464316":{"manifest":{"name":"Magic Switchbot"},"description":"Magic Switchbot integration component for Home Assistant","domain":"magicswitchbot","etag_releases":"W/\"8092c1bd4ffef37e76c1b85b777aeca2d753d9fa97f40d8d1552702a5284c2b1\"","etag_repository":"W/\"3eb62918abce92ab9e65f1b4d19fa5a8852bf9387fd779e4c11b260da1eed815\"","full_name":"ec-blaster/magicswitchbot-homeassistant","last_commit":"980ddab","last_updated":"2022-10-08T15:57:58Z","last_version":"v1.1.1","manifest_name":"Magic Switchbot","stargazers_count":15,"topics":["magicswitchbot","switches"],"last_fetched":1695190737.558881},"410667735":{"manifest":{"name":"Reaper DAW"},"description":"Reaper DAW custom integration for Home Assistant","downloads":210,"domain":"reaper","etag_releases":"W/\"978061a8545946d26aface83e9f9ebb93caad583760e4ac104949ceae0b6c70b\"","etag_repository":"W/\"63169a50b9a0a93feb06d16d219696ad041769db18ebb85c9ea41dd9beedc461\"","full_name":"kubawolanin/ha-reaper","last_commit":"cc4ba41","last_updated":"2021-11-12T16:36:27Z","last_version":"0.2.2","manifest_name":"Reaper DAW","open_issues":4,"stargazers_count":16,"topics":["daw","digital-audio-workstation","reaper"],"last_fetched":1709633931.769728},"259867685":{"manifest":{"country":["SE"],"name":"Swedish Public Transport Sensor (HASL)"},"description":"Swedish Public Transport Sensor (HASL). Formerly named HomeAssistant SL Sensor","domain":"hasl3","etag_releases":"W/\"82f3ff8ce440d44e4a39409955b57fa0425549d2cf0dbaacf6b6e3f0157775b5\"","etag_repository":"W/\"9537ebdd19229b5098ec03814c769e2982efbc17fe0c6d703b424f4b657657db\"","full_name":"hasl-sensor/integration","last_commit":"aaa82ae","last_updated":"2024-03-18T18:28:15Z","last_version":"3.1.1","manifest_name":"Swedish Public Transport Sensor (HASL)","open_issues":12,"stargazers_count":31,"topics":["ha-sensor-sl","hasl","hasl3","haslv3","sl-sensor","stockholms-lokaltrafik"],"last_fetched":1711707430.271058},"438036391":{"manifest":{"name":"Ariston NET"},"description":"Ariston NET remotethermo integration for Home Assistant based on API","downloads":1437,"domain":"ariston","etag_releases":"W/\"7143aa56ba6224fdd2a453bfd1f23b2cac1877283254b61a8842c3eeb2af771e\"","etag_repository":"W/\"bb662a8fdd79cca01c76a00d453f5634595c248c173e9f298a49e5356de5909d\"","full_name":"fustom/ariston-remotethermo-home-assistant-v3","last_commit":"5f158ca","last_updated":"2024-03-19T11:02:33Z","last_version":"v0.19.0","manifest_name":"Ariston","open_issues":30,"stargazers_count":118,"topics":["ariston","ariston-net","cloud"],"last_fetched":1712192353.683412},"180032210":{"manifest":{"name":"Thermal Comfort"},"description":"Thermal Comfort sensor for HA (absolute humidity, heat index, dew point, thermal perception)","downloads":20,"domain":"thermal_comfort","etag_releases":"W/\"db957bc83c48d0d086b961320805c351f31b0dd4a4812ffe7746ea5174e1b944\"","etag_repository":"W/\"8b6e366699c3420165cb51554c5a3d13ee8891ceddbb916263faf9edc7e98943\"","full_name":"dolezsa/thermal_comfort","last_commit":"43b5d73","last_updated":"2024-01-26T12:46:24Z","last_version":"2.2.2","manifest_name":"Thermal Comfort","open_issues":27,"stargazers_count":512,"topics":["absolute-humidity","comfort-model","comfort-zone","dew-point","dew-point-perception","heat-index","thermal-comfort","thermal-perception","thermal-stress"],"last_fetched":1712096210.034087},"401454435":{"manifest":{"name":"battery_sim"},"description":"Home assistant home battery simulator - allows you to model how much energy you would save with a home battery","domain":"battery_sim","etag_releases":"W/\"a7bb3e54e1e1b2fced92445e5801b0a30f5a6abaa4db92f5c1feef17ffcbe2b8\"","etag_repository":"W/\"741b191ef51768954850ea209f59632522ea0c602c4391ccd63e507778d7abd6\"","full_name":"hif2k1/battery_sim","last_commit":"225bb65","last_updated":"2024-02-20T21:39:20Z","last_version":"Battery_sim_1.3.5","manifest_name":"Battery Simulation","open_issues":9,"stargazers_count":95,"topics":["energy-storage","environmental"],"last_fetched":1711390811.956828},"245267534":{"manifest":{"name":"Virtual Components"},"description":"Virtual Components for Home Assistant","domain":"virtual","etag_releases":"W/\"226640d430cebf3646a6aa8724665d70d0a096af6fa7ed29fe560a216c08bfac\"","etag_repository":"W/\"423ccd269bd86db16a9a7100cee23a945d62a4b28904d93550411ed64d4ad286\"","full_name":"twrecked/hass-virtual","last_commit":"6482e19","last_updated":"2024-02-04T22:48:23Z","last_version":"v0.8.0.1","manifest_name":"Virtual Components","open_issues":41,"stargazers_count":132,"topics":["virtual"],"last_fetched":1711138860.088375},"232077394":{"manifest":{"name":"Chargeamps"},"description":"Home Assistant Component for Chargeamps","domain":"chargeamps","etag_releases":"W/\"a6500cfef1914577f6b72599428f34e50d9cd95c248bd56e307b20f425756c85\"","etag_repository":"W/\"332ae7238c0197ea6389c66055ca687d398f10fa0d3e3fc881f732677c14a815\"","full_name":"kirei/hass-chargeamps","last_commit":"443b50d","last_updated":"2024-02-02T05:17:26Z","last_version":"v1.9.3","manifest_name":"Chargeamps","open_issues":6,"stargazers_count":24,"topics":["chargeamps"],"last_fetched":1712009843.024442},"651597909":{"manifest":{"name":"pfSense gateways monitoring"},"description":"Monitor and react on your pfSense gateway's status with Home Assistant.","domain":"pfsense_gateways","etag_releases":"W/\"fb94bfbf69dfd0444d6c937e016ff53ee3cbcae4182b4968011c31c1774715b1\"","etag_repository":"W/\"5059e59099915de586237c5de0ab838af6f3d59208954103d9bbf9edc30907c6\"","full_name":"sdrapha/home-assistant-custom-components-pfsense-gateways","last_commit":"7744d1a","last_updated":"2023-11-14T22:55:47Z","last_version":"v1.1.1","manifest_name":"pfSense Gateways","open_issues":1,"stargazers_count":2,"topics":["hassio-integration","pfsense"],"last_fetched":1700010232.605862},"443140011":{"manifest":{"name":"Ambient Weather Station - Local"},"description":"Enables local support for Ambient Weather personal weather stations.","domain":"awnet_local","etag_releases":"W/\"29eedc9e857e2d129ce824354d1ddda2238a6000657b17cbb4df2cc9399d80cf\"","etag_repository":"W/\"24a9808221bc3d9cfa4ae5b2873703fa3769b6d4ea474d8fae7bf4b4e448a6ec\"","full_name":"tlskinneriv/awnet_local","last_commit":"76476bc","last_updated":"2023-12-05T05:25:00Z","last_version":"v1.2.0","manifest_name":"Ambient Weather Station - Local","stargazers_count":22,"topics":["ambient-weather","ambient-weather-api"],"last_fetched":1708784291.742736},"183989659":{"manifest":{"name":"NHL API"},"description":"NHL Stats API Integration Into Home Assistant","domain":"nhl_api","etag_releases":"W/\"c7c083687449b256deb78555cf50224aebe9a84c2c2bcf4acc1e2e3403495049\"","etag_repository":"W/\"3de565f233b413bb917379f702ffc1f99354346f61a362963e38385322ede962\"","full_name":"JayBlackedOut/hass-nhlapi","last_commit":"2fd2ec0","last_updated":"2024-03-10T18:17:36Z","last_version":"v0.11.5","manifest_name":"NHL API","stargazers_count":64,"last_fetched":1711520401.162751},"598313217":{"manifest":{"country":["BE"],"name":"MijnTuin"},"description":"MijnTuin.org Home Assistant custom component HACS to manage garden plants and see activities for your garden","domain":"mijntuin","etag_releases":"W/\"45af5371729d2f3798e99d2f4ada630b6d38456dd24e2d56f2e5216ed44d19de\"","etag_repository":"W/\"06f531929508ae6dd2e78924c7b2f1d242b1ce8d7e9ab4d6e5a54ef263378a97\"","full_name":"myTselection/MijnTuin","last_commit":"50f93a6","last_updated":"2024-04-03T15:45:48Z","last_version":"1.6.4","manifest_name":"MijnTuin","open_issues":2,"stargazers_count":12,"topics":["garden","gardening"],"last_fetched":1712168514.094903},"541834155":{"manifest":{"name":"PetSafe"},"description":"Integrate PetSafe Smartfeed feeders an Scoopfree litter boxes into Home Assistant.","domain":"petsafe","etag_releases":"W/\"ba4c87f70400921b8b2b7f0b84b41af2ccfca178b4f9090be3e329a4b9721a06\"","etag_repository":"W/\"1109f8ac0e2f3618c6e3d845b617e9c3701ec060409a4ec85ff7446f5efb27cc\"","full_name":"dcmeglio/homeassistant-petsafe","last_commit":"bfc2df2","last_updated":"2023-01-29T14:46:05Z","last_version":"1.3.0","manifest_name":"PetSafe","open_issues":5,"stargazers_count":23,"topics":["cats","dogs","feeder","litterbox","petsafe"],"last_fetched":1707113890.919544},"270386127":{"manifest":{"name":"Comelit SimpleHome/Vedo integration for Home Assistant"},"description":"With Comelit Hub/Vedo integration, you can connect your Home Assistant instance to Comelit Simple Home and Vedo systems.","domain":"comelit","etag_releases":"W/\"68ca25057169d9e31b895bea91dd55015db3fb213505e7210b4e9ba7c56da6a1\"","etag_repository":"W/\"0aa17aa04bba89c3ca399af6da269711265fad2ed6c97acac0fa6d67e05fa2ff\"","full_name":"gicamm/homeassistant-comelit","last_commit":"89ab6ec","last_updated":"2023-06-09T23:42:31Z","last_version":"0.9.5","manifest_name":"Comelit SimpleHome/Vedo","open_issues":4,"stargazers_count":19,"topics":["automation","comelit","comelit-hub","comelit-vedo","vedo"],"last_fetched":1710339313.717179},"238568340":{"manifest":{"name":"Freebox Player"},"description":"Custom Component for Home Assistant, enable to remote Freebox Player","domain":"freebox_player","etag_releases":"W/\"ae1cc1bdcc7a7390305d243aeccc958be33cfa70cb0dd55e1f87858c7b03696b\"","etag_repository":"W/\"582a36718b8707eb5fd2c3b8b611a839d8de560c8ac260c43abcee09d1ee1ede\"","full_name":"Pouzor/freebox_player","last_commit":"9f0390b","last_updated":"2021-05-12T23:52:40Z","last_version":"1.0.6","manifest_name":"Freebox Player","open_issues":7,"stargazers_count":18,"topics":["freebox"],"last_fetched":1708691308.826391},"266557774":{"manifest":{"name":"proscenic 790T vacuum"},"description":"proscenic 790T intergration for home assistant","downloads":33,"domain":"proscenic","etag_releases":"W/\"6f36ba923c042234b209a0726cbc141b7752cf530004c7f279a775575695262e\"","etag_repository":"W/\"00a2a4ad4647c9541100831f0adeb384cd01159db8ea70b3d4f507fdcb6fb7d3\"","full_name":"deblockt/hass-proscenic-790T-vacuum","last_commit":"92148ab","last_updated":"2023-10-05T19:07:28Z","last_version":"0.0.12","manifest_name":"proscenic-vacuum","open_issues":6,"stargazers_count":17,"topics":["790t","proscenic","vacuum","vacuum-cleaner"],"last_fetched":1699784062.400475},"353966616":{"manifest":{"country":["GR"],"name":"OpenWeatherMap All"},"description":"Home Assistant custom component combining multiple OpenWeatherMap API calls","domain":"openweathermap_all","etag_repository":"W/\"86062c538a2ed3b263703e820a16602ecb5bafa8eea87d819ce725e4c5d8bbc4\"","full_name":"viktak/ha-cc-openweathermap_all","last_commit":"a626c3e","last_updated":"2023-01-16T08:26:19Z","manifest_name":"OpenWeatherMap All API","open_issues":1,"stargazers_count":20,"topics":["openweathermap"],"last_fetched":1710246606.122997},"402333014":{"manifest":{"name":"openWB MQTT"},"description":"Custom component for home assistant supporting openWB wallbox","domain":"openwbmqtt","etag_releases":"W/\"71be37a4619ff25620cfa2865a32e838c7539663cdd3bd6bfe1988e4ca511c8e\"","etag_repository":"W/\"328b5a3401027535f5798e7ead83dc6bdfb66b2095778d91040895850a0a5478\"","full_name":"a529987659852/openwbmqtt","last_commit":"85798c5","last_updated":"2024-02-28T09:41:52Z","last_version":"v0.5.12","manifest_name":"openWB over MQTT","open_issues":8,"stargazers_count":35,"topics":["mqtt"],"last_fetched":1709295716.464928},"573233876":{"manifest":{"name":"Switch Manager"},"description":"Switch manager is a centralised component to handle button pushes for your wireless switches. This includes anything passed through the event bus. The component relies on switch blueprints which is easily made to allow GUI configuration of your switches and their button pushes. This helps remove clutter from the automations.","domain":"switch_manager","etag_releases":"W/\"08ef5eab0771a46fcfcc6f374d88ed0d37a2091e7558a6eb0f499f61cdff3632\"","etag_repository":"W/\"401d34c31701ff62855eed8a50b49e4619f94b58e77a64357e134ee4c0702906\"","full_name":"Sian-Lee-SA/Home-Assistant-Switch-Manager","last_commit":"1935b11","last_updated":"2024-04-02T13:53:37Z","last_version":"v1.3.3","manifest_name":"Switch Manager","open_issues":3,"stargazers_count":182,"topics":["component","script","switch-manager"],"last_fetched":1712197783.513967},"419381725":{"manifest":{"name":"Huawei Solar"},"description":"Home Assistant integration for Huawei Solar inverters via Modbus","domain":"huawei_solar","etag_releases":"W/\"761e20c6153f3ca7fc062865a0b3df2f7bdbaecbe584d05313e97f6445057465\"","etag_repository":"W/\"1e04c7fed4cf3f31ad76c7bd9b28a3c13c056123b545359abdba04e6fb2cbe19\"","full_name":"wlcrs/huawei_solar","last_commit":"76b3751","last_updated":"2024-04-04T06:08:55Z","last_version":"1.3.3","manifest_name":"Huawei Solar","open_issues":11,"stargazers_count":442,"topics":["home-assistant-integration","huawei","huawei-solar","modbus","modbus-rtu","modbus-tcp","solar-energy"],"last_fetched":1712219085.016558},"373750934":{"manifest":{"country":["TW"],"name":"Taipower Bimonthly Energy Cost"},"description":"Calculate Taipower (Taiwan Power Company) bi-monthly bill amount from kWh sensor on Home Assistant.","domain":"taipower_bimonthly_cost","etag_releases":"W/\"666381035299b3114b90812b817f406d8ccec5f82ba54354ff9031bd2dc9050a\"","etag_repository":"W/\"e4e305223319a2ce59c1076208a98a9e9c74048f541b2f51cee5a5f0bd30e9b5\"","full_name":"cnstudio/Taipower-Bimonthly-Energy-Cost-homeassistant","last_commit":"6729d1f","last_updated":"2023-04-03T15:12:59Z","last_version":"v0.52.1","manifest_name":"TaiPower Bimonthly Energy Cost","stargazers_count":59,"topics":["bill","bimonthly","power","taipower"],"last_fetched":1711527501.805217},"382905556":{"manifest":{"name":"Cover Time Based Synced"},"description":"\u231b Time-based cover. Install it via HACS.","domain":"cover_time_based_synced","etag_releases":"W/\"72c2f41c3233f8963f4e22021e1d8b91ffa20a978ae167ff79b6a1538d4ea6b6\"","etag_repository":"W/\"6e3a7637679d1c4bc286b526a22688263949e613843f18afa9d646d36ac8bc08\"","full_name":"kotborealis/home-assistant-custom-components-cover-time-based-synced","last_commit":"7098bac","last_updated":"2023-04-18T13:20:55Z","last_version":"v2.1.0","manifest_name":"Cover Time Based Synced","open_issues":9,"stargazers_count":18,"topics":["cover","roller-shutters","service","shutter","trigger"],"last_fetched":1712161206.145284},"305188358":{"manifest":{"name":"Heatmiser Wifi"},"description":"Heatmiser Wifi Home Assistant Component","domain":"heatmiser_wifi","etag_repository":"W/\"8c7f88817e5a7653f95d349be194147254fb2678c1770a1ee84135f0bfc786db\"","full_name":"midstar/heatmiser_wifi_ha","last_commit":"e7da8bc","last_updated":"2022-05-12T14:24:49Z","manifest_name":"Heatmiser Wifi","open_issues":3,"stargazers_count":3,"topics":["climate","heatmiser","homeassisant","thermostat","wifi"],"last_fetched":1697876361.595337},"220678749":{"manifest":{"country":["IT"],"name":"cfr sensor"},"description":"HA Integration for Centro Funzionale Regione Toscana","domain":"cfr","etag_releases":"W/\"8236114fbd32a445a9e760c8fca5fac6f08224eb87e2f0b8c2c6613a0b7e21b5\"","etag_repository":"W/\"89b9f671b39157ac6699ef4ea7c595677cc102766bd8dfe505059fd85a746b2d\"","full_name":"shogunxam/Home-Assistant-custom-components-cfr-toscana","last_commit":"93ade25","last_updated":"2023-03-03T09:27:23Z","last_version":"v0.11","manifest_name":"CFR (Centro Funzionale Regione Toscana)","stargazers_count":4,"last_fetched":1698973335.403692},"490422137":{"manifest":{"name":"IPCamLive"},"description":"IPCamLive integration for Home Assistant","domain":"ipcamlive","etag_releases":"W/\"41157dbd50f8b777dc42ff2aa0ff11ee15f854cd50ef2b62e1bb8d1de607021e\"","etag_repository":"W/\"01bc8e607e8001b91ddffdf0ae14ee6398bb7974aa998b483cc92f987d7b317d\"","full_name":"ddanssaert/home-assistant-ipcamlive","last_commit":"64a5efd","last_updated":"2023-05-11T12:47:38Z","last_version":"v.0.0.1","manifest_name":"IPCamLive","open_issues":4,"stargazers_count":5,"topics":["ipcamera","ipcamlive"],"last_fetched":1709928840.744706},"373101151":{"manifest":{"name":"SunSpec"},"description":"Home Assistant customcomponent for SunSpec modbus devices","domain":"sunspec","etag_releases":"W/\"2ff693159261b24223a8f84f2f04258cc89c0a4d8d6ef675e319eb7c05e92672\"","etag_repository":"W/\"b87d7a76b7929d2dfc58f9aab8b338d9ae70dd79fe0941671db349aba7ec5197\"","full_name":"CJNE/ha-sunspec","last_commit":"1a0991f","last_updated":"2024-03-29T12:30:16Z","last_version":"0.0.25","manifest_name":"SunSpec","open_issues":32,"stargazers_count":56,"topics":["sunspec"],"last_fetched":1712161005.039261},"311536795":{"manifest":{"name":"Frigate"},"description":"Frigate integration for Home Assistant","domain":"frigate","etag_releases":"W/\"d988a1829acf97185b4c35ba6b7462273312f5217f4f8c27795cfafcbded032e\"","etag_repository":"W/\"530c996342c4609d34e1f98d096246e0bcefbede773cd46b824b2bd0b4b8e0d5\"","full_name":"blakeblackshear/frigate-hass-integration","last_commit":"94c5c5f","last_updated":"2024-04-04T06:18:42Z","last_version":"v5.1.0","manifest_name":"Frigate","open_issues":18,"stargazers_count":590,"topics":["ai","camera","frigate","nvr","object-detection"],"last_fetched":1712218653.581369},"603119944":{"manifest":{"country":["ES"],"name":"Tarifa 2.0 TD"},"description":"Componente para Home Assisant para usuarios con tarifa 2.0 TD","downloads":1,"domain":"tarifa_20td","etag_releases":"W/\"2760e875758bb7471b30492b9003318614fea12f864cdfc930dd544488904e7d\"","etag_repository":"W/\"9796a4a69ad8c2c8f991e78e3944fa089dec38a0c3136c33cd8df63411510b9b\"","full_name":"MiguelAngelLV/tarifa_20td","last_commit":"381c210","last_updated":"2024-03-24T20:28:18Z","last_version":"V2.0","manifest_name":"Tarifa 2.0 TD","stargazers_count":19,"topics":["energy-monitor","tarifa"],"last_fetched":1712175610.648401},"121891488":{"manifest":{"name":"Lennox iComfort WiFi Thermostat Integration"},"description":"Home Assistant custom component for controlling Lennox iComfort WiFi and AirEase Comfort Sync thermostats.","domain":"myicomfort","etag_releases":"W/\"cd8675cf9a22d1a6fded646e7219188d40b595bbba83134fb2667c5e43ff9622\"","etag_repository":"W/\"273277afbbd76cd546e16b1605b97be7c24973c39ed4eb26271215b5aa71ef1d\"","full_name":"thevoltagesource/LennoxiComfort","last_commit":"e849b66","last_updated":"2024-01-21T21:24:54Z","last_version":"v3.4.0","manifest_name":"Lennox iComfort WiFI","open_issues":4,"stargazers_count":32,"topics":["icomfort","lennox","thermostat"],"last_fetched":1712192655.143279},"223541049":{"manifest":{"name":"SamsungTV Tizen"},"description":"\ud83d\udcfa HomeAssistant - For Samsung TVs 2016+, Includes SmartThings API and Channel List Support","domain":"samsungtv_tizen","etag_releases":"W/\"8f73fbe03a6b1e6aa4029e8142124af155df22d996b54665357bea230028cfcc\"","etag_repository":"W/\"a548b049f828dafe7ec843337ff34f05a98e010b54d249fb70ba039775e5a973\"","full_name":"jaruba/ha-samsungtv-tizen","last_commit":"6a5c82c","last_updated":"2022-12-31T20:09:24Z","last_version":"v1.6.1","manifest_name":"SamsungTV Tizen","open_issues":89,"stargazers_count":271,"last_fetched":1711678960.117338},"541978646":{"manifest":{"name":"Technische Alternative C.M.I."},"description":"Custom Home Assistant integration to read data from a C.M.I.","domain":"ta_cmi","etag_releases":"W/\"5b263beb711f9d5d2c0a1f4f6fb135e1b1f692d7577e7cba5cd0226f5bfc9920\"","etag_repository":"W/\"fd26ace8cdbf115cfaba342f06fee14f7a0468c7059edd36338cf6d79c432b0f\"","full_name":"DeerMaximum/Technische-Alternative-CMI","last_commit":"088463c","last_updated":"2024-02-16T14:43:39Z","last_version":"v1.9.1","manifest_name":"Technische Alternative C.M.I.","open_issues":4,"stargazers_count":31,"last_fetched":1711995458.76862},"249381778":{"manifest":{"name":"Local Tuya"},"description":"local handling for Tuya devices","domain":"localtuya","etag_releases":"W/\"eb29004dd97a9aaf8f7ec001980e2e3621acfb7da84cd621586e3a38cd708528\"","etag_repository":"W/\"92dc215f9bdb9f4d8670dd3d1aeeace7edbe736a2ce87933925cbe9e0c67b03d\"","full_name":"rospogrigio/localtuya","last_commit":"490ad9e","last_updated":"2024-03-27T17:48:32Z","last_version":"v5.2.1","manifest_name":"LocalTuya integration","open_issues":1121,"stargazers_count":2579,"topics":["localtuya","tuya","tuya-api"],"last_fetched":1712153953.227981},"675748333":{"manifest":{"country":["SE"],"name":"Hemglass"},"description":"A Home Assistant sensor for getting information about the next time Hemglass comes to visit.","downloads":110,"domain":"hemglass","etag_releases":"W/\"7f7970b1e2cbb466b92f7be1fd0c1293ae7b6e6b314f5403a15aa2697368d142\"","etag_repository":"W/\"4db16f0cb73e208fd20cc3b5e7ff4c2ac50241511e4aeb40c4dbb9bdbb13721c\"","full_name":"popeen/Home-Assistant-Custom-Component-Hemglass","last_commit":"3bf1def","last_updated":"2023-11-28T21:23:28Z","last_version":"0.1.6","manifest_name":"Hemglass","open_issues":2,"stargazers_count":5,"topics":["hactoberfest"],"last_fetched":1705781989.942815},"363468409":{"manifest":{"name":"RedPocket Mobile"},"description":"RedPocket Integration for Data Usage Monitoring","domain":"redpocket","etag_releases":"W/\"0d3760fc7cb48d3c403ea41ea2a6cbe0c88ace5c1b80de929682eab95cb11d53\"","etag_repository":"W/\"b8d23bf1c67030b6988c36216406c22033b82676f525d1461a0ae7ff44de4173\"","full_name":"mbillow/ha-redpocket","last_commit":"5c54fd1","last_updated":"2021-06-06T19:51:29Z","last_version":"v2.3.3","manifest_name":"RedPocket Mobile","open_issues":2,"stargazers_count":3,"topics":["home","mvno","redpocket"],"last_fetched":1711311446.960064},"714066776":{"manifest":{"country":["FR"],"name":"iRacing for Home Assistant"},"description":"iRacing integration for Home Assistant","domain":"iracing","etag_releases":"W/\"c989f4a930606ea28baee410c15109afa67017066b3773b604bc9cf208304a3c\"","etag_repository":"W/\"e3fbe5381a767560c0fe9a284b0c5d215251e647b585fa0246fc0bc143ec1629\"","full_name":"cazeaux/ha-iracing","last_commit":"0efa5df","last_updated":"2024-03-16T16:55:57Z","last_version":"v1.2.2","manifest_name":"iRacing","stargazers_count":4,"topics":["iracing"],"last_fetched":1710764588.071991},"267433712":{"manifest":{"country":["CZ"],"name":"PRE Distribuce CZ"},"description":"Home Assistant integration to display info about energy plan","domain":"predistribuce","etag_repository":"W/\"ff2e450a127db20f30052546b9503b0833fa9e7a7fb5526ad33045e24c7d70ad\"","full_name":"slesinger/HomeAssistant-PREdistribuce","last_commit":"ed28bc7","last_updated":"2024-01-11T19:05:44Z","manifest_name":"PRE Distribuce","open_issues":8,"stargazers_count":11,"topics":["energy","power"],"last_fetched":1705674012.519907},"322881712":{"manifest":{"name":"Honor Router 3/X3 tracker"},"description":"Honor X3 router Device tracker for Home Assistant","domain":"honor_x3","etag_releases":"W/\"58156c96fa59b8ede57a373f42e561eed2f9739cf46ac43302a1e88a8e6a650e\"","etag_repository":"W/\"c63fb40fff766a73ef9775bb778ffe1f67d7bb996c4a2e8935c85e8d03d6a480\"","full_name":"juacas/honor_x3","last_commit":"3798953","last_updated":"2021-08-24T07:44:17Z","last_version":"v1.0.5","manifest_name":"Honor 3/X3 Router","stargazers_count":11,"topics":["device-tracker","presence-detection","router"],"last_fetched":1703218758.636403},"637354954":{"manifest":{"name":"Robonect"},"description":"Home Assistant integration for Robonect","domain":"robonect","etag_releases":"W/\"75a8a67e5ebba53a6253b6f3677b6979ad09edf363239edd8b0a32ab76fa718d\"","etag_repository":"W/\"947a4391030cceb6ccdd81d230e832796525615015e0a78c05ea96831d81d4cc\"","full_name":"geertmeersman/robonect","last_commit":"ac52480","last_updated":"2024-03-28T09:39:02Z","last_version":"v1.6.0","manifest_name":"Robonect","stargazers_count":28,"topics":["robonect"],"last_fetched":1712225772.556585},"615891516":{"manifest":{"country":["US"],"name":"Sense Custom Reporting (Kasa Plug Emulation)"},"description":"Report custom devices to sense energy monitoring for ha consumption devices","domain":"ha_sense","etag_releases":"W/\"5f322b93adf2056501218b42713262f410195f38fe73c3e18d3b15547e21e8c2\"","etag_repository":"W/\"fa5030b14a50e85bc9d8f7b31874b029c38381941461eee706b507b4721516f3\"","full_name":"dahlb/ha_sense","last_commit":"27ceeed","last_updated":"2024-04-01T21:25:09Z","last_version":"v1.2.5","manifest_name":"Sense Custom Reporting","open_issues":1,"stargazers_count":3,"topics":["python3"],"last_fetched":1712009680.922823},"625887812":{"manifest":{"name":"Azure OpenAI Conversation"},"description":"Azure OpenAI Conversation for Home Assistant","downloads":1558,"domain":"azure_openai_conversation","etag_releases":"W/\"fbdd885147a5fde13dad53fae0da73abf96e5da34ee19daadcfb18eef14e2c45\"","etag_repository":"W/\"43a7a7ea8341dbabb6e7c98960f7924996b559bc10ecee9f5ec0e2978eef119f\"","full_name":"joselcaguilar/azure-openai-ha","last_commit":"7c6b96b","last_updated":"2023-10-26T20:37:51Z","last_version":"v1.1.0","manifest_name":"Azure OpenAI Conversation","open_issues":9,"stargazers_count":37,"topics":["azure-openai","gpt"],"last_fetched":1711916246.473312},"679713495":{"manifest":{"name":"Battery Notes"},"description":"A Home Assistant integration to provide battery notes of devices","downloads":7205,"domain":"battery_notes","etag_releases":"W/\"dade5c2ec87d6aaf9bd67d57b80e30d07efd34201d8c7f2cad3f230a9dd2bdee\"","etag_repository":"W/\"ae9060574219b94c73dd846ff6390c1738150e848d4fb27aca7fd5619c42ff60\"","full_name":"andrew-codechimp/HA-Battery-Notes","last_commit":"7c9ae91","last_updated":"2024-04-04T06:15:12Z","last_version":"2.2.5","manifest_name":"Battery Notes","open_issues":1,"stargazers_count":373,"topics":["homeassistant-custom-component"],"last_fetched":1712225609.127915},"196057008":{"manifest":{"name":"Attributes extractor"},"description":"Breaks out specified attribute from other entities to a sensor","domain":"attributes","etag_releases":"W/\"95882e41a1e369185fdb1295c06128fc10c387f737d8cf95054507b03035bd40\"","etag_repository":"W/\"72f48c2dc360c0cf0655e75ae6864d0c601322acec0716a4e80b90c7915d8260\"","full_name":"pilotak/homeassistant-attributes","last_commit":"d44f91b","last_updated":"2023-06-08T18:08:10Z","last_version":"v1.2.1","manifest_name":"Attributes","open_issues":7,"stargazers_count":94,"topics":["attributes","breakout"],"last_fetched":1710678475.929583},"235915302":{"manifest":{"name":"Marta / Breeze Card"},"description":"Custom Home Assistant sensor for the Marta/Breeze Card.","domain":"marta","etag_releases":"W/\"4e3796cf2903d6294bf13e1dd8da234b95d88eecab91171c333481bb9a62c428\"","etag_repository":"W/\"c94ab3fc19e0f28d1a33b3828a9f2a7885be4c3dfcffcef52f3ca9f63727123a\"","full_name":"ryanmac8/Home-Assistant-Marta","last_commit":"0270a21","last_updated":"2021-05-13T14:56:54Z","last_version":"1.2","manifest_name":"Marta Card","stargazers_count":4,"topics":["breeze-card","marta"],"last_fetched":1706811742.689346},"408074547":{"manifest":{"name":"Acer Air Monitor"},"description":"Acer air monitor for Home Assistant","domain":"acer_air_monitor","etag_releases":"W/\"456620189b68b7e673c0522d93caa1c04a735e9b40cf3dc7026791cd59e62800\"","etag_repository":"W/\"fa8d710899d054961549e3b41aaca8e7ea867bdf4257e049f82a507291c54e4a\"","full_name":"sugoi-wada/acer-air-monitor-2018","last_commit":"30621ea","last_updated":"2024-04-03T19:39:52Z","last_version":"v1.3.0","manifest_name":"Acer Air Monitor","open_issues":4,"last_fetched":1712182769.246535},"477001098":{"manifest":{"name":"Philips AirPurifier (with CoAP)"},"description":"\ud83d\udca8 Philips AirPurifier custom component for Home Assistant. Supports local CoAP protocol.","domain":"philips_airpurifier_coap","etag_releases":"W/\"045e48afb1f96fe83381b0fb0e685923a31721d4fbf7daeb61753e88c7e9da9a\"","etag_repository":"W/\"8ffa0d33da583bf705ee72cb678b4389bf352bf65cdb4315127025fb861311dc\"","full_name":"kongo09/philips-airpurifier-coap","last_commit":"4312bc8","last_updated":"2024-03-24T19:07:07Z","last_version":"v0.18.7","manifest_name":"Philips AirPurifier (with CoAP)","open_issues":6,"stargazers_count":144,"topics":["air-purifier","philips"],"last_fetched":1711852036.767904},"589430688":{"manifest":{"name":"GNE PV Monitoring"},"description":"This sensor uses official API to get data from GNE","downloads":110,"domain":"gne_pv_monitoring","etag_releases":"W/\"be4e0ce35e37ceb98f314e76f38a97b46eeaecc9e6bc2b886520241c40e069bb\"","etag_repository":"W/\"ccd2ca105d95f42f7aafe8bbc104afef311c1384ea8a45972083627758655884\"","full_name":"PiotrMachowski/Home-Assistant-custom-components-GNE-PV-Monitoring","last_commit":"faf2558","last_updated":"2023-07-07T02:53:36Z","last_version":"v1.0.3","manifest_name":"GNE PV Monitoring","open_issues":1,"stargazers_count":2,"topics":["gne","photovoltaic"],"last_fetched":1708028263.863723},"711632405":{"manifest":{"country":["FR"],"name":"Little Monkey"},"description":"Int\u00e9gration personnalis\u00e9e Home Assistant pour l'assistant d'\u00e9nergie ecojoko","downloads":605,"domain":"little_monkey","etag_releases":"W/\"0902d39f45e09a747a445301c5beabf072bb012b286563fcd16042f7510f41c6\"","etag_repository":"W/\"b53f134e58af7bab5d3c80b7d41cf10aa37866d2da2c8519dc60ee10b9bee96c\"","full_name":"jmcruvellier/little_monkey","last_commit":"a295239","last_updated":"2024-02-10T23:28:15Z","last_version":"v1.2.0","manifest_name":"Little Monkey","open_issues":1,"stargazers_count":17,"topics":["custom-integration","custom-integrations","ecojoko","energy","energy-monitor"],"last_fetched":1711715227.528342},"407205510":{"manifest":{"country":["RU"],"name":"\u041f\u0418\u041a \u0414\u043e\u043c\u043e\u0444\u043e\u043d / PIK Intercom"},"description":"\u041f\u0418\u041a \u0414\u043e\u043c\u043e\u0444\u043e\u043d \u0434\u043b\u044f Home Assistant","domain":"pik_intercom","etag_releases":"W/\"66890aadf7a2fa63a86415a84341b2b897ff5d31ae551cf4de43a8c1d0fea9b9\"","etag_repository":"W/\"9859740971096c6d62afc4b51698728e51adacff2831999b3fc9c3cb27640b72\"","full_name":"alryaz/hass-pik-intercom","last_commit":"3ab2ffc","last_updated":"2024-03-17T13:05:15Z","last_version":"v2024.3.0","manifest_name":"PIK Intercom / \u041f\u0418\u041a \u0414\u043e\u043c\u043e\u0444\u043e\u043d","open_issues":7,"stargazers_count":42,"topics":["intercom","pik-group"],"last_fetched":1710843219.242226},"278596510":{"manifest":{"name":"Leaf Spy"},"description":"A Home Assistant integration to receive live data sent from the LeafSpy app","domain":"leafspy","etag_releases":"W/\"15c698743274a6e4407f31f0ab12f2c4567a8fb3d497ad872ba9be8e79abea33\"","etag_repository":"W/\"803962cd8cf77879a55e6ad533abe3b723f01a8197c1f3b53d6f9dfde67f370b\"","full_name":"jesserockz/ha-leafspy","last_commit":"62124e3","last_updated":"2024-03-07T23:08:35Z","last_version":"v0.2.1","manifest_name":"Leaf Spy","open_issues":1,"stargazers_count":16,"topics":["electric-vehicles","ev","leaf","leafspy","nissan"],"last_fetched":1711995577.429181},"312080478":{"manifest":{"name":"govee"},"description":"A HACS repository for Govee light integration","domain":"govee","etag_releases":"W/\"82fa3edb4005d4b9ad6370b0776f4e68ad6ee45c5eb2516a8236c7ea0ff2c6bc\"","etag_repository":"W/\"1d414cb4a50624b1233b4d02d49aeb5242244eeeeb56dcbae98da6bb0f089fc2\"","full_name":"LaggAt/hacs-govee","last_commit":"52d3bc0","last_updated":"2024-02-11T08:43:54Z","last_version":"2023.11.1","manifest_name":"Govee","open_issues":86,"stargazers_count":248,"topics":["devcontainer","govee","light"],"last_fetched":1711628915.186874},"352169259":{"manifest":{"country":["NL","BE"],"name":"Neerslag App"},"description":"Neerslag app for Home Assistant. All-in-one package (Sensors + Card).","domain":"neerslag","etag_repository":"W/\"d16c58ef8d7a93bc4bc4af9d7e1d8efa663019ce0191a510315fe86305118cce\"","full_name":"aex351/home-assistant-neerslag-app","last_commit":"5e543ee","last_updated":"2022-07-08T17:26:32Z","manifest_name":"Neerslag App (Buienalarm / Buienradar)","open_issues":20,"stargazers_count":48,"last_fetched":1709288001.589098},"201497401":{"manifest":{"name":"Xiaomi IR Climate"},"description":"Xiaomi IR Climate Component","domain":"xiaomi_remote","etag_repository":"W/\"83d6f9323eef93600613d357717663a648dd8e042a347ca1409536dcfd510485\"","full_name":"Anonym-tsk/homeassistant-climate-xiaomi-remote","last_commit":"4223ab3","last_updated":"2022-10-11T15:33:07Z","manifest_name":"Xiaomi Remote Climate","open_issues":7,"stargazers_count":30,"topics":["climate","xiaomi"],"last_fetched":1707740558.785125},"354515979":{"manifest":{"name":"Philips Ambilight+Hue Switch"},"description":"ON/OFF Abilight+Hue (Switch) component for Philips Ambilight TV's","domain":"philips_ambilight_hue","etag_releases":"W/\"46f72a2b0b4eea18491982d108af673157bd704704d485e584eeaa9f07836b63\"","etag_repository":"W/\"0822632232719a9951c5e34d0a14d6511b1c8c737aaa29b00a3776b0107275f9\"","full_name":"Mr-Groch/ambihue","last_commit":"8eca367","last_updated":"2023-03-12T21:32:05Z","last_version":"1.0.3","manifest_name":"Philips TV Ambilight+Hue","stargazers_count":12,"topics":["ambilight","philips-hue"],"last_fetched":1697833086.662928},"717139656":{"manifest":{"name":"digitalSTROM"},"description":"digitalSTROM integration for Home Assistant","domain":"digitalstrom","etag_releases":"W/\"d5e0062f3cd3f919b6fbf13aa998ab3021468e2128acbe46a5ac0c8024684817\"","etag_repository":"W/\"ff1f4e5ceb0813f899c62fa5c898fd69de8ea904e0cf3357cec815433af07b86\"","full_name":"Mat931/digitalstrom-homeassistant","last_commit":"788ac1e","last_updated":"2024-03-17T12:00:45Z","last_version":"v0.0.9","manifest_name":"digitalSTROM","open_issues":4,"stargazers_count":14,"topics":["digitalstrom","home-assistant-integration"],"last_fetched":1711283224.107181},"502240544":{"manifest":{"country":["NZ"],"name":"Contact Energy"},"description":"Contact Energy integration for Home Assistant","domain":"contact_energy","etag_releases":"W/\"a438a89ab7ff70e6abe1886e10cc5d14afeca0c8364765b1fe0dddcdf7311af4\"","etag_repository":"W/\"1315b6cc2726d2f1ee17be4732f0b8459dab708da19289a94f6b20269b7dd576\"","full_name":"codyc1515/ha-contact-energy","last_commit":"16826d2","last_updated":"2024-02-28T18:35:30Z","last_version":"v1.0.0","manifest_name":"Contact Energy","open_issues":6,"stargazers_count":7,"topics":["energy","nz"],"last_fetched":1710896133.612498},"207620142":{"manifest":{"country":["IT"],"name":"DPC sensor"},"description":"Italy Meteo-hydro alert and hydrogeological phenomena Civil Protection (Protezione Civile). In this custom component you can find the vigilance Bulletin and the Bulletin of national hydrogeological and hydraulic criticalities. They allow to check whether in your current location there will be criticalities/warnings related to weather-hydrogeological and hydraulic phenomena. Weather forecasts for civil protection purposes differs from the classic \"weather forecasts\". They highlight potentially harmful situations to people or things. This component was created for personal purposes, in order to be able to monitor the Civil Protection site and check for important updates. I hope it will be useful to you.","domain":"dpc","etag_releases":"W/\"3f8576a6a7bdd340ccf4c017460e6c2927044617950e1a6f1c0732f0e410193c\"","etag_repository":"W/\"58c9a9b342ebd7c8a2dc1ff594dc1de39dc8a3737b56d882a9acbb1d001ffa6c\"","full_name":"caiosweet/Home-Assistant-custom-components-DPC-Alert","last_commit":"83e37eb","last_updated":"2023-10-09T19:10:25Z","last_version":"v2023.10.0","manifest_name":"Dipartimento Protezione Civile","open_issues":2,"stargazers_count":43,"topics":["dpc","protezionecivile"],"last_fetched":1707308554.122648},"224560492":{"manifest":{"country":["CA"],"name":"Sinope Neviweb130"},"description":"Neviweb130 custom component for Home Assistant to manage devices connected via a GT130 and wifi devices from Sinop\u00e9","domain":"neviweb130","etag_releases":"W/\"59604a593a3308ec0b2662ea59cec54b11db7320d7e9792c0a698f8d6a3daeed\"","etag_repository":"W/\"28d152180cecd13f7a02fc8f88e6d93610f4534ca72516dc554132cae24cf92a\"","full_name":"claudegel/sinope-130","last_commit":"6a0cea3","last_updated":"2024-03-23T02:31:10Z","last_version":"v2.7.2","manifest_name":"Sinope Neviweb130","open_issues":11,"stargazers_count":57,"topics":["neviweb","sinope"],"last_fetched":1712161005.038416},"242635439":{"manifest":{"name":"Disk Space"},"description":"Disk space for a path. For use with Home Assistant","domain":"diskspace","etag_releases":"W/\"699ecfa6a978936253f6a17df78a08f4fc0509f40fa4ee773638d5fc05d7860a\"","etag_repository":"W/\"d7e630a36b43cfccf708890c7f5570529bdd5e71fa51a9cf7d94859143799571\"","full_name":"kuchel77/diskspace","last_commit":"b80bddc","last_updated":"2021-04-18T05:13:59Z","last_version":"0.8","manifest_name":"diskspace","open_issues":4,"stargazers_count":9,"topics":["assistant","disk","home","space"],"last_fetched":1709929004.599326},"262140617":{"manifest":{"country":["IL"],"name":"Read Your Meter"},"description":"Home Assistant sensor to read water meter","domain":"read_your_meter","etag_releases":"W/\"9aa2b4e60ce92db30d56ce725e7a704edfc697bd3229fb13e9fb6c6e93b20d3c\"","etag_repository":"W/\"3200e532aaba529abf552c4b610ed713c5c2ca969f367105b29f39314003da6f\"","full_name":"eyalcha/read_your_meter","last_commit":"288371a","last_updated":"2022-07-25T19:36:44Z","last_version":"1.0.12","manifest_name":"Read Your Meter","open_issues":4,"stargazers_count":35,"last_fetched":1709799350.480942},"483187645":{"manifest":{"country":["GB"],"name":"Microsoft Graph"},"description":"Microsoft Graph API Presence Integration for Home Assistant","domain":"microsoft_graph","etag_releases":"W/\"2441b651a72e735f6dae7ea653790692191234039751cbd3209a3d19660f108a\"","etag_repository":"W/\"612e1f5117bcfb400234d6049b43b136b079003c765915b048ade0e3c66e8141\"","full_name":"geoffreylagaisse/Hass-Microsoft-Graph","last_commit":"b6691a0","last_updated":"2023-04-28T15:38:44Z","last_version":"1.4","manifest_name":"Microsoft Graph","open_issues":3,"stargazers_count":28,"topics":["custom","graphapi"],"last_fetched":1705961712.446615},"379621461":{"manifest":{"name":"Mixergy"},"description":"Add support for Mixergy's smart water tank into Home Assistant","domain":"mixergy","etag_releases":"W/\"adc267368feab13b218195715af9ecdb2350f01f3d81afca109432ca045055be\"","etag_repository":"W/\"707f4443040ece9c4d779f187e2b7c65591a83e27d6457843facfa7b19c8c061\"","full_name":"tomasmcguinness/homeassistant-mixergy","last_commit":"a2e2a05","last_updated":"2024-03-31T19:44:41Z","last_version":"v0.8.1","manifest_name":"Mixergy","open_issues":4,"stargazers_count":30,"topics":["hotwater","mixergy"],"last_fetched":1711916472.967488},"400832075":{"manifest":{"name":"Aqua Temp"},"description":"Home Assistant AquaTemp Heat Pump Climate Entity","domain":"aqua_temp","etag_releases":"W/\"8add9547a073cd4346610a99404403f0e4086fa88a6069dd0edd925638279ae5\"","etag_repository":"W/\"3727a34e7159f253e6be955bb945220fe1da8ca52aba063cad5a84623d302e84\"","full_name":"radical-squared/aquatemp","last_commit":"cfe8e96","last_updated":"2024-02-08T16:06:28Z","last_version":"v3.0.31","manifest_name":"Aqua Temp","open_issues":6,"stargazers_count":26,"topics":["aquatemp","climate-entity"],"last_fetched":1712161337.792087},"201740996":{"manifest":{"name":"Generate readme"},"description":"Use Jinja and data from Home Assistant to generate your README.md file","downloads":255,"domain":"readme","etag_releases":"W/\"aad7f18a192ec30b57078682df5e1cc4014d1a24573b3741f555e2eefea1c518\"","etag_repository":"W/\"dc70493ef0fd25da3cde06fbfaed8772ed26c33ba6006e8b99d7232f19032746\"","full_name":"custom-components/readme","last_commit":"58ea978","last_updated":"2024-03-16T05:31:48Z","last_version":"0.5.0","manifest_name":"Generate readme","open_issues":1,"stargazers_count":31,"topics":["automation","jinja","readme"],"last_fetched":1711995425.439419},"442001863":{"manifest":{"name":"TP-Link Deco"},"description":"Home Assistant TP-Link Deco Custom Component","domain":"tplink_deco","etag_releases":"W/\"390bbdc1d7e7723e7f023bfed6a54be393d22141626ce885581dfbd36bccb363\"","etag_repository":"W/\"778b06eee4a707987aeba9be8b187ba91c180da62482fa842b8fda33f7b32736\"","full_name":"amosyuen/ha-tplink-deco","last_commit":"796ebff","last_updated":"2024-04-01T11:24:46Z","last_version":"v3.6.0","manifest_name":"TP-Link Deco","open_issues":19,"stargazers_count":146,"topics":["router","tp-link"],"last_fetched":1711980771.888387},"313850121":{"manifest":{"name":"Xiaomi Miio For Yeelink"},"description":"Xiaomi Miio Yeelink/Yeelight devices for Home Assistant","downloads":56,"domain":"miio_yeelink","etag_releases":"W/\"5252617e4cc95228b31bfa3ab696151cec8eafa619f47d1cf7d65bf9865b0ea3\"","etag_repository":"W/\"2220e18839278fc167c2a42a78a4a64018b29f0084b9ea1eceb2d38b70b93b92\"","full_name":"al-one/hass-miio-yeelink","last_commit":"53945c8","last_updated":"2023-12-08T10:02:59Z","last_version":"v0.1.13","manifest_name":"Miio For Yeelink","open_issues":35,"stargazers_count":165,"topics":["miio","miot","xiaomi","yeelight","yeelink"],"last_fetched":1711685741.392425},"542686924":{"manifest":{"name":"ENTSO-e Transparency Platform"},"description":"Integration for Home Assistant to fetch day ahead energy prices from European countries via ENTSO-e Transparency Platform","domain":"entsoe","etag_releases":"W/\"a2736768f208a0457b7728f7081ccf82d7ef7eca5f01e95b9861756835170e7d\"","etag_repository":"W/\"debe76f5b606201b9bfccc58273e037d83a4b57504489d92a9ee05f5d927e38a\"","full_name":"JaccoR/hass-entso-e","last_commit":"68ef614","last_updated":"2024-03-11T08:30:50Z","last_version":"v0.3.0","manifest_name":"ENTSO-e Transparency Platform","open_issues":33,"stargazers_count":153,"topics":["day-ahead","day-ahead-auction","day-ahead-market","electricity-market","electricity-prices","energy","energy-prices","entso-e","entsoe"],"last_fetched":1712161158.499699},"282714722":{"manifest":{"country":["DE"],"name":"Senec solar system sensor"},"description":"SENEC Battery integration for Home Assistant","domain":"senec","etag_releases":"W/\"499ba391a445730deb8db13c46696972894a07cd4c75b4dcfdb6c4670a17dd70\"","etag_repository":"W/\"63be6a83b5ba92178f876e1075b405b925757342e71aa9a361a8d4944ba25fd1\"","full_name":"mchwalisz/home-assistant-senec","last_commit":"3fc159e","last_updated":"2024-03-18T20:35:16Z","last_version":"2.1.1","manifest_name":"senec","open_issues":21,"stargazers_count":45,"topics":["home-assistant-component"],"last_fetched":1710886625.272107},"417400028":{"manifest":{"name":"Smart thermostat (PID)"},"description":"Smart Thermostat with PID controller for HomeAssistant","domain":"smart_thermostat","etag_releases":"W/\"e904b43ee54c2505ff5615772e0d559f5658d03668335a9506c64f83979ee318\"","etag_repository":"W/\"99ca98f62cab4719589a4e32191cab6dc1c588f1c1099e1d5637186c7b813105\"","full_name":"ScratMan/HASmartThermostat","last_commit":"0f9ceb0","last_updated":"2024-03-30T12:17:16Z","last_version":"2024.2.1","manifest_name":"Smart thermostat","open_issues":32,"stargazers_count":323,"topics":["air-conditioner","heater","heater-control","heater-controller","heating","heating-control","heating-controller","pid-controller","smart-thermostat","thermostat"],"last_fetched":1711801656.85706},"196605143":{"manifest":{},"description":"Custom component for Philips TV's running Android which are built between 2014 and 2016. Written in Python3 for Home Assistant.","domain":"philips_2014","etag_releases":"W/\"668d492cfae54efb4ab1333a059dfe0dbd7528b9ab4c803a25012ce676f7cf04\"","etag_repository":"W/\"15dfdf8f37ff6924b87fed5fab2b58de73650d838ed4625e67bf9d0d682f9fd5\"","full_name":"RobHofmann/HomeAssistant-PhilipsAndroid2014","last_commit":"56c4d40","last_updated":"2021-05-09T12:39:18Z","last_version":"1.0.0","manifest_name":"Philips TV 2014-2016","stargazers_count":2,"last_fetched":1678387541.387022},"507584200":{"manifest":{"name":"Ecopower Dynamic Grid Prices"},"description":"Dynamic Grid Prices for Ecopower","domain":"ecopower_dynamic_grid_prices","etag_releases":"W/\"9e513bd65a2f78ef02f94d152c20e17acc271f2d4f5118a112bd3df347117860\"","etag_repository":"W/\"d487e566976954600b23725870833f229ce5d6d06c3d746b7a60fbebca976b25\"","full_name":"infradom/ecopower_dynamic_grid_prices","last_commit":"aae0d27","last_updated":"2023-10-03T07:03:03Z","last_version":"V0.0.8","manifest_name":"EcopowerPrices","open_issues":3,"stargazers_count":7,"topics":["day-ahead-market","ecopower","electricity-market","electricity-prices","forecasts"],"last_fetched":1706472948.227669},"231989179":{"manifest":{"name":"HASS Bardolph"},"description":"HASS custom component to load and run Bardolph (simple scripting utility for LIFX light bulbs by Al Fontes, Jr.)","domain":"bardolph","etag_repository":"W/\"a7fc79e9a635b2d8f8b92d4918da6cf377e707dd358dcc879bb2085c9ae1a361\"","full_name":"JAAlperin/hass-bardolph","last_commit":"806fb18","last_updated":"2021-05-08T22:23:44Z","manifest_name":"Bardolph","stargazers_count":3,"topics":["bardolph","color-bulb","lifx","lifx-lan-protocol","scripts","services"],"last_fetched":1681748514.385522},"242528119":{"manifest":{"name":"RuuviTag Sensor"},"description":"Ruuvi tag BLE sensor for Home Assistant.","domain":"ruuvi","etag_repository":"W/\"fd1841cd9df0a119f3a29b10225e40b7b24cff22e7da4c00ddedf70cbd3c58ca\"","full_name":"ruuvi-friends/ruuvi-hass.io","last_commit":"ef60f8d","last_updated":"2022-01-25T13:23:39Z","manifest_name":"Ruuvi sensor tags","open_issues":8,"stargazers_count":42,"topics":["ruuvi-ble-devices","ruuvitag","ruuvitag-sensor"],"last_fetched":1704903880.496879},"129049262":{"manifest":{"name":"Xiaomi Mi Smart Pedestal Fan Integration"},"description":"Xiaomi Mi Smart Fan integration for Home Assistant","domain":"xiaomi_miio_fan","etag_releases":"W/\"aa5309832deda12281a5a5aafec2ce7935d9cca8c4a43b25cf72a707e94ed416\"","etag_repository":"W/\"69be7223d4fba067b212195c319843d234c56637f91b2315f9953ecb174b5aa8\"","full_name":"syssi/xiaomi_fan","last_commit":"1c6eb91","last_updated":"2024-01-11T17:00:12Z","last_version":"2023.12.0.0","manifest_name":"Xiaomi Mi Smart Pedestal Fan","open_issues":48,"stargazers_count":384,"topics":["fan","miio","miio-protocol","miot","xiaomi"],"last_fetched":1712089241.521958},"356033332":{"manifest":{"name":"Crypto Tracker"},"description":"Integration for Home Assistant to implement a crypto tracking system","domain":"cryptostate","etag_releases":"W/\"c04f90739ffde5ecaecec63f192a5e9f1d4e584aebc756c197a2c98776a62bcd\"","etag_repository":"W/\"f9af2b84c2b62fd788ce1b09833b274ff67319fcb90ca4bb75c5e54c7b5a10ed\"","full_name":"BigNocciolino/CryptoTracker","last_commit":"fb73f5e","last_updated":"2024-03-09T10:55:27Z","last_version":"v2.1.0","manifest_name":"CryptoState","stargazers_count":22,"topics":["automation","currency","tracker"],"last_fetched":1711901679.825956},"337387822":{"manifest":{"name":"Hella ONYX.CENTER"},"description":"Home Assistant integration (HACS) for Hella's ONYX.CENTER appliance","domain":"hella_onyx","etag_releases":"W/\"7106adfa74567686332c8efcb0f6d9b8273f48939db477685cbcc2df3cde92d4\"","etag_repository":"W/\"6c1948e908213f028cb06a157c3a36ad719be018f6fcbd6c16d71adf00c7ebf2\"","full_name":"muhlba91/onyx-homeassistant-integration","last_commit":"7392054","last_updated":"2024-04-04T07:17:55Z","last_version":"v10.0.0","manifest_name":"Hella ONYX.CENTER","open_issues":4,"stargazers_count":5,"topics":["hella","onyx"],"last_fetched":1712218950.520558},"647324399":{"manifest":{"name":"Additional CA"},"description":"Add private Certificate Authority or self-signed certificate into Home Assistant to access 3rd-party service with TLS/SSL.","domain":"additional_ca","etag_releases":"W/\"23321fc28985a791f0dd11a791d45cd0c8b72b34e4da0f3e4df131c3a594fa20\"","etag_repository":"W/\"0e7722de562b0d1ba7898b28f0069f9ca2a0d9b0d086b237edb12a25a32337b7\"","full_name":"Athozs/hass-additional-ca","last_commit":"86a8552","last_updated":"2024-03-23T12:13:55Z","last_version":"0.2.2","manifest_name":"Additional CA","stargazers_count":17,"topics":["certificate","certificate-authority","home-assistant-integration","homeassistant-custom-component"],"last_fetched":1711203066.887666},"229519365":{"manifest":{"country":["AU"],"name":"WaterNSW Real Time Data"},"description":"Home Assistant Sensor for WaterNSW Real Time Data","domain":"waternsw","etag_releases":"W/\"655cf474711f9d47927ce4170ecebcc766d95d5ca959fa4f7c4bb76ea69d52cc\"","etag_repository":"W/\"d481ee16621a6012d91f7272d83ef9bdd5dc2dce3851a2a42710222f1b8d42fa\"","full_name":"bacco007/sensor.waternsw","last_commit":"2d64b80","last_updated":"2022-06-10T08:04:57Z","last_version":"0.6","manifest_name":"Water NSW","stargazers_count":6,"last_fetched":1702498462.819623},"319608056":{"manifest":{"name":"Bodymiscale"},"description":"Custom_components Body Metrics for Xiaomi Miscale 1 and 2 (esphome or BLE monitor for Homeassistant)","domain":"bodymiscale","etag_releases":"W/\"3240074fd7f30ba27eb4e1b3dce6a33ab25328a91bff708afae388271189ed9d\"","etag_repository":"W/\"0ce330d3590d7bdae14ca3fb2c13e2fae877d1814d194dc6c4db6e4d1cef1106\"","full_name":"dckiller51/bodymiscale","last_commit":"8bd04bd","last_updated":"2024-03-25T22:40:20Z","last_version":"2024.1.3","manifest_name":"BodyMiScale","open_issues":17,"stargazers_count":189,"topics":["ble-monitor","esphome","miscale","mitemp-bt","xiaomi"],"last_fetched":1712168275.109904},"589348474":{"manifest":{"name":"EnergyTariff"},"description":"HACS Integration for monitoring Norwegian grid tariff level","domain":"energytariff","etag_releases":"W/\"af4c25df1de80a92105760df855c630127c946d620e778e25daa0faec8878c34\"","etag_repository":"W/\"83ba00f9d4ce2861abe70632683690cdf21f08ded6842247b6251a6eac596c89\"","full_name":"epaulsen/energytariff","last_commit":"9b6a997","last_updated":"2023-10-11T09:35:33Z","last_version":"0.2.4","manifest_name":"Energy tariff","open_issues":7,"stargazers_count":27,"topics":["energy-tariff"],"last_fetched":1708092880.986154},"240459262":{"manifest":{"country":["DE"],"name":"Abfall API (Jumomind)"},"description":"Abfall API (Jumomind) custom component for home assistant - Get an alert when garbage collection is due","domain":"abfallapi_jumomind","etag_repository":"W/\"b443f7afa62d45d1493f5765c8085e6056b99c4ec82c589ec4f2d40d871c1417\"","full_name":"tuxuser/abfallapi_jumomind_ha","last_commit":"8b4449f","last_updated":"2021-12-22T09:57:43Z","manifest_name":"jumomind api waste collection schedule","open_issues":2,"stargazers_count":4,"topics":["abfall","collection","deutschland","garbage","germany","jumomind","muell","waste"],"last_fetched":1691648608.415854},"535287543":{"manifest":{"name":"evnex"},"description":"A cloud-polling Home Assistant component to integrate with an Evnex Charger","domain":"evnex","etag_releases":"W/\"3d16b603077c1485178e6634b37a89b83f29a47735f87b5a951a9b4ee734af92\"","etag_repository":"W/\"d6bc870805e986a41c8de164a8d2e2cf5d02499210bc28b417689f5865c7dd98\"","full_name":"hardbyte/ha-evnex","last_commit":"917e695","last_updated":"2024-02-10T04:13:43Z","last_version":"v0.5.3","manifest_name":"Evnex EV Charger","open_issues":4,"stargazers_count":5,"topics":["charger","energy-consumption","homeassistant-custom-component"],"last_fetched":1712132381.339528},"657192016":{"manifest":{"country":["BG"],"name":"KAT Bulgaria"},"description":"This is a custom component that checks periodically if you have any fines from KAT Bulgaria.","domain":"kat_bulgaria","etag_releases":"W/\"054d212ccffa4aff0578aaa835b6230745c107608a1ce288d23006bd85f89d96\"","etag_repository":"W/\"a870294073a0e86b3b6bc97acc4a4747334788a3f5df9ef2d1dcc45c9df9e1dc\"","full_name":"Nedevski/hass_kat_bulgaria","last_commit":"279fbea","last_updated":"2024-01-29T17:06:41Z","last_version":"0.6.2.6","manifest_name":"KAT Bulgaria","stargazers_count":6,"topics":["kat-bulgaria"],"last_fetched":1707337108.27138},"481715988":{"manifest":{"country":["NL"],"name":"Kia Connected Services"},"description":"Home Assistant Custom Component: MijnKia Connected Services","domain":"kia_connect","etag_releases":"W/\"608708d3fdef1474f8bf420cd86c85dbc1c7a0275a5efcc8d6b9b046e4f64e7c\"","etag_repository":"W/\"595e95579835d778a74782030ca2819b1baffb4a06b1d22ca925406f1b863831\"","full_name":"PimDoos/kia_connect","last_commit":"4060606","last_updated":"2023-12-28T18:40:45Z","last_version":"v0.1.5","manifest_name":"Kia Connected Services","open_issues":3,"stargazers_count":8,"topics":["api-wrapper","connected-vehicle","home-assistant-custom-component","kia"],"last_fetched":1707992406.488987},"139892990":{"manifest":{"name":"BrewDog"},"description":"\ud83c\udf7b Display information about random beers from Brewdog as a sensor in Home Assistant, you can use this in a push notification next time you visit a bar.","domain":"brewdog","etag_repository":"W/\"3473093d7c39d7f522bd36bb7e38a92a6034bd3668e38b439cc59a43c0eebe7e\"","full_name":"custom-components/brewdog","last_commit":"90e6824","last_updated":"2022-03-11T08:08:33Z","manifest_name":"BrewDog","stargazers_count":5,"topics":["api","brewdog","punkapi"],"last_fetched":1704903520.892833},"542621509":{"manifest":{"name":"Imou Life"},"description":"Home Assistant custom component for controlling Imou devices","domain":"imou_life","etag_releases":"W/\"696aa2097ebc2d38365dfba02f4b2c5c4039daa1245a62081aeaf7cc2c4c390c\"","etag_repository":"W/\"81df677d52b3fa5c463a1bb37407c4a2670ca213592656ed88fc579977ecdade\"","full_name":"user2684/imou_life","last_commit":"8b7cd6b","last_updated":"2024-01-27T14:23:03Z","last_version":"1.0.15","manifest_name":"Imou Life","open_issues":39,"stargazers_count":100,"topics":["camera","imou","imou-life","motion-detection","webcam"],"last_fetched":1711289932.598576},"369774988":{"manifest":{"name":"openweathermaphistory"},"description":"A home assistant sensor that uses the OpenWeatherMap API to get forecast, current obs and history data","downloads":797,"domain":"openweathermaphistory","etag_releases":"W/\"8d26cf6d624a7710e72479bf2a197b7cb99327ba16533aecddb6da0b09e1b35f\"","etag_repository":"W/\"c3e388e5f57a3e4a17def5a0bb1805efb7ee0c25a5d0a3e14ae016fa68829e7f\"","full_name":"petergridge/openweathermaphistory","last_commit":"2a84c4d","last_updated":"2024-02-21T20:16:16Z","last_version":"v2.0.13","manifest_name":"Open Weather Map Rain History","open_issues":1,"stargazers_count":45,"topics":["irrigation","weather"],"last_fetched":1711793964.793847},"454942078":{"manifest":{"name":"Tenda AC23 Router Device Tracker"},"description":"Track your devices via Tenda AC23 router using Home Assistant's device tracker","domain":"tenda_tracker","etag_releases":"W/\"a4fba5d2619a51736c5bcff75b549da6220fe54401ccb7c7b5fa5a422bf298b7\"","etag_repository":"W/\"cf0de7f519f32b1faf963711f01a9a8f0e3ef8b78eb1183825ffb40916d9a97f\"","full_name":"sakowicz/home-assistant-tenda-tracker","last_commit":"0500d3f","last_updated":"2024-03-08T12:03:14Z","last_version":"v0.0.6","manifest_name":"Tenda AC23 Router Device Tracker","open_issues":2,"stargazers_count":4,"topics":["device-tracker","home","tenda","tenda-ac23","tracker"],"last_fetched":1709900962.084922},"233079250":{"manifest":{"country":["NO"],"name":"darksky_m"},"description":"darksky - clouds cover and alerts","domain":"darksky_m","etag_repository":"W/\"6475e0b91a0b4e187905d6a54029955caf351932da61624016156c97abc8d689\"","full_name":"kodi1/darksky_m","last_commit":"ead4a32","last_updated":"2021-03-28T10:12:47Z","manifest_name":"darksky mod - alerts and clouds","topics":["darksky"],"last_fetched":1678387413.722035},"272337216":{"manifest":{"country":["RU","BY"],"name":"Pandora Car Alarm System"},"description":"Home Assistant custom component for Pandora Car Alarm System","domain":"pandora_cas","etag_releases":"W/\"25d1da4a48a85e4fc6dc2023e43de0e2a5d778cf3fd000ae5e81af6256351ff1\"","etag_repository":"W/\"19492e063fb877de96afa0bc052e8479ba768fc9b5e7efe4eff5c80480b45df0\"","full_name":"turbulator/pandora-cas","last_commit":"9258cf8","last_updated":"2023-03-06T05:08:02Z","last_version":"1.4.4","manifest_name":"Pandora Car Alarm System","open_issues":5,"stargazers_count":40,"topics":["pandora"],"last_fetched":1709634128.411913},"199313405":{"manifest":{"name":"Beward Integration"},"description":"Home Assistant custom component for Beward security Cameras and Doorbells","downloads":73,"domain":"beward","etag_releases":"W/\"c121f8153ceb6c4d6c0ad9b8df8d6ff8c3830dff1fb2a7a671cdf06c23a1aff2\"","etag_repository":"W/\"0c0eb72589cb25af1443b8ad335bfc86a1d498bece7112bb1354314a046f549b\"","full_name":"Limych/ha-beward","last_commit":"d1f43a7","last_updated":"2024-02-05T12:01:52Z","last_version":"1.1.28","manifest_name":"Beward Integration","open_issues":13,"stargazers_count":20,"topics":["beward","camera","doorbell","dvr","security","surveillance"],"last_fetched":1709417801.905603},"296320952":{"manifest":{"country":["CN"],"name":"\u5c0f\u7c73\u4e91\u670d\u52a1"},"description":"HASS\u7684\u5c0f\u7c73\u4e91\u670d\u52a1\u96c6\u6210","domain":"xiaomi_cloud","etag_releases":"W/\"28c52e39c3c3c5acd404f27ea674f50c3aadc0d5a16fb64d174a54b179262b0f\"","etag_repository":"W/\"c2b178032153b2bef3148af675539f0131c380efbca91fbb4b0b6358a5a6836c\"","full_name":"fineemb/xiaomi-cloud","last_commit":"04d9793","last_updated":"2023-09-14T13:28:45Z","last_version":"v1.2.6","manifest_name":"Xiaomi Cloud","open_issues":10,"stargazers_count":42,"topics":["cloud","xiaomi"],"last_fetched":1710982715.523204},"307974458":{"manifest":{"country":["SE"],"name":"ResRobot"},"description":"Get departure times for swedish public transportation","domain":"resrobot","etag_releases":"W/\"2f19d7c12ea1a44dff681240b9f2a06ee75328511da9018cc9344493ed679c37\"","etag_repository":"W/\"d2122ade10cf9b6d022e99288ebf8d6e0cdec12d51a7e01026423a427c92aee4\"","full_name":"TekniskSupport/home-assistant-resrobot","last_commit":"162abea","last_updated":"2023-12-07T12:38:25Z","last_version":"v0.0.18","manifest_name":"resrobot","open_issues":3,"stargazers_count":12,"topics":["bus","ferry","iesus","public","sweden","train","tram","transportation"],"last_fetched":1705667541.440985},"340616586":{"manifest":{"name":"Narodmon Cloud Integration"},"description":"Component to integrate Narodmon cloud into Home Assistant","downloads":20,"domain":"narodmon","etag_releases":"W/\"980554abb53b3e3d30f329e8b2eaa3d01e122be1339e6073b4799bb747a9bbb2\"","etag_repository":"W/\"b611e2f462f961b13777326220d7e614e7e5ce77f61a26c036cc27f07efc315f\"","full_name":"Limych/ha-narodmon","last_commit":"c20aaa0","last_updated":"2024-03-11T08:02:42Z","last_version":"2.0.3","manifest_name":"Narodmon Cloud Integration","open_issues":9,"stargazers_count":17,"topics":["home-assistant-component","narodmon","weather"],"last_fetched":1710152401.627833},"585709486":{"manifest":{"country":["NL"],"name":"Remeha Home"},"description":"Remeha Home integration for Home Assistant","domain":"remeha_home","etag_releases":"W/\"2862854cb0b9530a3ac03d4eb9f45a8cb7af3701c424db9bbee4db0e806d8021\"","etag_repository":"W/\"b8dbd1b6bc794573292e312edf23ea4b03c0fa6cbee026b9d7bf32f39845f3ec\"","full_name":"msvisser/remeha_home","last_commit":"3dacb68","last_updated":"2024-02-23T15:13:19Z","last_version":"v0.1.13","manifest_name":"Remeha Home","open_issues":15,"stargazers_count":52,"topics":["home-assistant-component","home-assistant-integration","remeha","remeha-home"],"last_fetched":1711614081.471324},"342208616":{"manifest":{"name":"Resol KM1/KM2, DL2/DL3, VBus/LAN, VBus/USB"},"description":"Custom component for retrieving sensor information from Resol KM1/KM2, DL2/DL3, VBus/LAN, VBus/USB","downloads":498,"domain":"deltasol","etag_releases":"W/\"6b97875814f1ecaff51cd0fdb7ca8088041af4684bc3c45dfc20b0048f6a7f9b\"","etag_repository":"W/\"4b0787b846a8d4aa0f0b2aebdc806eb86866c4721d2a42082852ee46deca3b3f\"","full_name":"dm82m/hass-Deltasol-KM2","last_commit":"1bcb26b","last_updated":"2023-11-22T09:53:12Z","last_version":"0.3.3","manifest_name":"Resol KM2, DL2/DL3, VBus/LAN, VBus/USB","open_issues":4,"stargazers_count":21,"topics":["deltasol","km2"],"last_fetched":1710324946.657617},"528492198":{"manifest":{"country":["BE"],"name":"Telenet Telemeter"},"description":"Telenet Telemeter Home Assistant custom component HACS for Belgian ISP and mobile phone network traffic.","domain":"telenet_telemeter","etag_releases":"W/\"9f316bd13e6d98991019bd791ae31ef496f4b1af7dfa60458b2578c1cab3c7c1\"","etag_repository":"W/\"e52c27e346b09bb393ad1a3fd2900e691bbb32371a58452d008e5ac0ff756db3\"","full_name":"myTselection/telenet_telemeter","last_commit":"9adce95","last_updated":"2024-03-10T12:22:07Z","last_version":"1.6.0","manifest_name":"Telenet Telemeter","open_issues":2,"stargazers_count":26,"topics":["telemeter","telenet"],"last_fetched":1711311478.532131},"709665442":{"manifest":{"name":"GTFS2 for HomeAssistant"},"description":"Support GTFS in Home Assistant GUI-only","domain":"gtfs2","etag_releases":"W/\"6b050ee85be27ebb144955350d2e90860fce1b649625d50be6e12eb97bf93c5e\"","etag_repository":"W/\"fec03d48c65226796a23d3a3205319d8f0d7cc8a566342def89ee1ed28f8f3c3\"","full_name":"vingerha/gtfs2","last_commit":"426c412","last_updated":"2024-03-29T08:40:51Z","last_version":"0.4.3","manifest_name":"GTFS 2 (General Transit Feed Specification)","open_issues":1,"stargazers_count":53,"topics":["bus","gtfs","train","tram","transport"],"last_fetched":1712147439.575536},"199306003":{"manifest":{"name":"Buienalarm"},"description":"Buienalarm custom_component for Home-Assistant","domain":"buienalarm","etag_releases":"W/\"74b5fed2579fdc99126cd85a97ff925e3c970c542d0b70ff09a047fc3af5e53a\"","etag_repository":"W/\"5f6c1e053c148531733481eb547737fbf028dca377eac2b0cfe22cdb5827b2e7\"","full_name":"gieljnssns/buienalarm-sensor-homeassistant","last_commit":"ef20a78","last_updated":"2024-01-08T08:57:59Z","last_version":"v1.11","manifest_name":"Buienalarm","open_issues":12,"stargazers_count":29,"last_fetched":1708995380.309991},"256928191":{"manifest":{"country":["FR"],"name":"GCE Eco-Devices"},"description":"Home Assistant custom component for GCE Eco-Devices","domain":"ecodevices","etag_releases":"W/\"7c22e85fe41b08a28dfab7bc272bb29aa76346c11d9cf81f912e2d17fa731f97\"","etag_repository":"W/\"d175fa0493d497f19fde96252af1eedd9e16d6f2dbb6a27f2391e405d91b9617\"","full_name":"Aohzan/ecodevices","last_commit":"1dcd50a","last_updated":"2023-12-31T17:51:31Z","last_version":"5.0.0","manifest_name":"GCE Eco-Devices","stargazers_count":13,"topics":["domotique","eco-devices","ecodevices","gce-electronics"],"last_fetched":1709720022.626275},"427902632":{"manifest":{"name":"Solarman Integration"},"description":"Home Assistant component for Solarman collectors used with a variety of inverters. ","domain":"solarman","etag_releases":"W/\"f73cdb6aa58b9a7446660fe510260d6766404944b954f8c55abc8c1b302c616e\"","etag_repository":"W/\"9a40240890318850c9f90cc22796e74ad0228b72ecf8660ecc4df82f5f500dcd\"","full_name":"StephanJoubert/home_assistant_solarman","last_commit":"8ffb55f","last_updated":"2024-03-10T14:44:46Z","last_version":"1.5.1","manifest_name":"Solarman","open_issues":251,"stargazers_count":464,"topics":["deye","energy","inverter","sofar","sol-ark","solar","solarman","solis","sunsynk"],"last_fetched":1712053340.247765},"224258177":{"manifest":{"country":["FR"],"name":"Heatzy"},"description":"Climate Home Assistant component for Heatzy Pilot","domain":"heatzy","etag_releases":"W/\"047544790a8506657109759febf8b1298da65464ac4c0edfb7f520dfbd6be5ee\"","etag_repository":"W/\"40dcf2a405c29eeccee812767c687346e11f350203a607217bb70d2980455324\"","full_name":"cyr-ius/hass-heatzy","last_commit":"672ee9e","last_updated":"2024-02-10T12:12:09Z","last_version":"6.1.2","manifest_name":"Heatzy","open_issues":5,"stargazers_count":33,"topics":["climate","heatzy"],"last_fetched":1709655415.040421},"661020642":{"manifest":{"name":"INA219 UPS Hat"},"description":" Home Assistant UPS Hat integration. Waveshare and others based on INA219","domain":"ina219_ups_hat","etag_releases":"W/\"c6ead2a29fbe2ab283ab7f381005aaaa1976e09703067456c6f6613f3c734805\"","etag_repository":"W/\"abfd06f7f56b54f3b457708e863e15811b8fcdfe61469c10ba6d1413ca144f30\"","full_name":"odya/hass-ina219-ups-hat","last_commit":"47f6cb3","last_updated":"2023-11-03T21:29:08Z","last_version":"v0.3.3","manifest_name":"INA219 UPS Hat","open_issues":3,"stargazers_count":4,"topics":["ups"],"last_fetched":1711621167.071999},"204192861":{"manifest":{"name":"Average Sensor"},"description":"Average Sensor for Home Assistant","downloads":3580,"domain":"average","etag_releases":"W/\"607b2e9bdfab9e0b5155f2cad4dced55bb59728c87e202d3b1a1ea01fad7002b\"","etag_repository":"W/\"d53b88258303ce77c7f456d3df97864caaf9c564b5c3313dc15eda6f12226d1d\"","full_name":"Limych/ha-average","last_commit":"fd0c46f","last_updated":"2024-04-01T01:56:36Z","last_version":"2.3.4","manifest_name":"Average Sensor","open_issues":24,"stargazers_count":316,"topics":["average","home-assistant-component"],"last_fetched":1712082042.049163},"299875200":{"manifest":{"name":"Victor Smart-Kill"},"description":"Home Assistant integration for Victor Smart-Kill WI-FI electronic mouse and rat traps from VictorPest.com.","downloads":7,"domain":"victorsmartkill","etag_releases":"W/\"087cc380fa05a7b2a22071d86d6d7690defdea2ac7cdd94915cb18b5f920d3ee\"","etag_repository":"W/\"5930a5f0ddf5664ef6c7aa9530ed780bef3f7daeea9adc4d25104f74adc42f4a\"","full_name":"toreamun/victorsmartkill-homeassistant","last_commit":"c5df641","last_updated":"2024-03-31T13:10:12Z","last_version":"2023.1.0","manifest_name":"Victor Smart-Kill","open_issues":8,"stargazers_count":18,"topics":["mouse","rat","trap","victor"],"last_fetched":1711894711.536959},"199718799":{"manifest":{"name":"Escea Fires"},"description":"\ud83c\udfe1Home Assistant Custom Component for Escea Fires \ud83d\udd25","domain":"escea","etag_releases":"W/\"8e87624b2a69343cc15204f2682d94a82e619f66ea005ff74f3e682faa7a4228\"","etag_repository":"W/\"951af02515575b2cb7a0a5dd662ab70a5a01a27693d1a6ba812c75c40be23c01\"","full_name":"snikch/climate.escea","last_commit":"3faea54","last_updated":"2022-05-29T11:37:06Z","last_version":"v1.0.3","manifest_name":"Escea Fires","open_issues":1,"stargazers_count":10,"topics":["climate","fireplace"],"last_fetched":1706329290.864483},"564355840":{"manifest":{"name":"Shopping List with Grocy"},"description":"A Shopping list integration with Grocy for Home Assistant","domain":"shopping_list_with_grocy","etag_releases":"W/\"9b7fc7dc79120468cfffb534dddcb699401389f2ec21eb44b74d8fc9d367ae2e\"","etag_repository":"W/\"e9c8fbc546fe819d46d4acb79b48b1339a522bf3b097e405bfdc8c675591dfb7\"","full_name":"Anrolosia/Shopping-List-with-Grocy","last_commit":"fe8db05","last_updated":"2023-11-19T18:24:12Z","last_version":"v0.14.0","manifest_name":"Shopping List with Grocy","stargazers_count":37,"topics":["custom","grocy"],"last_fetched":1711663953.330273},"529083424":{"manifest":{"name":"myUplink"},"description":"Custom Home Assistant integration for devices and sensors in myUplink account.","domain":"myuplink","etag_releases":"W/\"c23b1b02c18395b6cd5ee13c72b9b15dfb2645687d8853447546846d4749885a\"","etag_repository":"W/\"1776cc914f68954c214ed8b1a393c81ecdcb8c4cad7d3a2f038141b1e32a6810\"","full_name":"jaroschek/home-assistant-myuplink","last_commit":"d327860","last_updated":"2024-03-04T16:22:00Z","last_version":"1.2.2","manifest_name":"myUplink","open_issues":24,"stargazers_count":35,"topics":["home-assistant-integration","myuplink","nibe","nibe-s"],"last_fetched":1711404984.38827},"246417951":{"manifest":{"name":"Whatpulse Sensor"},"description":"This component retrieves the statistics from Whatpulse","domain":"whatpulse","etag_repository":"W/\"41b1e162b3ce8fdb7e5121012033af4c99ebb7ed6a128036f3d480122e31101a\"","full_name":"SLG/home-assistant-whatpulse","last_commit":"665fe09","last_updated":"2021-06-03T17:59:28Z","manifest_name":"Whatpulse","stargazers_count":1,"topics":["whatpulse"],"last_fetched":1678387580.106852},"362700564":{"manifest":{"name":"Tesla"},"description":"Tesla custom integration for Home Assistant. This requires a refresh token be generated by third-party apps to login.","downloads":5374,"domain":"tesla_custom","etag_releases":"W/\"04f099923f8defe8d45399e95b28bd6513b6f7a4df1c3d690588a4c77b66e79e\"","etag_repository":"W/\"ea4029cea348db62f579ed55a4f4599053bd6c0c237b2bb62f9dfdb25011848b\"","full_name":"alandtse/tesla","last_commit":"280a702","last_updated":"2024-04-01T19:46:43Z","last_version":"v3.20.5","manifest_name":"Tesla Custom Integration","open_issues":100,"stargazers_count":510,"topics":["home-assistant-component","tesla"],"last_fetched":1712225587.962179},"598336481":{"manifest":{"country":["IL"],"name":"Israel Meteorological Service / sensor"},"description":"The Israel Meteorological Service (IMS) integration component for home assistant","domain":"ims","etag_releases":"W/\"466d30cd3994ba31f4a49614d4ef3e00174f8e59dd1f978d326f4c3288c8a52c\"","etag_repository":"W/\"aa2a52479e5c221f9ac81deabb77684d08a552a3a5ee9467fd930f4abfb2340f\"","full_name":"t0mer/ims-custom-component","last_commit":"7bac3e3","last_updated":"2024-02-05T08:20:32Z","last_version":"0.1.24","manifest_name":"The Israel Meteorological Service integration","open_issues":5,"stargazers_count":34,"topics":["ims","israel-meteorological-service","python3"],"last_fetched":1711311605.284901},"512965887":{"manifest":{"country":["CN"],"name":"mhtzn"},"description":"MHTZN custom component for Home Assistant","domain":"mhtzn","etag_releases":"W/\"f5b1a2508caa247d45eb7338bc2efba48a20536b8cd7a04bd389a064f04771f9\"","etag_repository":"W/\"3db91058aacc9e43fdaa5c6f6be21db632dbb626c8a0891504a0051f1b56262b\"","full_name":"leonardlcl/mhtzn","last_commit":"039312d","last_updated":"2023-02-27T02:30:14Z","last_version":"v1.4.12","manifest_name":"\u68c9\u82b1\u7cd6\u667a\u80fd","stargazers_count":2,"topics":["hass-mhtzn","mhtzn"],"last_fetched":1678387435.484001},"474183846":{"manifest":{"name":"HA-Mila"},"description":"\ud83c\udfe1 \ud83d\udca8 Home Assistant custom component for Mila Air Purifier (Unofficial)","domain":"mila","etag_repository":"W/\"e7cb5ae6530af0008022c5f9c74a0fe444794b549e7c3115014b65eef55e6013\"","full_name":"sanghviharshit/ha-mila","last_commit":"4916349","last_updated":"2024-01-29T17:17:46Z","manifest_name":"Mila Cares","open_issues":6,"stargazers_count":40,"topics":["air-purifier","air-quality","air-quality-sensor","mila"],"last_fetched":1707095018.967768},"442181774":{"manifest":{"name":"Daikin Altherma"},"description":"Daikin Altherma custom component for home assistant","domain":"daikin_altherma","etag_releases":"W/\"8673ddaa41504de6e16d72fdae66068b2343bf651ecc8889aa05d8506e341a5e\"","etag_repository":"W/\"d115f19b1ea4adb0b25b309c054384d4ffc4117f28d6719822f6993257c3f35f\"","full_name":"tadasdanielius/daikin_altherma","last_commit":"629231f","last_updated":"2024-01-03T21:43:01Z","last_version":"v1.4.0","manifest_name":"Daikin Altherma HVAC","open_issues":9,"stargazers_count":69,"topics":["altherma","brp069a61","brp069a62","daikin","daikin-altherma","homeassistant-custom-component"],"last_fetched":1711995822.785078},"153006394":{"manifest":{},"description":null,"domain":"school_holidays","etag_releases":"W/\"179408e11c98e0b5950288fa6676a6de80233c9e8fc262acb86998fa36b0c89e\"","etag_repository":"W/\"dac475ddbdbeb88fec5ed61d07f32833e64953ef870f2486e105973ee36313dd\"","full_name":"rt400/School-Vacation","last_commit":"57cb6b9","last_updated":"2024-02-24T18:32:13Z","last_version":"2.0.3","manifest_name":"Israel School Vacation Times","stargazers_count":10,"last_fetched":1711275605.849524},"514391925":{"manifest":{"name":"AppWash"},"description":"AppWash integration for HomeAssistant","domain":"appwash","etag_repository":"W/\"c3274b06ec3fc1a2b4321ed971e09f1e076f29342520752715f532ea68cfa080\"","full_name":"fapfaff/homeassistant-appwash","last_commit":"235b7b5","last_updated":"2022-07-21T16:30:20Z","manifest_name":"AppWash","topics":["dryer","miele","washing-machine"],"last_fetched":1678386438.248396},"600178779":{"manifest":{"country":["NL"],"name":"Sessy"},"description":"Home Assistant integration for Sessy (Smart Energy Storage SYstem)","domain":"sessy","etag_releases":"W/\"4c51c05421805c2dffc37adb292d57e12b442bca8d789463c2ea7fc55d17ae82\"","etag_repository":"W/\"ecf8396f1a0e2cdc2da1025ff009840316db75c5ff8a7c19b00dfc350e09e65f\"","full_name":"PimDoos/ha-sessy","last_commit":"87be3d7","last_updated":"2024-04-03T19:05:40Z","last_version":"v0.5.6","manifest_name":"Sessy","open_issues":4,"stargazers_count":21,"topics":["energy-storage-systems","homeassistant-custom-component","sessy"],"last_fetched":1712175669.053938},"604796673":{"manifest":{"country":["BE","FR","NL","IT","DE","LU"],"name":"Carbu.com"},"description":"Home Assistant custom component HACS integration to Carbu.com site to compare and save on your actual fuel oil / heating oil (mazout) and fuel (diesel, super and lpg) purchases in Belgium, France and Luxembourg. Actual fuel prices per gasstation supported for Belgium, France, Luxembourg, Spain, Netherlands, Germany and Italy too!","domain":"carbu_com","etag_releases":"W/\"254edbbb7f77815d5d05015e0cb559f5d28faa7d32048aa44d141d94f63ea98c\"","etag_repository":"W/\"a8a334d7f5db2c196a9fd4a51c1dab79f1b3d71f2c49fe7ac57673c1d93bbf06\"","full_name":"myTselection/Carbu_com","last_commit":"6a36d90","last_updated":"2024-03-10T12:25:41Z","last_version":"9.1.0","manifest_name":"Carbu.com","open_issues":3,"stargazers_count":16,"topics":["fuel-prices","price-tracker"],"last_fetched":1710973040.103933},"598381225":{"manifest":{"name":"Fronius_Solarweb"},"description":"Home Assistant integration for cloud-based Fronius Solar.web api","downloads":1610,"domain":"solarweb","etag_releases":"W/\"3f756324e4fc096f2bf8d5e57688b3ec653235b2613bed6cd45ab968c1a03671\"","etag_repository":"W/\"ce3aec47b2e59a2f0e7144efd87af2c68fda58bb94f31f17fd577d560098215e\"","full_name":"drc38/Fronius_solarweb","last_commit":"b5dedc4","last_updated":"2024-04-04T09:04:28Z","last_version":"0.2.1","manifest_name":"Fronius Solar.Web","open_issues":3,"stargazers_count":2,"topics":["fronius","fronius-solar-api"],"last_fetched":1712225729.948949},"186605347":{"manifest":{"name":"Bosch thermostat"},"description":"HA custom component for Bosch thermostats","domain":"bosch","etag_releases":"W/\"7a114aec4b0ceee8867735aecc77bcf1d49f42c74dcb6eb430b40fb7c2dfc17a\"","etag_repository":"W/\"12d1c79f6a5cc6ad9c667eff5db724aa5d773c033848981ae072dbf3b42aca33\"","full_name":"bosch-thermostat/home-assistant-bosch-custom-component","last_commit":"849641e","last_updated":"2024-04-01T15:47:57Z","last_version":"v0.25.0","manifest_name":"Bosch thermostat","open_issues":4,"stargazers_count":195,"topics":["bosch","bosch-thermostat","buderus","nefit","sensors","thermostat","xmpp"],"last_fetched":1712175331.991667},"181480967":{"manifest":{},"description":"Generic Hygrostat for Home Assistant","domain":"generic_hygrostat","etag_releases":"W/\"c20558a60a5e5370d8e48f52aef18d7dea929db314e884975a17a1ebd83bc085\"","etag_repository":"W/\"ce0030520f0ac05b1c82efbcdf1f3fd4d9be914f07b1b858d1ed2e3174a94b63\"","full_name":"basschipper/homeassistant-generic-hygrostat","last_commit":"a57d2c1","last_updated":"2023-12-13T09:52:19Z","last_version":"v0.8.0","manifest_name":"Generic Hygrostat","open_issues":4,"stargazers_count":72,"last_fetched":1711328205.222615},"269665267":{"manifest":{"name":"Yamaha (YNCA)"},"description":"Custom integration for Home Assistant to support Yamaha AV receivers with the YNCA protocol (serial and network).","domain":"yamaha_ynca","etag_releases":"W/\"3b4ea4dacf74e1a7f1f126739d80a35c084f6eb18ec5dcbc70e6545127b5f3e2\"","etag_repository":"W/\"4a2cc9121dd490bd301c2d425cd4780211281def5a854be2f06a4875f448d762\"","full_name":"mvdwetering/yamaha_ynca","last_commit":"0e16a1d","last_updated":"2024-03-24T14:55:25Z","last_version":"v7.7.0","manifest_name":"Yamaha (YNCA)","open_issues":5,"stargazers_count":30,"topics":["home-assistant-component","yamaha-avr","yamaha-receiver"],"last_fetched":1712031660.712277},"201805130":{"manifest":{"name":"nordpool"},"description":"This component allows you to pull in the energy prices into Home-Assistant.","domain":"nordpool","etag_releases":"W/\"d1ea7fac67a0da1562146ac6906bbf642280a5ceaf2de24012c315f3ff6773e1\"","etag_repository":"W/\"4089c0fe72e4d2a91a19e296fde398e1b382fade859bae61203941444030a9a4\"","full_name":"custom-components/nordpool","last_commit":"83b6869","last_updated":"2024-03-31T06:13:26Z","last_version":"0.0.14","manifest_name":"Nord Pool","open_issues":35,"stargazers_count":404,"topics":["energy-prices","nordpool"],"last_fetched":1712081841.465602},"237695750":{"manifest":{"country":["AU"],"name":"OpenNEM (AU) Data"},"description":"OpenNEM Sensor for Home Assistant","domain":"opennem","etag_releases":"W/\"2c53c31d45f90f1f6fcbff0d7c99e1c012e6b868e51e852a80b5e0d5bf42ab67\"","etag_repository":"W/\"c23d5b70ab74a7646d1efda141dc50e2af4642780f982eb92d44f336cdc3aa04\"","full_name":"bacco007/sensor.opennem","last_commit":"abe6ef6","last_updated":"2023-09-08T23:56:08Z","last_version":"2023.09.1","manifest_name":"OpenNEM","open_issues":8,"stargazers_count":11,"topics":["opennem"],"last_fetched":1698281630.517351},"432522624":{"manifest":{"country":["FR"],"name":"GCE IPX800 V5"},"description":"IPX800 V5 integration for Home-Assistant","domain":"ipx800v5","etag_releases":"W/\"47594e162ddcb6aa4555dd55c5ad12f5d4cd05145655a916999070c7bd4d6408\"","etag_repository":"W/\"5d71ca2e6b8c6d4d64ac692f49d6548be116222789f7340670cad88aac26a665\"","full_name":"Aohzan/ipx800v5","last_commit":"86a94e8","last_updated":"2024-03-21T20:38:43Z","last_version":"1.7.0","manifest_name":"GCE IPX800 V5","stargazers_count":10,"topics":["domotique","gce-electronics","home-assistant-integration","ipx800","ipx800-v5","ipx800v5"],"last_fetched":1711059173.812715},"137655647":{"manifest":{},"description":"HomeAssistant component for control of Virgin Media Tivo boxes","domain":"virgintivo","etag_releases":"W/\"df6e8aaabcc62f93603448b49510da2810acf68ae6a56d95487e4601b4097b2c\"","etag_repository":"W/\"2883fc96a737d4665157ead37ade7ecad03c41afb11aec7fb613234785fe0c09\"","full_name":"bertbert72/HomeAssistant_VirginTivo","last_commit":"1a962ee","last_updated":"2024-01-16T05:02:29Z","last_version":"0.1.27","manifest_name":"Virgin Tivo","open_issues":3,"stargazers_count":27,"last_fetched":1711268119.215058},"203244705":{"manifest":{"name":"OpenMensa Sensor"},"description":"A platform sensor which tells you which meals are served in your canteen.","domain":"openmensa","etag_repository":"W/\"58d6e0c4e54ea46caa2aa180080557d039be0c90eb54570c19fc0e195f37eaf2\"","full_name":"Mofeywalker/openmensa-hass-component","last_commit":"c9238a2","last_updated":"2021-09-04T08:04:28Z","manifest_name":"Openmensa","stargazers_count":4,"last_fetched":1711793917.013709},"158194879":{"manifest":{"name":"Entity Controller"},"description":"Home Assistant Entity and lighting controller for managing devices with timers, scripts, and sun-based time restrictions.","domain":"entity_controller","etag_releases":"W/\"1c8cf4e5857702f4ae5819b0024933b6d69515333da231917d05cd806dee5ef5\"","etag_repository":"W/\"936daf57511973a7c70179924f565dba18e960bdd19fe6b6cde5490cf8a43cfe\"","full_name":"danobot/entity-controller","last_commit":"29e9af5","last_updated":"2024-03-19T05:10:18Z","last_version":"v9.7.3","manifest_name":"Entity Controller","open_issues":14,"stargazers_count":272,"topics":["entity-controller","finite-state-machine","internet-of-things","iot","lighting-controller","motion-light","motion-sensor"],"last_fetched":1711729047.912281},"339464185":{"manifest":{"name":"Weishaupt WEM Portal"},"description":"Custom component for retrieving sensor information from Weishaupt WEM Portal","domain":"wemportal","etag_releases":"W/\"1b79b91cc4d82c4abfacf9302868493abc3f538bd1b8faf1b10d6436889a803a\"","etag_repository":"W/\"01dd6a8994f36ccea3aed913cdc60f4edaafbe1cbd4e567f403cda724bf433ae\"","full_name":"erikkastelec/hass-WEM-Portal","last_commit":"9ae02d7","last_updated":"2023-06-01T08:39:06Z","last_version":"1.5.9","manifest_name":"Weishaupt WEM Portal","open_issues":12,"stargazers_count":42,"topics":["weishaupt","wem-portal"],"last_fetched":1712168318.754961},"388918745":{"manifest":{"name":"Creasol DomBus"},"description":"Home Assistant integration for Creasol DomBus RS485 modules (inputs, outputs, sensors).","domain":"creasoldombus","etag_repository":"W/\"bce31a2cc73483d49fff5e2ea5b4d40bbbcd1768c26286d64f5549ac1ad10637\"","full_name":"CreasolTech/home-assistant-creasol-dombus","last_commit":"9e7b2a8","last_updated":"2023-07-22T10:29:32Z","manifest_name":"Creasol DomBus RS485 modules","stargazers_count":1,"topics":["dombus","domotic","rs485"],"last_fetched":1690028608.548119},"261614146":{"manifest":{"country":["FR"],"name":"SickChill"},"description":"\ud83c\udfa5 SickChill component to feed Upcoming Media Card.","domain":"sickchill","etag_releases":"W/\"fe2e2851753f768e42abdcc6e87db2aa0875eb6c61029d8c8c114535143a8c02\"","etag_repository":"W/\"e834029512b476b7e6ec31f87b2902c2fe792ab3a8a610ad746f2e76388f4ecb\"","full_name":"youdroid/home-assistant-sickchill","last_commit":"5128514","last_updated":"2022-06-01T18:12:09Z","last_version":"V1.3.2","manifest_name":"SickChill Next TV Shows","stargazers_count":3,"topics":["sickchill"],"last_fetched":1682699129.531283},"290193894":{"manifest":{"name":"Rollease Acmeda Automate Pulse Hub v2"},"description":"Rollease Acmeda Automate Pulse Hub v2 integration for Home Assistant","domain":"automate","etag_releases":"W/\"e34bafe45358b4c8f1eff37fe4825a4044662b2e280ea9e37ace1dfc354cdb6e\"","etag_repository":"W/\"22935198f2f4ddd92c06dbaef413816b7bec1430d11ad6b2f1fbfafbb3a1803e\"","full_name":"sillyfrog/Automate-Pulse-v2","last_commit":"5ae0c79","last_updated":"2023-02-10T20:57:35Z","last_version":"v0.9.9","manifest_name":"Automate Pulse Hub v2","open_issues":4,"stargazers_count":30,"last_fetched":1711477403.393538},"445609628":{"manifest":{"name":"PID Controller"},"description":"PID Controller to Home Assistant","downloads":1844,"domain":"pid_controller","etag_releases":"W/\"08a3f2b403bb096269154adbe1a6e492d21f8e6f762c7fd23045eeb10e190f0d\"","etag_repository":"W/\"52cd0b73ba0fc28a0135fefb91d00af71fbd99bad5d7fa96548b08a4fd694e8d\"","full_name":"soloam/ha-pid-controller","last_commit":"6005239","last_updated":"2023-12-24T10:09:42Z","last_version":"v1.1.5","manifest_name":"PID Controller","open_issues":27,"stargazers_count":83,"topics":["pid","thermostat"],"last_fetched":1711808308.147503},"303793543":{"manifest":{"country":["EN","CZ"],"name":"Skydance"},"description":"A Home Assistant integration for communication with Skydance lighting WiFi relay.","domain":"skydance","etag_releases":"W/\"ffca60b28577d84ebb4f811e9359dc7db3ae9d6fdd9865697633396773bde4d9\"","etag_repository":"W/\"d7c2b577126bb02c828865c8663ea7529f45464fbfb2b546157b709734079336\"","full_name":"tomasbedrich/home-assistant-skydance","last_commit":"cb057e4","last_updated":"2024-03-01T08:44:00Z","last_version":"3.0.0","manifest_name":"Skydance","open_issues":1,"stargazers_count":15,"topics":["networking"],"last_fetched":1709288492.097247},"692576253":{"manifest":{"name":"Nextcloud Talk Bot"},"description":"Custom component for Home Assistant to communicate between Home Assistant and Nextcloud Talk","domain":"nctalkbot","etag_releases":"W/\"c87a4e26e569013c10b2d4d5ba90798139049e688348ccab0a2eac58b93f462d\"","etag_repository":"W/\"5b154a8e2a785f13f8d9ace8ca5e0001db46257f9c2713ff3016222b59b9dabe\"","full_name":"klatka/nc-talk-bot-component","last_commit":"3b0f6ff","last_updated":"2024-02-06T12:50:07Z","last_version":"0.4.1","manifest_name":"Nextcloud Talk Bot","stargazers_count":8,"topics":["homeassistant-custom-component","nextcloud","nextcloud-talk","nextcloud-talk-bot","nextcloud-talk-chat-bot","notify"],"last_fetched":1711772332.676216},"567001290":{"manifest":{"name":"EnergyScore"},"description":"Custom Integration for Home Assistant to score how energy is utilized based on price point","domain":"energyscore","etag_releases":"W/\"5ec6057647672073ca5ffe8587a290878a88c3e844e304a09e55fabb147b9621\"","etag_repository":"W/\"4219851ce02d72c7b5d266b095e53d502d7337af469cc65c02210fcde09e59b3\"","full_name":"knudsvik/EnergyScore","last_commit":"d958ea6","last_updated":"2023-10-15T12:44:22Z","last_version":"v1.3.3","manifest_name":"EnergyScore","open_issues":19,"stargazers_count":32,"topics":["energy"],"last_fetched":1712082020.334303},"223739645":{"manifest":{"name":"Climate IP"},"description":"Home Assistant Climate Device for controlling (not only) Samsung AC","domain":"climate_ip","etag_releases":"W/\"e1337bc3c8cb48f309aab9722fb58ee5fd02e4e46e0ca938c5e773d25c68301e\"","etag_repository":"W/\"1d30757cf555fe7acb981c612807016c54faa8726bd2eae97f5d0e7faf5e017b\"","full_name":"atxbyea/samsungrac","last_commit":"20e0854","last_updated":"2024-01-14T13:37:14Z","last_version":"6.0.1","manifest_name":"Climate IP","open_issues":24,"stargazers_count":52,"topics":["airconditioning","hacktoberfest2021","samsung"],"last_fetched":1711181685.321087},"593275617":{"manifest":{"name":"Gradual Volume Control"},"description":"Home Assistant integration providing a service to gradually change the volume of media_players over a given timespan.","domain":"grad_vol","etag_releases":"W/\"a37183fe01a6127b9018e2cb5055d70771b1cfae4b2df5e3b1288e4e4ff9a0df\"","etag_repository":"W/\"7c882f736acdf72eff9059c1ec689bad2ad4f5c92ffd9882b97ff81450fe8006\"","full_name":"NinDTendo/homeassistant_gradual_volume_control","last_commit":"5f25af1","last_updated":"2023-10-01T21:37:58Z","last_version":"1.0.1","manifest_name":"Gradual Volume","stargazers_count":7,"topics":["home-assistant-config"],"last_fetched":1711024064.149388},"333849286":{"manifest":{"country":["DK"],"name":"Eforsyning"},"description":"Home Assistant module enabling retrieval of regional heating data from eForsyning.","domain":"eforsyning","etag_releases":"W/\"04866d5d98f050753a4ab44bcbfc0080422508f62967d976f33703105f6ff5eb\"","etag_repository":"W/\"ca1f45fb0bf5106da73c8081017471946f14b0dcb8fc793a1d6669aa4b71279d\"","full_name":"kpoppel/homeassistant-eforsyning","last_commit":"10863ae","last_updated":"2024-03-05T06:47:58Z","last_version":"v1.2.5","manifest_name":"EForsyning","open_issues":9,"stargazers_count":31,"topics":["energy","heating"],"last_fetched":1710339403.603898},"117426840":{"manifest":{"name":"Volkswagen We Connect"},"description":"Volkswagen Carnet Component for home assistant","downloads":3574,"domain":"volkswagencarnet","etag_releases":"W/\"67568e14b258546c965487f4df4e821c2c673255ee006a4c22bbd7fc554ab157\"","etag_repository":"W/\"81667c0388e51c7a0ef6e9cfd9c2e3367be13719b1fb89f2234696e99c529c9c\"","full_name":"robinostlund/homeassistant-volkswagencarnet","last_commit":"e297300","last_updated":"2024-03-17T23:03:11Z","last_version":"v4.5.9","manifest_name":"Volkswagen WeConnect","open_issues":3,"stargazers_count":290,"topics":["volkswagen-carnet"],"last_fetched":1712226009.20031},"411736321":{"manifest":{"name":"DWD Pollenflug"},"description":"Adds pollen forecasts from DWD to Home Assistant.","domain":"dwd_pollenflug","etag_releases":"W/\"5305c0370d2b734c0b28431ea044762c331c4d21662224350f2db2db869f5e7b\"","etag_repository":"W/\"9393190541da4bc6db76a68b7d362a8006785fa12f5c8e05e4b0d355d67d60ee\"","full_name":"mampfes/hacs_dwd_pollenflug","last_commit":"0b29e54","last_updated":"2023-09-20T15:34:23Z","last_version":"1.0.3","manifest_name":"DWD Pollenflug","stargazers_count":51,"topics":["dwd","pollen","pollenflug"],"last_fetched":1712182611.883124},"593695273":{"manifest":{"country":["GB"],"name":"DVLA Vehicle Enquiry Service"},"description":"A custom component for connecting to the DVLAs Vehicle Enquiry Service API.","domain":"dvla","etag_releases":"W/\"fdb661e2f519c7323320a70938bdd5c34faf6c0e72121ad3410505291a788d7a\"","etag_repository":"W/\"18d3ba073396036f931e734a062c5b4b08d3d56472bc8c9c0d64142e5dad5af2\"","full_name":"jampez77/DVLA-Vehicle-Enquiry-Service","last_commit":"9fae51e","last_updated":"2024-01-12T11:25:50Z","last_version":"2024.1.0","manifest_name":"DVLA Vehicle Enquiry Service","open_issues":4,"stargazers_count":21,"last_fetched":1710951632.395906},"174809046":{"manifest":{"name":"Avanza Stock"},"description":"Custom component to get stock data from Avanza for Home Assistant","domain":"avanza_stock","etag_releases":"W/\"ee10a4b0efbedfab02ed5087921ec75a01a44b2432acbf7b7c374145cd9211b9\"","etag_repository":"W/\"7df47ddb468d78ba6b9b1f6187a3c71387bcf3dd4a446169f321bfc4b416b335\"","full_name":"custom-components/sensor.avanza_stock","last_commit":"4838a02","last_updated":"2024-04-01T07:15:24Z","last_version":"v1.5.2","manifest_name":"Avanza Stock","stargazers_count":44,"topics":["funds","stock"],"last_fetched":1712074696.154422},"445977563":{"manifest":{"name":"Plum ecoMAX boiler controller integration"},"description":"Plum ecoMAX boiler controller integration for Home Assistant.","domain":"plum_ecomax","etag_releases":"W/\"eab5cd1067c0151b37ebfc5ee3faaf813e8d550c918f262eae6c64c45e6eec44\"","etag_repository":"W/\"c610437436fdbbe8c7b4429f4e022c1e2b319c5fe670097a7f82c6560f3d1cdb\"","full_name":"denpamusic/homeassistant-plum-ecomax","last_commit":"1837e15","last_updated":"2024-04-01T18:26:27Z","last_version":"v0.4.3","manifest_name":"Plum ecoMAX","open_issues":18,"stargazers_count":26,"topics":["ecomax","econet","heating-controller","heating-monitoring","python3"],"last_fetched":1712002570.279559},"237628853":{"manifest":{"country":["DE"],"name":"Abfall API (RegioIT)"},"description":"Abfall API (RegioIT) custom component for home assistant - Get an alert when garbage collection is due","domain":"abfallapi_regioit","etag_repository":"W/\"a7c388685a02101b1d951aa44e22f17cc41ce0ba626d4f66ad18b0e006aa18ff\"","full_name":"tuxuser/abfallapi_regioit_ha","last_commit":"4408613","last_updated":"2023-11-13T19:12:48Z","manifest_name":"regioit api waste collection schedule","open_issues":2,"stargazers_count":11,"topics":["collection","component","garbage","muell","muellabfuhr","regioit","waste"],"last_fetched":1705616429.724054},"651444976":{"manifest":{"country":["ES"],"name":"Gas Stations Spain"},"description":"Home Assistant Component for Gas Stations of Spain","domain":"gas_station_spain","etag_releases":"W/\"2af3933a7abfdefbccbf79592c6bc241a9503f13dfa5fda6d417fbd6cff23de8\"","etag_repository":"W/\"3780ee3eb7a7c11a7f634074623f53b9e9575ebd73ab439c393ace55cf6abcd8\"","full_name":"MiguelAngelLV/gas_station_spain","last_commit":"ec14544","last_updated":"2024-01-29T20:34:08Z","last_version":"V1.3","manifest_name":"Gasolineras de Espa\u00f1a","open_issues":2,"stargazers_count":20,"topics":["gasstations","homassistant","spain"],"last_fetched":1712182632.611983},"379688863":{"manifest":{"country":["CA"],"name":"Thermal Vision"},"description":"Thermal Vision Sensor and Camera for Home Assistant","domain":"thermal_vision","etag_releases":"W/\"9942221b01ab116b932dcc7c310748c8b363970ee4213167138f3c142b0df3c8\"","etag_repository":"W/\"38181e8e51dfc33ddc82c9c55a2234c80ec10338652bb921c172fb2d68f1e5e7\"","full_name":"TheRealWaldo/thermal","last_commit":"9ddf0a9","last_updated":"2023-11-01T15:18:00Z","last_version":"v3.1.5","manifest_name":"Thermal Vision","open_issues":6,"stargazers_count":57,"topics":["homeassistant-custom-component","thermal-camera"],"last_fetched":1711197100.787876},"127689312":{"manifest":{"country":["CA"],"name":"Sinope Neviweb"},"description":"Neviweb Custom Component for Home Assistant to manage devices connected via GT125","domain":"neviweb","etag_releases":"W/\"f1644c4c7689f76e952b8130082193154faae388f858678a4709d16ef5531dce\"","etag_repository":"W/\"ac37a2dd338670b061a4d3812a68e6f23ba85b35d134352f1f255b5be606248d\"","full_name":"claudegel/sinope-1","last_commit":"b8e41be","last_updated":"2024-01-06T20:53:05Z","last_version":"v2.1.7","manifest_name":"Sinope Neviweb","stargazers_count":28,"topics":["neviweb","sinope"],"last_fetched":1706206673.628955},"542062483":{"manifest":{"name":"HASS.Agent"},"description":"HASS.Agent's Home Assistant integration. Adds notifications and mediaplayer capabilities to HASS.Agent - a Windows based client (companion app) for Home Assistant.","domain":"hass_agent","etag_releases":"W/\"4b6922e98476598dc6e280fd2b763373a703ec1477ffe8bba31598c11b838927\"","etag_repository":"W/\"e530e9e82249aff9113c47f7c7b0d112991693a2b7cf1be0a6444b7649395f58\"","full_name":"LAB02-Research/HASS.Agent-Integration","last_commit":"78c580c","last_updated":"2024-04-01T19:15:20Z","last_version":"v2022.11.9","manifest_name":"HASS.Agent","open_issues":21,"stargazers_count":86,"topics":["notifications"],"last_fetched":1712175564.569434},"300358676":{"manifest":{"name":"Tapo: Cameras Control"},"description":"Control for Tapo cameras as a Home Assistant component","domain":"tapo_control","etag_releases":"W/\"0213ab71e4d4636dd1cf9e1031daa16731c42b21734e84c0d8a37082c43ff122\"","etag_repository":"W/\"0c4fd7f9dfc3eeb6a628c19ec32082d1bb6e7a14c65660c8e7ea92ba2916947b\"","full_name":"JurajNyiri/HomeAssistant-Tapo-Control","last_commit":"cfa9dba","last_updated":"2024-04-02T09:52:14Z","last_version":"5.4.17","manifest_name":"Tapo: Cameras Control","open_issues":30,"stargazers_count":809,"topics":["camera","cameras","homeassistant-custom-component","ptz","tapo"],"last_fetched":1712225846.352547},"344446335":{"manifest":{"name":"Office 365"},"description":"Office 365 integration for Home Assistant","downloads":2891,"domain":"o365","etag_releases":"W/\"dbca6ad758bcc9290aa9f7cc79315fc6b5b3391a34382daa9601f7e22e46a503\"","etag_repository":"W/\"825b48950dfbe516071a6194e5f55a1e03ef51b67a26c36f934f9108bd6d1baa\"","full_name":"RogerSelwyn/O365-HomeAssistant","last_commit":"dae856d","last_updated":"2024-03-25T09:29:33Z","last_version":"v4.7.0","manifest_name":"Office 365","open_issues":1,"stargazers_count":156,"topics":["homeassistant-custom-component","microsoft","o365"],"last_fetched":1712009998.378143},"434912125":{"manifest":{"country":["ZA"],"name":"Load Shedding"},"description":"A Home Assistant integration to track your load schedding schedule.","domain":"load_shedding","etag_releases":"W/\"efdaaf7acb1e5e1c5c07d976b5690fefd9026990ede97f6e025109c22b224f70\"","etag_repository":"W/\"7b1f53bcc7746db623d4f2f6bc8c0c9f45a9c19c4f50dc710324b8cd3d453501\"","full_name":"wernerhp/ha.integration.load_shedding","last_commit":"393dcd1","last_updated":"2024-03-30T14:43:29Z","last_version":"v1.3.2","manifest_name":"Load Shedding","open_issues":12,"stargazers_count":108,"topics":["eskom","load-shedding"],"last_fetched":1711815835.246143},"682685628":{"manifest":{"name":"Stateful Scenes"},"description":"Stateful Scenes in Home Assistant (Home Kit scene compatible)","downloads":440,"domain":"stateful_scenes","etag_releases":"W/\"e7c7cc4cf6ecac0b882c46e86c3bba9fb3e7b73dbebb1e1edac7c8b4af6906bc\"","etag_repository":"W/\"3c28bfda818ba7f7d256d9bafbe27156206a5d0915bf8ebd1b031c3fb37db80e\"","full_name":"hugobloem/stateful_scenes","last_commit":"2ceb10f","last_updated":"2024-04-02T06:25:37Z","last_version":"1.2.1","manifest_name":"Stateful Scenes","open_issues":5,"stargazers_count":31,"topics":["custom-integration","ha-scene","homeassistant-scenes","homekit","homekit-scenes","stateful-scene"],"last_fetched":1712218818.423598},"459336824":{"manifest":{"country":["US"],"name":"hass-lacrosseview"},"description":"La Crosse view for Home Assistant","domain":"lacrosseview","etag_releases":"W/\"1ec812712bdb3ff49b46fc52154d3c06cb3c3902db279def058677b6456d0c61\"","etag_repository":"W/\"a5b08253d23299a518087b8d5828fa4bdcb483c2931e3e1616c1a9cd3c0363be\"","full_name":"regulad/hass-lacrosseview","last_commit":"db43c09","last_updated":"2023-05-13T19:16:21Z","last_version":"v0.1.5","manifest_name":"La Crosse View","open_issues":4,"stargazers_count":5,"topics":["home-assistant-config","lacrosseview"],"last_fetched":1712067518.757729},"606857916":{"manifest":{"name":"Deye Dehumidifier"},"description":"Control Deye (\u5fb7\u4e1a) Dehumidifier devices from Home Assistant","domain":"deye_dehumidifier","etag_releases":"W/\"eddec1111f67b1e5fb4376f1af371561fbda10e32409b3c6dc0918a3243620ea\"","etag_repository":"W/\"4cf189223c911831efc7bbd19414bf1395316867bf186b52f972792a2c624ea7\"","full_name":"stackia/ha-deye-dehumidifier","last_commit":"70d7610","last_updated":"2024-04-04T06:32:23Z","last_version":"v1.5.0","manifest_name":"Deye Dehumidifier","stargazers_count":30,"topics":["deye","home-assistant-component"],"last_fetched":1712219066.746554},"278930028":{"manifest":{"name":"Linkplay-based speakers and devices"},"description":"LinkPlay based media devices integration for Home Assistant. Supports multiroom, Media Browser, and snapshot and restore functionality for TTS. Compatible with Mini Media Player card.","domain":"linkplay","etag_releases":"W/\"32a09a2dbb0251403ba85ae25546ed6a3b0297a450fd23ec29b1d8de3cc64371\"","etag_repository":"W/\"90915c5acf3b332f6152ac123f04f550563ca9f3384c8d3f2cf75c273356a5ca\"","full_name":"nagyrobi/home-assistant-custom-components-linkplay","last_commit":"2822455","last_updated":"2024-01-07T18:16:23Z","last_version":"3.2.0","manifest_name":"Linkplay","open_issues":9,"stargazers_count":146,"topics":["arylic","cvte","harman-kardon","linkplay","speaker","tts"],"last_fetched":1712168514.612257},"203592862":{"manifest":{"country":["CN"],"name":"USR-R16 16\u8def\u7f51\u7edc\u7ee7\u7535\u5668"},"description":"USR-R16 integration for Home Assistant","domain":"usr_r16","etag_repository":"W/\"01168fb354ee1cb182b9b6459006ec84c33b2d7b76a473aa0d4d32e6e7f1efd6\"","full_name":"blindlight86/HA_USR-R16","last_commit":"c123192","last_updated":"2022-07-31T19:41:14Z","manifest_name":"USR r16","open_issues":2,"stargazers_count":8,"topics":["relays"],"last_fetched":1706638584.358323},"286186485":{"manifest":{"name":"Scheduler component"},"description":"Custom component for HA that enables the creation of scheduler entities","downloads":1,"domain":"scheduler","etag_releases":"W/\"8c4ad0397ab1fee0faae6a2f132ac44f6198d51bf5d663299c155e0060392092\"","etag_repository":"W/\"1bfccc17ffb023b50b7e8287d4bc741bd2606c218478bee87fd2365a5c84367d\"","full_name":"nielsfaber/scheduler-component","last_commit":"0a80ab6","last_updated":"2024-04-03T06:18:01Z","last_version":"v3.3.3","manifest_name":"Scheduler","open_issues":7,"stargazers_count":561,"topics":["scheduler"],"last_fetched":1712153894.658844},"524883312":{"manifest":{"name":"Q-Sys QRC integration"},"description":"Home Assistant Q-Sys QRC integration","domain":"qsys_qrc","etag_releases":"W/\"de5433fcbdab644d434eb84a58a756ea64bcf496ae304437782af60c2c927580\"","etag_repository":"W/\"a4a6b49b6301c40155592b50d8bfe583a5e9e94635a762dc61fe817b529fde35\"","full_name":"nkvoll/home-assistant-qsys-qrc","last_commit":"c37e9e1","last_updated":"2024-02-02T09:47:32Z","last_version":"v0.4.0","manifest_name":"Q-Sys QRC Integration","open_issues":2,"stargazers_count":6,"topics":["hacs-custom","home-assistant-custom-component","home-assistant-integration","q-sys","qsys"],"last_fetched":1712009939.310595},"195438291":{"manifest":{"name":"Nintendo Wishlist"},"description":"A sensor that monitors a Nintendo Switch wish list for when games are on sale.","domain":"nintendo_wishlist","etag_releases":"W/\"b96164a66bbb60f8d4937020d9ff367165917e1b81e6651c76bb69ca4c048adb\"","etag_repository":"W/\"3aada6b4fe09c1ddadbaa650f41689ac478c57f0afdedb27304941cafbd5ebac\"","full_name":"custom-components/sensor.nintendo_wishlist","last_commit":"53d9cb5","last_updated":"2023-12-21T23:42:09Z","last_version":"3.1.13","manifest_name":"Nintendo Wishlist Component","open_issues":1,"stargazers_count":16,"topics":["nintendo-switch"],"last_fetched":1710303358.937938},"603218187":{"manifest":{"name":"MyLight Systems"},"description":"MyLight Systems integration - Home Assistant","domain":"mylight_systems","etag_releases":"W/\"3f634a1021dfc6512ffc2b0ac48f6c207e2a228e1b7304181cf6830cebd6a558\"","etag_repository":"W/\"a790e6abb5be026e5bdfff8dd3334fb4c5dc392468e17fad8dc1db93b1e7842e\"","full_name":"acesyde/hassio_mylight_integration","last_commit":"226aa89","last_updated":"2024-04-01T06:35:02Z","last_version":"0.1.1","manifest_name":"MyLight Systems","open_issues":5,"stargazers_count":5,"topics":["mylight"],"last_fetched":1711995323.318451},"680920137":{"manifest":{"name":"Aerogarden"},"description":"Aerogarden integration for Home Assistant","downloads":46,"domain":"aerogarden","etag_releases":"W/\"d22967356a14ad44e0ed793cef489c08fe5fa7438dedafa31bdfbd91f2752942\"","etag_repository":"W/\"8c4d9432c51fd84a20570a887e98637071d23538da53165a3f59069a5d207943\"","full_name":"dalinicus/homeassistant-aerogarden","last_commit":"3557a38","last_updated":"2024-01-07T16:44:33Z","last_version":"1.4.1","manifest_name":"Aerogarden","open_issues":1,"stargazers_count":7,"topics":["aerogarden","bounty","farm","harvest","hydroponics"],"last_fetched":1704831343.143455},"507038522":{"manifest":{"name":"NAD Multi-room Audio Controller"},"description":"NAD Multi-room Audio Controller HomeAssistant Integration","domain":"nad_controller","etag_releases":"W/\"15ad04f13c61890bc65749a6445df22a6863ca404adf6e23a07e2d0ac4bc5742\"","etag_repository":"W/\"8f37d613174e745ec29be4356dac52c061048e15a415938f3731072fb41fc557\"","full_name":"Breina/nad_controller","last_commit":"dd21ff7","last_updated":"2024-02-29T13:14:52Z","last_version":"v0.1.1","manifest_name":"NAD Multi-room Audio Controller","open_issues":1,"topics":["amplifier-controller"],"last_fetched":1709216141.727769},"527179792":{"manifest":{"country":["AT"],"name":"wnsm"},"description":"A home-assistant integration supporting WienerNetze Smartmeters as sensors","downloads":451,"domain":"wnsm","etag_releases":"W/\"da2c1e13c6b6768c0b89224b375aa72f9a2b546b920919639c719d9e85cec10d\"","etag_repository":"W/\"892029d6a8f3fa5177a1557de6c335bc1824de2bd391efe37e49ad9bd748ec7d\"","full_name":"DarwinsBuddy/WienerNetzeSmartmeter","last_commit":"5c39eb8","last_updated":"2024-03-17T09:53:43Z","last_version":"v1.4.7","manifest_name":"WienerNetzeSmartmeter","open_issues":9,"stargazers_count":113,"topics":["energy","smartmeter","wien-energie","wiener-netze"],"last_fetched":1712153651.096412},"299753146":{"manifest":{"name":"Xiaomi Cloud Map Extractor"},"description":"This custom integration provides a way to present a live view of a map for Xiaomi (Roborock/Viomi/Roidmi/Dreame) vacuums without a need for rooting.","downloads":42532,"domain":"xiaomi_cloud_map_extractor","etag_releases":"W/\"c83e18e73af7858401ab0c8fe1b5ba431dcd6f59509739e7874d576ad05209e2\"","etag_repository":"W/\"7a5c5e7eb50592d01a00dca45fad7b1c4cd625f70d7245423ecfecdb09097e52\"","full_name":"PiotrMachowski/Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor","last_commit":"2475e84","last_updated":"2024-01-24T21:33:35Z","last_version":"v2.2.1","manifest_name":"Xiaomi Cloud Map Extractor","open_issues":74,"stargazers_count":1079,"topics":["cloud","dreame","map","roborock","robot","roidmi","vacuum","vacuum-map","viomi","xiaomi","xiaomi-smart-home","xiaomi-vacuum"],"last_fetched":1712074997.566237},"615769161":{"manifest":{"name":"v2c_trydan"},"description":"Electric car charger for v2c trydan in home asssitant via HACS","downloads":1,"domain":"v2c_trydan","etag_releases":"W/\"a3e59e404079627eb49ef6b92d98d5de0fd4c4d35b6c8822caa8a6d629d577c1\"","etag_repository":"W/\"f5b865dec69ea0a155b5a0c8991a8b0e477f4da05c40f1b474216c990fa07f7c\"","full_name":"Rain1971/V2C_trydant","last_commit":"6226f40","last_updated":"2024-04-01T19:00:43Z","last_version":"v2.9.8","manifest_name":"v2c_trydan","open_issues":1,"stargazers_count":16,"topics":["v2c"],"last_fetched":1712002862.546982},"635072820":{"manifest":{"name":"T-Smart thermostat"},"description":"Support for Tesla T-Smart thermostats in Home Assistant","domain":"t_smart","etag_releases":"W/\"a7d8825c7339d958156f0a6498bdafbb06f08870f1bb8b77ba7a08c502ecac41\"","etag_repository":"W/\"6805334f7911a099dd52399f8904c3b763ff161b25e812380fc6492d9f957d09\"","full_name":"pdw-mb/tsmart_ha","last_commit":"2f8cc01","last_updated":"2024-04-03T12:51:36Z","last_version":"0.3.0","manifest_name":"T-Smart Thermostat","open_issues":5,"stargazers_count":7,"topics":["t-smart"],"last_fetched":1712153910.625031},"651666000":{"manifest":{"name":"Harvest Time Tracker"},"description":"Unofficial Home Assistant integration for www.getharvest.com","domain":"harvest_time_tracker","etag_releases":"W/\"d0919751eb16ee87d5eaf879f12cbd5a6bfce5441e3623e54dfa184a7eb41ade\"","etag_repository":"W/\"8e3f73042b967ca109615e9507161429cfdc5a0deb30e4c8abcba3fcb919a9be\"","full_name":"BottlecapDave/HomeAssistant-HarvestTimeTracker","last_commit":"4474b80","last_updated":"2024-01-31T21:09:08Z","last_version":"v1.1.1","manifest_name":"Harvest Time Tracker","stargazers_count":2,"topics":["harvest","harvest-api","timetracker"],"last_fetched":1709605120.85729},"362513331":{"manifest":{"name":"Technicolor"},"description":"This is an integration for HomeAssistant. It's a Device Tracker component for the Technicolor Gateway.","domain":"technicolor","etag_releases":"W/\"3e9f31e8b6ac51b12e2d6a652eca3c36a3840c63a6fe15d6ca51d7e9b5d8d5c9\"","etag_repository":"W/\"11d097d2a216cb8f2def527b3724323dee6d31a572b3cffd2e31acc6570af962\"","full_name":"shaiu/technicolor","last_commit":"97996e5","last_updated":"2023-05-28T09:30:46Z","last_version":"v0.6.0","manifest_name":"Technicolor","open_issues":4,"stargazers_count":6,"last_fetched":1707762150.225702},"220313935":{"manifest":{"country":["NO","SE"],"name":"hass-AMS"},"description":"Custom component reading AMS through MBus adapter into HomeAssistant","domain":"ams","etag_releases":"W/\"a7490b0366d612bc75ca817d3f0039cba214b7e8bdf50a9ed11fdc155c42a47d\"","etag_repository":"W/\"34a49b65a4c36508b872ee68e90650fbeadcccc1669dcc662bb023122e7ac594\"","full_name":"turbokongen/hass-AMS","last_commit":"dd9e32c","last_updated":"2024-03-17T07:15:08Z","last_version":"v2.0.1","manifest_name":"AMS Reader","open_issues":2,"stargazers_count":41,"topics":["mbus-adapter","meter","sensors"],"last_fetched":1711052498.247662},"396695907":{"manifest":{"name":"Gree Extension for Home-Assistant built in integration"},"description":"Gree Extension for built in integration","domain":"gree_ext","etag_repository":"W/\"4e17d8c5d2139c4cf68faf5689d04693ab6cadb1a041cd018b969586cb780d5c\"","full_name":"mullerdavid/hass_GreeExt","last_commit":"77915fa","last_updated":"2023-06-12T09:56:03Z","manifest_name":"Gree climate extension","open_issues":1,"stargazers_count":7,"topics":["gree"],"last_fetched":1711534768.90493},"175020245":{"manifest":{},"description":"Sensor which gathers water outage information from Tavos (Slovakia) website","domain":"tavos_water_outage","etag_releases":"W/\"a058bbff75e97a017ac9cdb1a6873c59b0eea842e0bccd190665576adf6386ba\"","etag_repository":"W/\"ace370e7dae8f6cb7ac5b01fbeb5f54d9c8aadcd6a9401672103dbdc0f5136d4\"","full_name":"JurajNyiri/HomeAssistant-Tavos","last_commit":"c37ea6e","last_updated":"2022-06-16T17:05:17Z","last_version":"1.1.3","manifest_name":"Tavos Water Outage","last_fetched":1703348305.848186},"151550084":{"manifest":{},"description":"A set of sensors to integrate the OWL Intuition devices network","domain":"owlintuition","etag_repository":"W/\"f94024cca7664b0281fd97d9a935bc4795e489847a6d8499a21d983cf54e00c9\"","full_name":"custom-components/sensor.owlintuition","last_commit":"b479dc3","last_updated":"2024-01-16T16:31:20Z","manifest_name":"OWL Intuition","open_issues":3,"stargazers_count":11,"last_fetched":1709546790.753166},"368653916":{"manifest":{"name":"MOOX-Track"},"description":"MOOX-Track Custom Component for HASS (hass-moox-track) is a custom component that connects your MOOX Track devices to Home Assistant as \"Device Trackers\"","domain":"moox_track","etag_releases":"W/\"b00a3043749e4199b6a649625d10fec8cd6324c94f398d7a555d0b5ee44bce5f\"","etag_repository":"W/\"ef1479737b426c001f609adc38a92f0f8db780cd26849a4d8803d7d5d1dd6cc5\"","full_name":"moox-it/hass-moox-track","last_commit":"5e48101","last_updated":"2024-01-16T17:02:06Z","last_version":"1.6","manifest_name":"MOOX Track","stargazers_count":1,"topics":["device","gps","moox","track","tracker"],"last_fetched":1705429307.915174},"348835574":{"manifest":{"country":["SE"],"name":"Motala Vatten & Avfall - Garbage collection sensor"},"description":"A sensor for getting collection date for garbage and sludge from Motala Vatten & Avfall.","downloads":3,"domain":"motalavattenavfall","etag_releases":"W/\"14ccec73a595fbeb7cd51595eb32f4ec43fab3af1d0f73c8e7279a34856925d0\"","etag_repository":"W/\"591a1d64b05398dd087c79773b90532f36eb26f8a6326e3317a30ffa4708ed9f\"","full_name":"popeen/Home-Assistant-Custom-Component-MotalaVattenAvfall","last_commit":"41da2e2","last_updated":"2023-09-23T10:39:35Z","last_version":"0.1.4","manifest_name":"Motala Vatten & Avfall","stargazers_count":3,"topics":["garbage-collection","motala"],"last_fetched":1705256501.504238},"231824299":{"manifest":{"name":"Warmup under-floor heating integration"},"description":"Home Assistant integration for Warmup heating thermostats as a HACS integration or a custom component","domain":"warmup","etag_releases":"W/\"8249781c0af7b5b49947db8649f7424a8074a47719a0dcb1b5e7a63079b5b587\"","etag_repository":"W/\"5671bfd2b5454827883c4defc30e5053a9d63858636402c01985ae8c879c50eb\"","full_name":"ha-warmup/warmup","last_commit":"14ab761","last_updated":"2024-03-06T18:23:45Z","last_version":"v2024.2.7","manifest_name":"Warmup","open_issues":19,"stargazers_count":24,"topics":["climate","climate-control","heating","heating-control","thermostat","warmup"],"last_fetched":1709756236.187587},"253842395":{"manifest":{"name":"Jaguar Landrover InControl"},"description":"An integration for JLR InControl to Home Assistant","domain":"jlrincontrol","etag_releases":"W/\"e931f55ea2e14fed3726b48758fbbeb77f597fa3c1ffb866bcc317a7a196f8c5\"","etag_repository":"W/\"c590c942051261e12c9c3211a4c7ee9b95e2805ce1833b1c8159ba30f538260a\"","full_name":"msp1974/homeassistant-jlrincontrol","last_commit":"f2a6c62","last_updated":"2024-03-20T23:35:44Z","last_version":"v2.2.7","manifest_name":"Jaguar Landrover InControl","open_issues":9,"stargazers_count":52,"topics":["i-pace","jaguar","jlr","landrover","rrs","vehicle","wirelesscar"],"last_fetched":1712225930.460681},"625947979":{"manifest":{"country":["BE","NL"],"name":"Youfone"},"description":"Home Assistant component for Youfone BE & NL services","domain":"youfone","etag_releases":"W/\"8c0a02d846269758b55ff14974346daf087b89036bb40943a2ad13ec5d2b7a87\"","etag_repository":"W/\"6baec34b6824d381712437e228bda2d580c84f810b3695e560daf6fd358d2159\"","full_name":"geertmeersman/youfone","last_commit":"ab597ce","last_updated":"2024-03-25T15:55:35Z","last_version":"v0.10.6","manifest_name":"Youfone","stargazers_count":3,"topics":["youfone"],"last_fetched":1711390785.206707},"129353521":{"manifest":{"name":"Xiaomi MiIO Raw"},"description":"Custom component for Home Assistant to faciliate the reverse engeneering of Xiaomi MiIO devices","domain":"xiaomi_miio_raw","etag_releases":"W/\"41f29b8ec822fdc85471c8527c1468e59d517a3831acb8c5a628082f5f54b688\"","etag_repository":"W/\"103aab88b4730b925c3e376e46f7e28f5b3bd8dc2b58b789d58e1873fa8291e0\"","full_name":"syssi/xiaomi_raw","last_commit":"a56838b","last_updated":"2024-02-11T14:06:43Z","last_version":"2024.2.0.0","manifest_name":"Custom component for Home Assistant to faciliate the reverse engeneering of Xiaomi MiIO devices","open_issues":11,"stargazers_count":102,"topics":["miio","miio-device","miio-protocol","monitoring"],"last_fetched":1710541241.794856},"627970137":{"manifest":{"name":"HERU"},"description":"\u00d6stberg HERU energy recovery unit component for Home Assistant","downloads":114,"domain":"heru","etag_releases":"W/\"c6cb21cc5b8ffa727e5f037f643a58bd05cd934db93ba7fcd22bf23e2a5b1217\"","etag_repository":"W/\"8a3ff5a4b97dbdd13d8605ed654ec7af06c4a05cfd0f2c4b40a49e54d5e5f8e5\"","full_name":"toringer/home-assistant-heru","last_commit":"26bf87b","last_updated":"2024-03-04T16:27:26Z","last_version":"v1.0.3","manifest_name":"HERU","open_issues":5,"stargazers_count":11,"topics":["climate","energy-recovery","energy-recovery-unit","heru","ostberg"],"last_fetched":1709576616.541817},"537001731":{"manifest":{"name":"Facebook Messenger"},"description":"Home Assistant custom integration for Facebook Messenger.","domain":"facebook_messenger","etag_releases":"W/\"046b72979f2d29f47852b5df37d3876ddada1d72a2cfdfc899f58ed0b25ea7a7\"","etag_repository":"W/\"97ddd93bf00c0c0bd41e7210c025d70b56553ac5749734f906330e098629e863\"","full_name":"emes30/facebook_messenger","last_commit":"80895d1","last_updated":"2022-09-26T21:07:38Z","last_version":"v1.0.2","manifest_name":"Facebook Messenger","open_issues":6,"stargazers_count":12,"topics":["facebook","images","messenger"],"last_fetched":1701651626.28592},"313759590":{"manifest":{"name":"Mint Mobile"},"description":"Mint Mobile Integration for Data Usage Monitoring","domain":"mintmobile","etag_releases":"W/\"a5d2d1ac68cf88340f6222cc577445c6e802c4833386dd8ae17041d4a92c7423\"","etag_repository":"W/\"5d811f631f92ba9c05922167cc8b0de9fac342edee4b470dfacbd00d924a0098\"","full_name":"ryanmac8/HA-Mint-Mobile","last_commit":"6a86612","last_updated":"2024-01-23T15:51:03Z","last_version":"v1.9","manifest_name":"Mint Mobile","open_issues":3,"stargazers_count":7,"topics":["automation"],"last_fetched":1707186321.374496},"262645913":{"manifest":{"country":["FR"],"name":"gitea"},"description":"\ud83c\udf75 Gitea component to follow your repositories","domain":"gitea","etag_releases":"W/\"93123cd03a2fbcf3ecc937aa808c55ddda49e33522cd3304dee9ef2b93fd419a\"","etag_repository":"W/\"4fc39ce13f414f614514d679446bca3738b57e208a05125c9031838204c498e3\"","full_name":"youdroid/home-assistant-gitea","last_commit":"730fe8a","last_updated":"2022-04-24T20:15:46Z","last_version":"V1.3.1","manifest_name":"gitea","open_issues":1,"stargazers_count":10,"topics":["gitea","homeassistant-custom-component","pyhton"],"last_fetched":1702066898.406035},"340759468":{"manifest":{"country":["NZ"],"name":"NIWA Tides"},"description":"Custom integration for Home Assistant to get New Zealand tide information from NIWA Tides API","domain":"niwa_tides","etag_releases":"W/\"5bda2c252697cda1c5ffbc6e5f0505240d31733aa89f9c62d60d0c87dda33ade\"","etag_repository":"W/\"8a9b2dae2d2a044155ee81ac8d5a57509de036fd164a2e3a4d23ee16f55cb804\"","full_name":"muxa/home-assistant-niwa-tides","last_commit":"bd9c3c3","last_updated":"2024-03-30T20:31:58Z","last_version":"v1.1.3","manifest_name":"NIWA Tides","stargazers_count":6,"topics":["tides"],"last_fetched":1711837088.673321},"676012641":{"manifest":{"name":"Audiobookshelf"},"description":"Adds sensors for an Audiobookshelf server to Home Assistant to show connection and active sessions","domain":"audiobookshelf","etag_releases":"W/\"b6d44ba50f538b40275ec215bbef881adb686cb169891a08717504e263aee2b5\"","etag_repository":"W/\"cd80aaaf1610f5b28ec03f48cf111faa2f3ab1f387d8492e01ce66ee7080e781\"","full_name":"wolffshots/hass-audiobookshelf","last_commit":"f25fca9","last_updated":"2024-03-05T18:57:00Z","last_version":"v0.0.5","manifest_name":"Audiobookshelf","open_issues":2,"stargazers_count":28,"topics":["audiobooks","audiobookshelf"],"last_fetched":1710865453.280464},"582955421":{"manifest":{"name":"SmartEVSE"},"description":"Integrate SmartEVSEv3 with HomeAssistant through custom component ","domain":"smartevse","etag_releases":"W/\"12a8bc1e6dace7d09cdd525098ae341b406b690283684f2d3e252af9b16a0bf8\"","etag_repository":"W/\"2ee7e52997524fb3aa7fb2446fbbc077c0e839a56c6e8a223a10cf11143a6b09\"","full_name":"dingo35/ha-SmartEVSEv3","last_commit":"49f3cd9","last_updated":"2024-03-29T20:58:20Z","last_version":"v1.1.1","manifest_name":"SmartEVSE-3","open_issues":1,"stargazers_count":11,"topics":["evse"],"last_fetched":1711750478.381252},"480127478":{"manifest":{"country":["DE"],"name":"ista EcoTrend"},"description":"ecotrend-ista Home Assistant Integration","downloads":213,"domain":"ecotrend_ista","etag_releases":"W/\"0d473b4d52255f20998bcee1c92f23c4a28ef5c7832d5a5a5f81acffb7b1f52f\"","etag_repository":"W/\"5951f1a894252dfea47a28e17bed454da7f9d0f750f2237587fb3a3edbbeb3a3\"","full_name":"Ludy87/ecotrend-ista","last_commit":"411cb21","last_updated":"2024-04-04T01:15:27Z","last_version":"v2.3.0","manifest_name":"ecotrend ista","open_issues":12,"stargazers_count":32,"topics":["ecotrend","hassio-integration","hassos","home-assistant-component","ista"],"last_fetched":1712197636.276885},"499901994":{"manifest":{"country":["DE","AT","CH"],"name":"Solarfocus eco manager-touch"},"description":"\ud83c\udfe1 Solarfocus eco manager touch integration for Home Assistant","domain":"solarfocus","etag_releases":"W/\"079f10b5d3747ca762a3cbe4e8ca3d6ed51d2d2ce49ff3eda56030a8116eccb9\"","etag_repository":"W/\"9985dd519350f47b4d519525119582a39428fe29fcfc39021d8d0a298d826651\"","full_name":"LavermanJJ/home-assistant-solarfocus","last_commit":"1ade22a","last_updated":"2024-03-01T21:43:40Z","last_version":"v4.2.0.1","manifest_name":"Solarfocus","open_issues":9,"stargazers_count":11,"topics":["home-assistant-component","solarfocus"],"last_fetched":1712089062.687237},"562404203":{"manifest":{"country":["BE"],"name":"RecycleApp"},"description":"Integrate RecycleApp into your Home Assistant.","domain":"recycle_app","etag_releases":"W/\"5b86bfb8f729a5006632479e6e645ef3a4474b572ca47954f6d468e63f161fca\"","etag_repository":"W/\"8522bdb278380bf26371e57455e00ebb5f8612779dd178de2ca0c278cbb9f8e3\"","full_name":"olibos/HomeAssistant-RecycleApp","last_commit":"8edf0c1","last_updated":"2024-04-03T21:13:06Z","last_version":"v2.4.0","manifest_name":"RecycleApp","open_issues":2,"stargazers_count":22,"topics":["fostplus","recycle"],"last_fetched":1712182669.652622},"635745672":{"manifest":{"name":"Netro Watering"},"description":"Netro Smart Garden integration for Home Assistant","domain":"netro_watering","etag_releases":"W/\"d8743ae446124fa5bb3a35710fe516aa999613fc5ffdd83eb4e764796332687c\"","etag_repository":"W/\"1c8fa68e6a3f90df126d497360b4842be5aaaa13e3b566c94439b9a21d292f4d\"","full_name":"kcofoni/ha-netro-watering","last_commit":"5ac6f93","last_updated":"2023-12-01T19:30:20Z","last_version":"1.2.0","manifest_name":"Netro Watering","stargazers_count":9,"topics":["asynchronous-programming","automation","irrigation","irrigation-controller","netro","plant","python3","sensors","water-monitoring","watering"],"last_fetched":1702736170.71752},"235943258":{"manifest":{"country":["US"],"name":"Hubitat"},"description":"A Hubitat integration for Home Assistant","domain":"hubitat","etag_releases":"W/\"e2e7b8800f5cf36a2f5600c54b6820d3f8911fad704cb9cb8a9b8798904de38d\"","etag_repository":"W/\"6081f40a5f66395820b15c12c0603e2c27c4138a75ca3083ba68aa67d3cbea0e\"","full_name":"jason0x43/hacs-hubitat","last_commit":"84f37ee","last_updated":"2024-03-27T04:12:13Z","last_version":"v0.9.26","manifest_name":"Hubitat","open_issues":35,"stargazers_count":178,"topics":["hubitat","maker-api"],"last_fetched":1712053107.961682},"171854441":{"manifest":{"name":"youtube"},"description":"A platform which give you info about the newest video on a channel","downloads":3462,"domain":"youtube","etag_releases":"W/\"4a709c98791fa150c16abd1d63f24a75d908249a57eb58f3fb80de507ffaf2b0\"","etag_repository":"W/\"79483917102b49f282d0cf3c983b0186692ebb69cd543e088de93a3ffa8277d3\"","full_name":"custom-components/youtube","last_commit":"54e7664","last_updated":"2024-03-13T19:45:36Z","last_version":"0.9.1","manifest_name":"Youtube Sensor","open_issues":5,"stargazers_count":54,"topics":["youtube"],"last_fetched":1710951505.763372},"356778495":{"manifest":{"name":"WebRTC Camera"},"description":"Home Assistant custom component for real-time viewing of almost any camera stream using WebRTC and other technologies.","domain":"webrtc","etag_releases":"W/\"4529dbdcb4c45c15243d18ae51e4b286fae168fd9c88219a177b5ea7f80433f9\"","etag_repository":"W/\"1ce02d8143eada82a66531b7199f849172bdcbcafe80242fee4c5749459ab0ae\"","full_name":"AlexxIT/WebRTC","last_commit":"309b6d5","last_updated":"2024-03-13T23:11:17Z","last_version":"v3.5.1","manifest_name":"WebRTC Camera","open_issues":135,"stargazers_count":1241,"topics":["ip-camera","mediasource-extensions","rtsp","webrtc"],"last_fetched":1712124959.430075},"534083455":{"manifest":{"country":["DE"],"name":"Deutsche Bahn"},"description":"Unofficial HA DB Integration, due to removal as of Home Assistant 2022.11","domain":"deutschebahn","etag_releases":"W/\"ba679ffddb891ddd56c5e3e5861b391f20c367df4bd14ab4aca3756141e95d54\"","etag_repository":"W/\"e788afe0927fc1207d5984d64247d333a310d34242b7752f5cd7a97bb47da774\"","full_name":"FaserF/ha-deutschebahn","last_commit":"ab5b7c5","last_updated":"2023-12-28T18:13:24Z","last_version":"2.2.0","manifest_name":"Deutsche Bahn","open_issues":10,"stargazers_count":34,"last_fetched":1711765137.255486},"534848317":{"manifest":{"name":"Redback Technologies"},"description":"Home Assistant integration for inverter and battery systems from Redback Technologies","domain":"redback","etag_repository":"W/\"9dc6d8b09d80b6e92541ee467a3409a93c9941ab90e1315cc69e15ec9c0aee46\"","full_name":"juicejuice/homeassistant_redback","last_commit":"b4ff10e","last_updated":"2024-03-03T22:52:37Z","manifest_name":"Redback Technologies Portal","open_issues":6,"stargazers_count":6,"topics":["inverter","redback-technologies"],"last_fetched":1710231565.612542},"164155243":{"manifest":{},"description":"Sensor for Home Assistant pulling data from the GoodWe SEMS API for solar panel production metrics.","domain":"sems","etag_releases":"W/\"7619ba2baebeaecc4c736eb802de44ce48eae933c504446d83f840282eca75f7\"","etag_repository":"W/\"3cee849bff1464744e389abb2c748ea12c5fc02676e0d4fae9e1bf2a904a1044\"","full_name":"TimSoethout/goodwe-sems-home-assistant","last_commit":"2fbd646","last_updated":"2024-04-03T07:08:35Z","last_version":"5.0.0","manifest_name":"GoodWe SEMS API","open_issues":23,"stargazers_count":78,"topics":["goodwe-sems","pv","sems-portal"],"last_fetched":1712132663.536878},"401282856":{"manifest":{"name":"Octopus Energy"},"description":"Unofficial Home Assistant integration for interacting with Octopus Energy","domain":"octopus_energy","etag_releases":"W/\"3abd88a471ca8525ba98cd102b4aa890a21d97713a59bd58f1469f7c495e4c6d\"","etag_repository":"W/\"2296c5308c292ff005b87ae092a7ea41bb040aad0fa312f0e0daa100b95cfe64\"","full_name":"BottlecapDave/HomeAssistant-OctopusEnergy","last_commit":"d51647c","last_updated":"2024-04-03T18:25:00Z","last_version":"v10.1.4","manifest_name":"Octopus Energy","open_issues":53,"stargazers_count":477,"topics":["energy-consumption","octopus-energy"],"last_fetched":1712211429.447152},"448323715":{"manifest":{"name":"Nest Protect"},"description":"Nest Protect integration for Home Assistant. This will allow you to integrate your smoke, heat, co and occupancy status real-time in HA.","domain":"nest_protect","etag_releases":"W/\"07c7d202ad4bd48e1a81dc0e9408f6484c1482ce4a089d06aff3fdfe88a313ec\"","etag_repository":"W/\"a46f74fa50ba8041ae9ff551e0f69adeb222df16cbd6711bd19a27bbfe0a930c\"","full_name":"iMicknl/ha-nest-protect","last_commit":"812f51a","last_updated":"2024-03-08T08:39:22Z","last_version":"v0.3.12","manifest_name":"Nest Protect","open_issues":53,"stargazers_count":295,"topics":["google","nest","nest-protect"],"last_fetched":1711760204.987272},"281956859":{"manifest":{"name":"D-Link HNAP"},"description":"Experimental integration to Home Assistant supporting D-Link devices","domain":"dlink_hnap","etag_repository":"W/\"5ebbaccf4a820a1419adf0ac76b4de72d637b623806c6389efa186417bb8ab6d\"","full_name":"postlund/dlink_hnap","last_commit":"774df53","last_updated":"2022-05-28T09:18:28Z","manifest_name":"D-Link HNAP","open_issues":4,"stargazers_count":42,"topics":["custom-integration","dlink"],"last_fetched":1709669987.789245},"403401396":{"manifest":{"name":"HERE Destination Weather"},"description":"Custom Home Assistant Integration for the HERE Destination Weather API","domain":"here_weather","etag_releases":"W/\"093e317460e8a97a12f877ca1c298972eef64c8db37df8c27c8de1de881d5f12\"","etag_repository":"W/\"6d1b486c72fda6b3de445286fd7360ca1786f8f9dd46582db40d8cf78e70e176\"","full_name":"eifinger/hass-here-weather","last_commit":"e67c8c6","last_updated":"2023-09-25T07:45:59Z","last_version":"v4.0.7","manifest_name":"HERE Destination Weather","open_issues":8,"stargazers_count":6,"topics":["here-maps-api","herepy","homeassistant-custom-component","pyton"],"last_fetched":1711995485.678239},"340596609":{"manifest":{"name":"Panasonic Smart App"},"description":"\ud83d\udd1b Panasonic Smart App integration for Home Assistant.","domain":"panasonic_smart_app","etag_releases":"W/\"2937a6f7f698a6bb3ce0d7450807dba227d0d092551c89a21d85c071fff1bcd6\"","etag_repository":"W/\"e4646efa20d17ccd81d79f2b8adefccff8c54b52c4f0e2cf20ce8f7cd579c692\"","full_name":"osk2/panasonic_smart_app","last_commit":"5b1da1f","last_updated":"2024-02-20T04:40:20Z","last_version":"v2.8.0","manifest_name":"Panasonic Smart App","open_issues":6,"stargazers_count":74,"topics":["panasonic"],"last_fetched":1711852126.791862},"199332790":{"manifest":{"name":"Variable"},"description":"A custom Home Assistant component for declaring and setting generic variable entities dynamically.","domain":"var","etag_releases":"W/\"1261505c375d000caf3c7168b5461d32375ff70c2c1754c417c2d6f432737627\"","etag_repository":"W/\"addedb6d83d5ed8e88b5ff491d9013ae1dc14aa0f641d26fbfb79108c29f3388\"","full_name":"snarky-snark/home-assistant-variables","last_commit":"dd47735","last_updated":"2024-03-25T13:50:15Z","last_version":"v0.15.2","manifest_name":"Variable","open_issues":17,"stargazers_count":255,"last_fetched":1712002910.935409},"534750752":{"manifest":{"name":"XY Screens projector screens and projector lifts"},"description":"Home Assistant integration for XY Screens projector screens and projector lifts over the RS-485 interface","domain":"xyscreens","etag_releases":"W/\"53e34f92ce54e220e4b0dd0795a83df4b5748bbdce34718e434034d2aabebc09\"","etag_repository":"W/\"ab1b00d0450f5c3f0cfad97684fcd3ab77fe1b5113e56803752fc6d37c8d433f\"","full_name":"rrooggiieerr/homeassistant-xyscreens","last_commit":"c07df4b","last_updated":"2024-01-04T00:21:27Z","last_version":"0.0.8","manifest_name":"XY Screens","stargazers_count":1,"topics":["projector-sceen","xy-screens"],"last_fetched":1704838760.641822},"325329098":{"manifest":{"name":"Sleep As Android"},"description":"Sleep As Android integration for Home Assistant","downloads":2448,"domain":"sleep_as_android","etag_releases":"W/\"668bd2d60182880893b23f293a8fc1ae177eccf93fc31fe2f9615156be01be1b\"","etag_repository":"W/\"21e71e871eeced97abcc48463a4ef679ae7acdd6d90efd238a63ee82d235634a\"","full_name":"IATkachenko/HA-SleepAsAndroid","last_commit":"4bfb7b1","last_updated":"2024-03-21T20:07:11Z","last_version":"v2.3.0","manifest_name":"Sleep As Android","open_issues":6,"stargazers_count":139,"topics":["mqtt","sleep-analysis","sleep-as-android","sleep-tracker"],"last_fetched":1711059367.994614},"228604799":{"manifest":{"country":["NL"],"name":"Arpscan Device Tracker"},"description":"This component tracks devices using the arp-scan liinux command, it's very fast, and reasonably accurate.","domain":"arpscan_tracker","etag_releases":"W/\"261cc9f94e8c28fea7f22b13c19e059d84e5835fd2bd5dca257cbbe5cbe3ba83\"","etag_repository":"W/\"834c07a09ae508d0708bf4a126e24b3aa38bda2a53f367301c149f47e8f5aa88\"","full_name":"cyberjunky/home-assistant-arpscan_tracker","last_commit":"d216415","last_updated":"2023-05-09T20:03:04Z","last_version":"1.0.7","manifest_name":"Arpscan tracker","stargazers_count":24,"last_fetched":1708978532.135416},"597502676":{"manifest":{"name":"Hikvision NVR / IP Camera"},"description":"Home Assistant integration for Hikvision NVRs and IP cameras","domain":"hikvision_next","etag_releases":"W/\"4878fdd2fd86429a3db8f37f08e443940d68beee570b24321614a87fe8f174ad\"","etag_repository":"W/\"c1281ebf297efdf020a1e44d02e5245e804c5fc009f842f4327f0bcea831ae4d\"","full_name":"maciej-or/hikvision_next","last_commit":"b5ac8a5","last_updated":"2024-04-02T05:50:14Z","last_version":"v1.0.11","manifest_name":"Hikvision NVR / IP Camera","open_issues":59,"stargazers_count":74,"topics":["hikvision"],"last_fetched":1712082057.394068},"277201070":{"manifest":{"name":"AmsHan"},"description":"Home Assistant integrasjon for str\u00f8mm\u00e5lere (AMS/HAN/P1). Integrasjonen st\u00f8ter b\u00e5de streaming (serieport/TCP-IP) og MQTT (Tibber Pulse, energyintelligence.se etc)","downloads":29,"domain":"amshan","etag_releases":"W/\"5ecb18f773cb8560e3e7d9e28ec9fd5f3163c848e64296ca6268981adc0cf839\"","etag_repository":"W/\"31b811f157651f6519ef084f31bfed80f7cf042e0824438b110f567cf2d8bf35\"","full_name":"toreamun/amshan-homeassistant","last_commit":"7e1d865","last_updated":"2024-01-06T18:44:22Z","last_version":"2023.6.0","manifest_name":"AMS HAN meter","open_issues":16,"stargazers_count":137,"topics":["aidon","ams","han","kaifa","kamstrup","mbus","meterbus","mqtt","p1","smart-meter","tibberpulse"],"last_fetched":1712082231.585887},"292616002":{"manifest":{"name":"Seedboxes.cc"},"description":"Home Assistant - Seedboxes.cc Integration","domain":"seedboxes_cc","etag_releases":"W/\"869dd3a1139f461962e3459948676431048da8354ccdb8269b6215bbc4e2116d\"","etag_repository":"W/\"9662d2bd55181d66e47b21dd1da2f97ad22588128fe4b4e1761038590b94daf2\"","full_name":"swartjean/ha-seedboxes-cc","last_commit":"06a15da","last_updated":"2021-04-05T10:15:21Z","last_version":"v1.0.2","manifest_name":"Seedboxes.cc","stargazers_count":2,"topics":["monitoring","seedbox","torrents"],"last_fetched":1690532503.871858},"454951296":{"manifest":{"name":"Raspberry Pi GPIO"},"description":"Home Assistant Raspberry Pi GPIO Integration","domain":"rpi_gpio","etag_releases":"W/\"c6ca0f506ca125dac7a3946c381389981c89b4be72100af1f343cf0a7ddfd68a\"","etag_repository":"W/\"68ab6106f3b135dc441ea226995d665ea63d8127200906ee7bdac8d5fa2c8f46\"","full_name":"thecode/ha-rpi_gpio","last_commit":"4f95e91","last_updated":"2024-03-26T19:28:32Z","last_version":"2022.7.0","manifest_name":"Raspberry Pi GPIO","stargazers_count":160,"topics":["iot","raspberry-pi","rpi-gpio"],"last_fetched":1711974731.86927},"200897141":{"manifest":{"name":"lovelace_gen"},"description":"\ud83d\udd39 Improve the lovelace yaml parser for Home Assistant","domain":"lovelace_gen","etag_releases":"W/\"a0f468e0ce0e1f173fd68cdd2d0defc4139a01a426a0cc9cd68372141db85eb3\"","etag_repository":"W/\"0995c23d9b7b82c5354119cb68abf50ec9afeba2c25c7c8c62eba5749b6ef335\"","full_name":"thomasloven/hass-lovelace_gen","last_commit":"d81ed07","last_updated":"2024-01-21T22:10:47Z","last_version":"0.1.2","manifest_name":"Lovelace Gen","open_issues":26,"stargazers_count":199,"last_fetched":1711102949.191148},"627734223":{"manifest":{"country":["US"],"name":"Monarch"},"description":"\ud83d\udcb0\ud83d\udcb2\ud83c\udfe0\ud83d\udcb3\ud83c\udfe6 Integration for Monarch in Home Assistant","domain":"monarchmoney","etag_releases":"W/\"50b322727f9c354c53ef15d778a2ed09c48f778ebb9488c52606d296127612dc\"","etag_repository":"W/\"bffbf6169b3b272370a06af9c995aadfeaabbf4ec793e4eb3c7c88a2be12f5fa\"","full_name":"sanghviharshit/ha-monarchmoney","last_commit":"00ebe0d","last_updated":"2024-02-13T22:17:19Z","last_version":"0.0.2","manifest_name":"Monarch","open_issues":3,"stargazers_count":9,"topics":["finance","monarch","monarchmoney","money"],"last_fetched":1710022803.200302},"485895021":{"manifest":{"country":["US"],"name":"Blueair Filters"},"description":"Home Assistant Integration for Blueair Class Filters","domain":"ha_blueair","etag_releases":"W/\"566144c7b9c52689575174a7b0fda77242ae5705b99ec6d55d80b4141d410372\"","etag_repository":"W/\"b37c08e97a9793c0b8796fc051f84260c0ccd873ddbbbb98a74eeeb7ab9b922c\"","full_name":"dahlb/ha_blueair","last_commit":"57446f0","last_updated":"2024-04-01T21:24:47Z","last_version":"v1.9.1","manifest_name":"Blueair","open_issues":8,"stargazers_count":23,"topics":["blueair","hassio-integration","python3"],"last_fetched":1712009675.965432},"448604854":{"manifest":{"country":["GB"],"name":"Cardiff Waste"},"description":"A Home Assistant integration to provide sensors for waste collections in Cardiff, UK","domain":"cardiffwaste","etag_releases":"W/\"5357ba42846d7b2810f84f81109e53769a39eeda8db7f2ce6c0ebdd38731a4a0\"","etag_repository":"W/\"f7b83e6f29c2ee31c79626b7675cc656d1defe115f660ec469d63f5d0a5d3832\"","full_name":"TomBrien/cardiffwaste-ha","last_commit":"9123262","last_updated":"2023-10-18T18:35:55Z","last_version":"0.4.1","manifest_name":"Cardiff Waste","open_issues":3,"stargazers_count":9,"topics":["cardiff","waste-collection"],"last_fetched":1707646853.285105},"503856080":{"manifest":{"country":["PT"],"name":"My Edenred"},"description":"myEdenred - Custom Component for Home Assistant","domain":"myedenred","etag_releases":"W/\"100890aff72e85a7a02037ef747e2f453a8be2652a34c4a33a05220ffcf547e9\"","etag_repository":"W/\"c6bd67fa65923294baded90677342ac5557ee3e33b769ff16efd6bb18160da65\"","full_name":"netsoft-ruidias/ha-custom-component-myedenred","last_commit":"34a3e65","last_updated":"2023-05-08T11:18:04Z","last_version":"v1.1.1","manifest_name":"myEdenred Card Integration","open_issues":4,"stargazers_count":7,"topics":["meal-card","myedenred"],"last_fetched":1698869961.798731},"380367845":{"manifest":{"name":"Eufy Security"},"description":"Home Assistant integration to manage Eufy Security devices as cameras, home base stations, doorbells, motion and contact sensors.","domain":"eufy_security","etag_releases":"W/\"4b1b3140da7339ce2636a4afe4938afc9309e36b231b91052f665cf655ed4e57\"","etag_repository":"W/\"4ba6c36663415491bda3016618aced53f1d99e119750b54c08e07cb82b278401\"","full_name":"fuatakgun/eufy_security","last_commit":"25af9ed","last_updated":"2024-03-28T02:07:58Z","last_version":"v8.0.1","manifest_name":"Eufy Security","open_issues":38,"stargazers_count":769,"topics":["camera","eufy","eufycam","eufysecurity","rtsp","security"],"last_fetched":1711916172.748196},"363203831":{"manifest":{"name":"SureHA"},"description":"SureHA \ud83d\udc3e monitor & control your Sure Petcare devices via Home Assistant","domain":"sureha","etag_releases":"W/\"e4939d6ab25d7d1345b56f8e379bbf667a35eb7186c8b919de971c3d69650412\"","etag_repository":"W/\"f42abf4a7aab6b9f7002f34ff4b8289e72d9892e5408ed659d076fd14804c209\"","full_name":"benleb/sureha","last_commit":"77ff2da","last_updated":"2024-02-27T17:54:57Z","last_version":"v0.4.2","manifest_name":"SureHA","open_issues":32,"stargazers_count":20,"topics":["surepet","surepetcare","surepy"],"last_fetched":1712218648.41647},"169460975":{"manifest":{},"description":"It is a fork of \"Yet another take on a home assistant custom alarm\" that will exist until its author is back to our Earth","domain":"bwalarm","etag_releases":"W/\"d154431cd0a54d9bb6250909520a06bad4226fea260598c226fe8a69f8ad39d5\"","etag_repository":"W/\"623a27d9df9e0d690fb58ee184af9ff07d63bd6f1e7e1414913ff89b94d732a3\"","full_name":"akasma74/Hass-Custom-Alarm","last_commit":"8c7b663","last_updated":"2023-06-12T10:41:28Z","last_version":"v.1.12.15","manifest_name":"BWAlarm (ak74 edition)","open_issues":29,"stargazers_count":80,"last_fetched":1711500865.875438},"419449609":{"manifest":{"name":"First Bus"},"description":"Unofficial Home Assistant integration for determining the time to the next First bus","domain":"first_bus","etag_releases":"W/\"91c69ee28f94009c5496bb50f21e1755b7a0b4804b76a503f8c792c681ec8422\"","etag_repository":"W/\"df67f6aa1f085b2c0cdfb2bcbf5b375140cd2ebe9280992c9617e47de5fb908a\"","full_name":"BottlecapDave/HomeAssistant-FirstBus","last_commit":"6d103a4","last_updated":"2024-03-25T02:02:43Z","last_version":"v2.0.0","manifest_name":"First Bus","open_issues":5,"stargazers_count":4,"topics":["bus-arrival","first-bus"],"last_fetched":1711333349.112643},"153870340":{"manifest":{"name":"Harmony Hub Climate Controller"},"description":"\u2744 Use a Harmony Hub to control an IR controlled climate device","domain":"harmony_ac","etag_releases":"W/\"051d79f2de7e4b6b254fb49c19bc7e71c70bee7810444d0b9f4fb4a560215d34\"","etag_repository":"W/\"b3f763095407539fc9946044908a179c6d07bcb280b125e316c88b2fd842784c\"","full_name":"nickneos/HA_harmony_climate_component","last_commit":"f52784f","last_updated":"2024-03-23T19:32:13Z","last_version":"v0.2.1","manifest_name":"Harmony AC","open_issues":2,"stargazers_count":28,"topics":["air-conditioner","climate","harmony","hvac"],"last_fetched":1711225146.96882},"205416078":{"manifest":{"name":"SensorPush"},"description":"SensorPush integration for Home Assistant","domain":"sensorpush","etag_releases":"W/\"f1fb40f8c6c633c4d3476139ecd8a6d7a82a95f38209a168bd43e91e5aee7778\"","etag_repository":"W/\"b06ddfa12dcce380dec7ff21b4e1c18679732747fcc05713d34bf6f19fdd5cc0\"","full_name":"rsnodgrass/hass-sensorpush","last_commit":"e409b4c","last_updated":"2022-11-16T07:33:19Z","last_version":"0.1.4","manifest_name":"SensorPush","open_issues":5,"stargazers_count":32,"topics":["iot"],"last_fetched":1703945889.179459},"317051290":{"manifest":{"country":["IL"],"name":"Kan Program"},"description":"Home assistant custom component to fetch kan program guide","domain":"kan_program","etag_releases":"W/\"7d49fa8a71f517f7a81ee2aebcebdb063b20667c7ca3a9b967c249bbbe969eb1\"","etag_repository":"W/\"82873b76ede8fe5ebb384672ee37e042b2f25df16334092879c217909c329097\"","full_name":"eyalcha/kan_program","last_commit":"10b9cdb","last_updated":"2022-07-14T17:31:08Z","last_version":"1.0.1","manifest_name":"Kan Program","stargazers_count":2,"last_fetched":1684167595.189642},"461802716":{"manifest":{"country":["SE"],"name":"Skolmat Integration"},"description":"Skolmat Home Assistant custom component for the food menu in Swedish schools","domain":"skolmat","etag_releases":"W/\"e81f398f6fd023e26fe09cae3bd3fddfe5d467d7297afe2a8baa93e99161c2ea\"","etag_repository":"W/\"a986ad57c4844cebfd6e4fde085c24d4b49d856ff54404218f74bb42b0191459\"","full_name":"Kaptensanders/skolmat","last_commit":"5e60288","last_updated":"2023-11-21T12:29:17Z","last_version":"v1.5.0","manifest_name":"Skolmat","open_issues":3,"stargazers_count":11,"topics":["food","food-menu","school","skola"],"last_fetched":1707286813.729877},"264415552":{"manifest":{"name":"Hive Custom Component"},"description":"A custom version of the home assistant hive component","domain":"hive","etag_releases":"W/\"019b3757e3fca33b420403bff27eaf5d9285ddeaa9800845687e6337b2af0c7b\"","etag_repository":"W/\"396a86f357b2abcbef868c144d60d9d191b91ce4f0b44cd5f38c5592a7702a71\"","full_name":"Pyhass/Hive-Custom-Component","last_commit":"ab611e2","last_updated":"2024-02-12T18:14:33Z","last_version":"2024.1.0","manifest_name":"Hive","open_issues":24,"stargazers_count":33,"topics":["hive"],"last_fetched":1710685031.947391},"121934877":{"manifest":{"name":"Xiaomi Mi and Aqara Air Conditioning Companion Integration"},"description":"Xiaomi Mi and Aqara Air Conditioning Companion integration for Home Assistant","domain":"xiaomi_miio_airconditioningcompanion","etag_releases":"W/\"ac58aae9a483e0bee0fa4f9ca557eb4b3e8829992e0cd9d34841b7a134a0a0f2\"","etag_repository":"W/\"384ca039e86f117807a6db096ffff47c218b38b17da5c50953c8f79c508e580f\"","full_name":"syssi/xiaomi_airconditioningcompanion","last_commit":"a3533fa","last_updated":"2023-12-24T09:29:42Z","last_version":"2023.12.0.0","manifest_name":"Xiaomi Mi and Aqara Air Conditioning Companion","open_issues":52,"stargazers_count":390,"topics":["acpartner","airconditioning","aqara","infrared","xiaomi"],"last_fetched":1710555932.79552},"100234318":{"manifest":{"name":"Xiaomi Philips Lights Integration"},"description":"Xiaomi Philips Lights integration for Home Assistant","domain":"xiaomi_miio_philipslight","etag_releases":"W/\"06418ccc2ea3f37a3b29b2760c7cde2da3e79166fb8c0daa90ad7be0b719074f\"","etag_repository":"W/\"f04511d4e93c7c06c92311ba5d4831b3f08072222fb29380f702a2eccf4e3ed9\"","full_name":"syssi/philipslight","last_commit":"717e055","last_updated":"2024-02-09T20:00:25Z","last_version":"2024.2.0.0","manifest_name":"Xiaomi Philips Lights Integration","open_issues":20,"stargazers_count":69,"topics":["light","miio","miio-protocol","xiaomi","xiaomi-philips-lights"],"last_fetched":1708438792.89294},"299123388":{"manifest":{"name":"Magic Areas"},"description":"Areas with batteries included for Home Assistant","domain":"magic_areas","etag_releases":"W/\"c5ac1750c0d2207c15ef2fd86becc44b0c9e66ebb62cfd7c7f51781150d5c461\"","etag_repository":"W/\"b1bb1c25b9c45b47dd2266bc36e5888f4e3ef68c178e887e8f706b737c3b76e1\"","full_name":"jseidl/hass-magic_areas","last_commit":"f535dcd","last_updated":"2024-03-01T08:42:32Z","last_version":"3.1.1","manifest_name":"Magic Areas","open_issues":1,"stargazers_count":169,"topics":["automation"],"last_fetched":1711700392.279154},"624779425":{"manifest":{"name":"ZCS Azzurro"},"description":"A modern integration for ZCS Azzurro devices in Home Assistant","downloads":657,"domain":"zcsazzurro","etag_releases":"W/\"e015c419e55ae907c2bd2599261536e3a2a9be52f0d713289b645e499bfe0626\"","etag_repository":"W/\"774041ea22fcf65305b62f389c4e4ff94c637c1f91ccc2f4d8ccef89a9ffb7a6\"","full_name":"aturri/ha-zcsazzurro","last_commit":"4ce5546","last_updated":"2024-03-25T01:31:20Z","last_version":"v0.1.0","manifest_name":"ZCS Azzurro","open_issues":9,"stargazers_count":16,"topics":["zcs","zcsazzurro"],"last_fetched":1712045800.42023},"591077142":{"manifest":{"country":["BE"],"name":"Bibliotheek.be"},"description":"Bibliotheek.be Home Assistant custom component HACS with overview of lended Belgian library items and services to (automatically) extend loans. ","domain":"bibliotheek_be","etag_releases":"W/\"0fa0adff6fd4a4505eb0404e56931dde55700f4fc75b009abc819c3fc173717d\"","etag_repository":"W/\"8f25ac3c52a701ff3ea5938a1846e6bfcdd6ee0fcc852fd630d3d216e9157a26\"","full_name":"myTselection/bibliotheek_be","last_commit":"5ef06ca","last_updated":"2024-03-24T16:37:55Z","last_version":"1.7.0","manifest_name":"Bibliotheek.be","open_issues":1,"stargazers_count":15,"last_fetched":1711405100.739593},"581307720":{"manifest":{"name":"QuestDB State Storage (QSS)"},"description":"QuestDB State Storage (QSS) Custom Component for Home Assistant to store entity states inside a QuestDB.","downloads":42,"domain":"qss","etag_releases":"W/\"260c5b6e4d880ef6e2a10ebe0a3da09f6084bea43f02561be4a3e898ffe9464b\"","etag_repository":"W/\"d31fe43ea82e6e48a454e7f4b77011e2a4665864438f0803c0fb2a78d8fa8360\"","full_name":"CM000n/qss","last_commit":"1c49d8e","last_updated":"2024-03-26T21:38:03Z","last_version":"v0.0.10","manifest_name":"QuestDB State Storage (QSS)","stargazers_count":7,"topics":["analytics","database","grafana","qss","questdb","state-storage","storage","timeseries"],"last_fetched":1711556310.301853},"305147191":{"manifest":{"country":["CZ"],"name":"CEZ Distribuce CZ"},"description":"CEZ Distribuce - Home Assistant Sensor","domain":"cezdistribuce","etag_releases":"W/\"c6653ebc9f6e7a67b36de0dddd0a33bc6e830637495fa986cf5d36d88f75513b\"","etag_repository":"W/\"2b023fbab935af92a19718624768e9780ea343fdad54a6e1fcbc8496191b681b\"","full_name":"zigul/HomeAssistant-CEZdistribuce","last_commit":"a6251d8","last_updated":"2024-03-25T10:31:07Z","last_version":"0.4.9","manifest_name":"CEZ Distribuce","open_issues":3,"stargazers_count":26,"topics":["cez"],"last_fetched":1711369858.759706},"420701401":{"manifest":{"country":["DE"],"name":"Water heater CLAGE DSX Touch"},"description":"Home Assistant integration for the water heater CLAGE DSX Touch connected through a Clage Homeserver","domain":"clage_homeserver","etag_repository":"W/\"8f7243bf458c1d61ed613e20678f77da14af529862df886b0477f2eafcbd8eba\"","full_name":"klacol/homeassistant-clage_homeserver","last_commit":"acd1b4a","last_updated":"2023-06-19T04:43:36Z","manifest_name":"CLAGE Homeserver","stargazers_count":1,"topics":["clage","waterheater"],"last_fetched":1687155670.314869},"563077911":{"manifest":{"country":["CN"],"name":"China Southern Power Grid Statistics"},"description":"Home Assistant intergration to get statictics from China Southern Power Grid (CSG) \u5357\u65b9\u7535\u7f51HA\u96c6\u6210","domain":"china_southern_power_grid_stat","etag_releases":"W/\"ea53b2f23fdfc4a32605b2c5d348319be57414122f35f7efdab6655648eac39e\"","etag_repository":"W/\"d6242ff456332b66d6fb90afcf90ed042610fb8afce806a43b20441f75bacb9c\"","full_name":"CubicPill/china_southern_power_grid_stat","last_commit":"6b5ce6c","last_updated":"2023-05-27T14:15:41Z","last_version":"v1.1.2","manifest_name":"China Southern Power Grid Statistics","open_issues":7,"stargazers_count":122,"last_fetched":1711678809.92782},"157618389":{"manifest":{"name":"fontawesome"},"description":"\ud83d\udd39 Use icons from fontawesome in home-assistant","domain":"fontawesome","etag_releases":"W/\"901b67ad79e93112ca564f1383c556e1ba99820218eb91e92f930528f11e6738\"","etag_repository":"W/\"bf7bca4ebf610662faeaf9b30a49725e41d9d0c25e33389c06c085d617e324cb\"","full_name":"thomasloven/hass-fontawesome","last_commit":"d20d278","last_updated":"2023-12-24T16:46:34Z","last_version":"2.2.1","manifest_name":"Fontawesome icons","open_issues":20,"stargazers_count":263,"last_fetched":1711808329.879154},"584473299":{"manifest":{"name":"Jablotron Cloud"},"description":"HACS custom component for jablotron cloud integration","domain":"jablotron_cloud","etag_releases":"W/\"9a3e75c5211542f55139a0d325df36fbee2dd222cadc9aa2f9daa752dba14229\"","etag_repository":"W/\"f6c946d0856557b47cea5970bdeda8dc788c31366034e2d136441c1b2dbdad99\"","full_name":"Pigotka/ha-cc-jablotron-cloud","last_commit":"4203f14","last_updated":"2024-02-16T12:27:17Z","last_version":"0.5.5","manifest_name":"Jablotron Cloud","open_issues":3,"stargazers_count":10,"last_fetched":1710354093.389435},"297106424":{"manifest":{"name":"Ebeco thermostats"},"description":"Integration for Ebeco thermostats","domain":"ebeco","etag_releases":"W/\"900fa49c122d26881b7edcabb42061a1659fe6fe87cc9f299b633d191af8c012\"","etag_repository":"W/\"9f4427e18f8b44d28aaa374b6c3b12094694a755f4729621d0b90d04f420010a\"","full_name":"joggs/home_assistant_ebeco","last_commit":"e2388fd","last_updated":"2024-01-20T11:27:47Z","last_version":"0.6.6","manifest_name":"Ebeco","open_issues":8,"stargazers_count":25,"topics":["ebeco"],"last_fetched":1709728028.850094},"233092112":{"manifest":{"country":["NO"],"name":"songpal_m"},"description":"songpal - volume down workaround","domain":"songpal_m","etag_repository":"W/\"1524a56d4e9541dc42ded44a4bcd16f5645e0b94b58f79c0fc3bb2c2e4b12cf5\"","full_name":"kodi1/songpal_m","last_commit":"4805076","last_updated":"2021-03-28T10:15:20Z","manifest_name":"songpal mod - volume decrease","stargazers_count":1,"topics":["songpal"],"last_fetched":1678387413.69856},"372058588":{"manifest":{"country":["HU"],"name":"MET Alerts Hungary"},"description":"Meteo alerts for Hungary","domain":"met_alerts_hu","etag_releases":"W/\"7bacab430ffeaa6b4ac0904fd40c2ea36479d63ebd9c76d26659efda6eb4f0c0\"","etag_repository":"W/\"c0db0a0357db116f9aa3d897633b1719accf4e2720e6ff80a8d5ca9dd1e3691a\"","full_name":"amaximus/met_alerts_hu","last_commit":"b6c26a6","last_updated":"2023-12-11T13:35:08Z","last_version":"2.6.2","manifest_name":"Meteo Alert Hungary","open_issues":1,"stargazers_count":12,"topics":["homeassistant-custom-component","hungary"],"last_fetched":1702303990.832525},"220482107":{"manifest":{"name":"HP Printers Integration"},"description":"HP Printer Integration","domain":"hpprinter","etag_releases":"W/\"bf7b7eb5b99376c75d3714a87a276d291a6ffed048f5e7bbd628c41e42d738c7\"","etag_repository":"W/\"2dce4a9cccccd799439068f6137731b92d48026df736b9dd8891a2a0f8e8705c\"","full_name":"elad-bar/ha-hpprinter","last_commit":"1ef086f","last_updated":"2024-03-22T16:17:43Z","last_version":"v1.0.12","manifest_name":"HP Printer","open_issues":22,"stargazers_count":81,"topics":["hp","hp-printer"],"last_fetched":1711793737.741337},"666758552":{"manifest":{"country":["fr"],"name":"Vigieau"},"description":"A custom integration for home-assistant on the Vigieau dataset","domain":"vigieau","etag_releases":"W/\"629b267dcde499c5c4f5c7306bcd112b06b444e4efc1f753dbaa9ad1175d32d1\"","etag_repository":"W/\"d009fbc1c1ad99a05554cb9b3983c68f598b242ca00d266a509c9f7c97de92bc\"","full_name":"kamaradclimber/vigieau","last_commit":"84d9c27","last_updated":"2023-10-26T18:46:33Z","last_version":"0.4.10","manifest_name":"Vigieau","open_issues":2,"stargazers_count":15,"topics":["open-data","water"],"last_fetched":1708273162.918667},"566085483":{"manifest":{"name":"jokes"},"description":"Home Assistant Sensor providing a random joke every minute.","domain":"jokes","etag_repository":"W/\"b82aa8329d062cee8ad1ef6d2f4a9f136a2ab6417ddc6fa9c3c210e103fb1b0b\"","full_name":"LaggAt/ha-jokes","last_commit":"b894d1a","last_updated":"2024-03-17T13:50:05Z","manifest_name":"Jokes","open_issues":5,"stargazers_count":17,"topics":["devcontainer","fun","jokes"],"last_fetched":1710865262.036996},"689755820":{"manifest":{"name":"Akuvox SmartPlus"},"description":"Home Assistant integration to add Akuvox SmartPlus door cameras, door open relay buttons and temporary keys","downloads":189,"domain":"akuvox","etag_releases":"W/\"6c9fdbdfbfbef12d0f99fd30e804c6c054bc1d187a11c131212a06f01e1966da\"","etag_repository":"W/\"3c4522ac0a061c8a5069ce232a908137a93fd4474b63d563fb4ab5dd25f9dc20\"","full_name":"nimroddolev/akuvox","last_commit":"7c33d71","last_updated":"2024-04-01T01:34:56Z","last_version":"v0.1.1","manifest_name":"Akuvox SmartPlus","open_issues":3,"stargazers_count":12,"topics":["akuvox","smartdoor","smartplus"],"last_fetched":1711995706.831574},"131915802":{"manifest":{"name":"Places"},"description":"Component to integrate with OpenStreetMap Reverse Geocode (places)","downloads":7,"domain":"places","etag_releases":"W/\"27ef05ddf288a8d0397058b011008fedaad7dff0eab55597e625fc53bc08bd0f\"","etag_repository":"W/\"963f5ee99f6a41965f0f488e18c5dcfd49c1feea648a6c7ac461cb58b5737a37\"","full_name":"custom-components/places","last_commit":"4952b24","last_updated":"2024-03-19T00:09:39Z","last_version":"v2.6.1","manifest_name":"Places","open_issues":2,"stargazers_count":104,"topics":["device-tracker","geolocation","openstreetmap"],"last_fetched":1710814818.164963},"316807165":{"manifest":{"name":"Miele integration"},"description":"Miele integration for Home assistant","domain":"miele","etag_releases":"W/\"5ce4324122df445653e6f9f77496b1c8c49064c1c60f52d1d8d5d7d90c44438a\"","etag_repository":"W/\"bf6b01299f6108d114c5cfba18d7f8ad7d63766edb89e11832e25c246bb693fa\"","full_name":"HomeAssistant-Mods/home-assistant-miele","last_commit":"dc2c21c","last_updated":"2024-02-16T09:37:38Z","last_version":"v.0.9.8","manifest_name":"Miele@home","open_issues":34,"stargazers_count":130,"topics":["miele"],"last_fetched":1712105880.66303},"602776380":{"manifest":{"country":["ES"],"name":"Balance Neto"},"description":"Componente para Home Assistant que calcula el Balance Neto Horario para instalaciones fotovolt\u00e1icas.","domain":"balance_neto","etag_releases":"W/\"1418adbf4373569c83ae04d68cf65d6ae7d7519c5046d7546e5d46c279616f2d\"","etag_repository":"W/\"cb5fa30d86828814ad4a953f8b94a930346ffc2ab3b7497da59752683301a132\"","full_name":"MiguelAngelLV/balance_neto","last_commit":"8590949","last_updated":"2023-12-23T06:41:42Z","last_version":"V1.4","manifest_name":"Balance Neto","open_issues":1,"stargazers_count":32,"topics":["fotovoltaica"],"last_fetched":1712175610.532049},"686447561":{"manifest":{"country":["IL"],"name":"matterbridge whatsapp custom notification / notify"},"description":"matterbridge-custom-notifier allows us to send whatsapp notifications to group using api calls but without the need to use the official whatsapp cloud api","domain":"matterbridge","etag_releases":"W/\"8f49a3fe157d70422b06b40cf886e48e04cb9afc8d7da8e8c497f5c264a35c21\"","etag_repository":"W/\"0b302e0b43ee100e0550145d8febec9420a1f8c23a901e6c567ff95227bf07d0\"","full_name":"t0mer/matterbridge-custom-notifier","last_commit":"85d1114","last_updated":"2024-04-01T18:55:35Z","last_version":"0.2.0","manifest_name":"Matterbridge notifier basde on matterbridge and can send notifications to many channels","open_issues":2,"stargazers_count":13,"topics":["api","go","hacs-custom","matterbridge","whatsapp"],"last_fetched":1712002928.198764},"228678807":{"manifest":{"country":["NL"],"name":"Toon Smart Meter"},"description":"This component reads and displays sensor values from the meteradapter connected to a rooted Toon thermostat.","domain":"toon_smartmeter","etag_releases":"W/\"c1125c43354312461a77d90e75e0d76f6bde26e82d4efa0c2efbecc20e5404e5\"","etag_repository":"W/\"32772ea09ff38795073b499cef18588bb889e375fe8d8d68aa0707b32d99a522\"","full_name":"cyberjunky/home-assistant-toon_smartmeter","last_commit":"eabe255","last_updated":"2024-01-05T12:14:08Z","last_version":"1.0.38","manifest_name":"Toon Smart Meter","open_issues":4,"stargazers_count":21,"last_fetched":1710756954.265596},"586345918":{"manifest":{"name":"Binance Integration for Home Assistant"},"description":"A Home Assistant Integration for the cryptocurrency trading platform Binance.","domain":"binance","etag_releases":"W/\"0738a21a3bce3734552193a2f1c6247fcfd15c73ddd614b57c91fd1d213ebc4d\"","etag_repository":"W/\"a7c9355b458dbcd0c129d104f71218891da85abc09b55bee374c07df504e8cd9\"","full_name":"Kartax/home-assistant-binance","last_commit":"bb6dc2b","last_updated":"2024-03-13T14:05:33Z","last_version":"1.1.4","manifest_name":"Binance Integration for Home Assistant","stargazers_count":6,"topics":["binance","bitcoin","crypto","cryptocurrency","dogecoin","ethereum","home-assistant-integration","ripp"],"last_fetched":1710348449.497162},"183222061":{"manifest":{"name":"Local Luftdaten Sensor"},"description":"Custom component for Home Assistant that integrates your (own) local Luftdaten sensor (air quality/particle sensor) without using the cloud.","domain":"local_luftdaten","etag_releases":"W/\"3926f8c5a3c37f02edd2deed0403581194ca1787ac1623813efa7e83becf876c\"","etag_repository":"W/\"cfa47ad2915c3e812cf2cba2d455e085b9915ca8b1102661170c0e1e5c66dfaa\"","full_name":"lichtteil/local_luftdaten","last_commit":"b23b4e1","last_updated":"2024-03-14T23:03:45Z","last_version":"2.3.1","manifest_name":"Local Luftdaten sensor","open_issues":4,"stargazers_count":44,"topics":["air-quality"],"last_fetched":1710464391.495778},"506738088":{"manifest":{"country":["PT"],"name":"Sodexo Card"},"description":"Sodexo - Custom Component for Home Assistant","domain":"sodexo","etag_releases":"W/\"b9b449cba5c3068894981b1f114fa2514359552fec06c91399ba4bc7f634d087\"","etag_repository":"W/\"812d17258473bb234ce96eb5d8761df0a56ca23b9991c76cef447fa1c2f26ad6\"","full_name":"netsoft-ruidias/ha-custom-component-sodexo","last_commit":"672eee2","last_updated":"2023-05-08T11:26:16Z","last_version":"v1.2.0","manifest_name":"Sodexo Meal Card Integration","open_issues":4,"stargazers_count":4,"topics":["meal-card","sodexo"],"last_fetched":1710951759.515722},"680907810":{"manifest":{"country":["CZ"],"name":"Prague waste separation points"},"description":"HA integration - waste separation points in Prague","domain":"golemio","etag_releases":"W/\"3187518b2da9677213ded9898445f20647b6aef94b105c2a55f5d050527983ff\"","etag_repository":"W/\"24b6bd250f2e2abea0727a9e77021de3bde1d4f9fd60533c643c646b6aebd70a\"","full_name":"Cmajda/ha_golemio","last_commit":"121fff8","last_updated":"2024-02-05T15:14:35Z","last_version":"1.1.2","manifest_name":"Golemio","stargazers_count":4,"last_fetched":1710303343.186745},"254347436":{"manifest":{"name":"Waste Collection Schedule"},"description":"Home Assistant integration framework for (garbage collection) schedules","domain":"waste_collection_schedule","etag_releases":"W/\"ff6900e5fb1e8ecf744fdb4bd38ba13eb7cf61952724e93736f4051a9647d3fb\"","etag_repository":"W/\"0f441d38f3bb8042e68eb066ef862f177f5a837a661cffe6971fd0c797f15180\"","full_name":"mampfes/hacs_waste_collection_schedule","last_commit":"ada82e6","last_updated":"2024-04-03T15:28:17Z","last_version":"1.46.0","manifest_name":"waste_collection_schedule","open_issues":115,"stargazers_count":765,"topics":["abfall","abfallnavi","abfallplus","garbage","garbage-collection","jumomind","muell","muellabfuhr","muellsammlung","mymuell","regioit","waste","waste-collection"],"last_fetched":1712211682.259986},"183064800":{"manifest":{"name":"Email Sensor"},"description":"Email Sensor for collecting tracking numbers from over 40 providers.","domain":"email","etag_releases":"W/\"392232b13c412f199626acaf081969cfde7b5d8878f6b8c74182bf4a6a62d4d5\"","etag_repository":"W/\"a369e266318f8026a609b1624ca7a7964e85fd50ffaf0e565b86db2452a1270a\"","full_name":"ljmerza/ha-email-sensor","last_commit":"57e52a6","last_updated":"2023-07-27T17:36:02Z","last_version":"3.13.1","manifest_name":"Email","open_issues":17,"stargazers_count":82,"last_fetched":1711254065.262129},"446609758":{"manifest":{"name":"Nicehash Excavator API"},"description":"Home Assistant integration for Nicehash Excavator miner API","domain":"nicehash_excavator","etag_releases":"W/\"c377013c6325efdadbb9e5d67706e2d3cf098f326fd79f9d04080932efd6fe8d\"","etag_repository":"W/\"c2e0d575a6720f9a6a46796d37421b27a3e9c7bda83a26a7455a27378f9c9ebf\"","full_name":"MesserschmittX/ha-nicehash-excavator-monitor","last_commit":"c8be596","last_updated":"2022-05-15T07:11:45Z","last_version":"v0.1.2","manifest_name":"Nicehash Excavator","stargazers_count":4,"topics":["excavator","mining","nicehash"],"last_fetched":1678387463.801681},"267076188":{"manifest":{"name":"Gigaset Elements"},"description":"Gigaset Smart Home integration for Home Assistant","domain":"gigasetelements","etag_releases":"W/\"57bc88d3a7a5b4fe85d8c0b3f2b3de8dd92356d931decd9176db84b3ee076652\"","etag_repository":"W/\"7f56c2e9d799c685d3e60ef143fe1350a66e148a1c4a674a5bf135f73e037775\"","full_name":"dynasticorpheus/gigasetelements-ha","last_commit":"f74d0fe","last_updated":"2024-03-26T12:29:04Z","last_version":"2023.12.2","manifest_name":"Gigaset Elements","open_issues":1,"stargazers_count":22,"topics":["community","gigaset","gigasetelements","python3"],"last_fetched":1712067259.096205},"341500126":{"manifest":{"country":["IT","GB","US","JP","ES","FR","DE"],"name":"Meross LAN"},"description":"Home Assistant integration for Meross devices","domain":"meross_lan","etag_releases":"W/\"e9b059708b882b4f3a5de5d6b3321390fb7bb14169a9648d4d88762b7e21503c\"","etag_repository":"W/\"1789136126d2cc8a52987edd312ef818b8a15ce1924b8f695dd66c470c623af6\"","full_name":"krahabb/meross_lan","last_commit":"5c16dea","last_updated":"2024-04-03T09:33:41Z","last_version":"v5.0.3","manifest_name":"Meross LAN","open_issues":22,"stargazers_count":355,"topics":["meross","meross-devices","meross-homeassistant","meross-lan"],"last_fetched":1712182585.435606},"485971293":{"manifest":{"name":"Super Soco Custom"},"description":"Custom component for integrating your Super Soco or Vmoto Soco motorcycle into Home Assistant. It provides meaningful data like power status, battery percentage, location and a lot more.","domain":"super_soco_custom","etag_repository":"W/\"c99aad9f675f881a0dd543f69191d80dddf968fa0f8955056002843ef676b331\"","full_name":"drakhart/ha-super-soco-custom","last_commit":"0e2b4fa","last_updated":"2023-08-30T19:35:18Z","manifest_name":"Super Soco Custom","open_issues":2,"stargazers_count":14,"topics":["super-soco"],"last_fetched":1711995475.078806},"454859084":{"manifest":{"name":"Home Connect Alt"},"description":"Alternative (and improved) Home Connect integration for Home Assistant","domain":"home_connect_alt","etag_releases":"W/\"525a2134f2f8b2c60d51e5e49b18a8b023d2699c8f7bd634f5d816160120ee4c\"","etag_repository":"W/\"ef4f4054a2ad2e7baad16e3694badd85510da4582318245e337e8e7108d1e946\"","full_name":"ekutner/home-connect-hass","last_commit":"928ba5e","last_updated":"2024-03-23T16:05:49Z","last_version":"1.1.6","manifest_name":"Home Connect Alt","open_issues":6,"stargazers_count":422,"topics":["home-assistant-component","home-assistant-integration","home-connect","homeconnect"],"last_fetched":1712175431.882056},"356725611":{"manifest":{"name":"Wavin Sentio"},"description":"Home Assistant component for monitoring and administration of Wavin Sentio underfloor heating system","domain":"wavinsentio","etag_releases":"W/\"cf59142fe015a946fb456f92a15d770cd15d59ff451b485f7a41b85d2112c356\"","etag_repository":"W/\"ecfcc8840d8b078bba7e0fdcf34354e2d59c8b70f9a7ae739d5dc8e60e58b0aa\"","full_name":"djerik/wavinsentio-ha","last_commit":"9d3df05","last_updated":"2024-03-05T22:54:23Z","last_version":"0.4.4","manifest_name":"Wavin Sentio","open_issues":4,"stargazers_count":15,"topics":["sentio","wavin"],"last_fetched":1711232055.989308},"634513270":{"manifest":{"name":"Helium Integration"},"description":"Helium Integration for Home Assistant","domain":"helium_solana","etag_releases":"W/\"6cda3d6b7edcc69e27a25658bda303b0a0b97bc66d5124b88ce723aa9cf79bad\"","etag_repository":"W/\"26ea0780465ae5b93c280f4aec9834e3574a029a8becbcd53abc4d132d85236c\"","full_name":"enes-oerdek/Home-Assistant-Helium-Integration","last_commit":"9ea491f","last_updated":"2024-04-02T00:21:44Z","last_version":"2.5.1","manifest_name":"Helium Integration","open_issues":5,"stargazers_count":18,"topics":["helium","helium-mining","helium-network","iot","solana"],"last_fetched":1712019617.159977},"625647772":{"manifest":{"country":["BE"],"name":"Mobile Vikings"},"description":"Home Assistant component for Mobile Vikings BE services","domain":"mobile_vikings","etag_releases":"W/\"25e5ee3be07da3e67c210a646592fcfe7f590504e17631ded80f088b9483aaa9\"","etag_repository":"W/\"e3b728028aad9c5610ad47fe763bb5a8ebbcbb92292df65e6d6ba445af5e8608\"","full_name":"geertmeersman/mobile_vikings","last_commit":"bf25020","last_updated":"2024-04-01T19:18:00Z","last_version":"v0.6.0","manifest_name":"Mobile Vikings","open_issues":2,"stargazers_count":8,"topics":["hacs-custom"],"last_fetched":1712009751.726012},"403243434":{"manifest":{"name":"Vaillant vSMART"},"description":"Home Assistant custom component for Vaillant vSMART.","domain":"vaillant_vsmart","etag_releases":"W/\"f4863852624c7c6683613cec34fe27203d21dc92a9523ecc825a8294b4c24e60\"","etag_repository":"W/\"0f85eb26acaf9ce894a0983fcd8e2f04d5fb6ee3ecc0aa43cffad7e56783e623\"","full_name":"MislavMandaric/home-assistant-vaillant-vsmart","last_commit":"ba2876f","last_updated":"2024-03-11T04:44:01Z","last_version":"v0.9.0","manifest_name":"Vaillant vSMART","open_issues":33,"stargazers_count":56,"topics":["home-assistant-component","vaillant"],"last_fetched":1710138118.6017},"303827752":{"manifest":{"name":"TryFi Dog Monitor"},"description":"Home Assistant integration for TryFi Dog Collar GPS monitoring.","domain":"tryfi","etag_releases":"W/\"04820445e03ec758ae8889c4294197e6fd6be72ae307e6d32091edbfaaa65465\"","etag_repository":"W/\"3e9265fb75c9bdd9ca0486d414675cf19387249ab1b19bd272ff83844d17d00f\"","full_name":"sbabcock23/hass-tryfi","last_commit":"9e642da","last_updated":"2023-12-27T10:25:41Z","last_version":"0.0.23","manifest_name":"TryFi","open_issues":17,"stargazers_count":47,"topics":["dog","dog-collar","gps","iot","tryfi"],"last_fetched":1708359860.822323},"504081359":{"manifest":{"name":"Sonic"},"description":"Sonic water shutoff valve Home Assistant integration by @markvader","domain":"sonic","etag_releases":"W/\"c840b6ad783ab1d1447d4213a68d1ca8b5ec5efc52023debd7edad4573a1eb6e\"","etag_repository":"W/\"5d108daa134760b44a5f0d0c6f1171b3ea1ef385405f1ecb2c66d0d72a86cbec\"","full_name":"markvader/sonic","last_commit":"5ecf30d","last_updated":"2023-10-18T14:12:58Z","last_version":"v0.2.0","manifest_name":"Sonic (Hero Labs)","open_issues":12,"stargazers_count":13,"topics":["hero-labs","herolabs","leaks","sonic","water"],"last_fetched":1708337943.107193},"202987887":{"manifest":{"name":"Node-RED Companion"},"description":"Companion Component for node-red-contrib-home-assistant-websocket to help integrate Node-RED with Home Assistant Core","downloads":335,"domain":"nodered","etag_releases":"W/\"3a53c8ac12a32ca113d875a0026133aaa1e0d605f4befef5ddc6e01a78f12064\"","etag_repository":"W/\"64046e323c0a85a8527f4e113bc1969ac2ba9f727ef7584d85d90871b46346ee\"","full_name":"zachowj/hass-node-red","last_commit":"517275c","last_updated":"2024-04-04T03:51:01Z","last_version":"v3.1.4","manifest_name":"Node-RED Companion","open_issues":5,"stargazers_count":415,"topics":["node-red"],"last_fetched":1712211853.104778},"315447202":{"manifest":{"name":"ytube_music_player"},"description":"YouTube music player for homeassistant","domain":"ytube_music_player","etag_releases":"W/\"2aa1a43906a2d55b61ed5857370b13b09bcb70953e850e02cc47ec1a106e2bfe\"","etag_repository":"W/\"ac9b2cfa085620c6e9628a58f18ddc1721ef72bd7707dd3a49b3a9829959700a\"","full_name":"KoljaWindeler/ytube_music_player","last_commit":"e7d39fa","last_updated":"2024-04-04T08:01:29Z","last_version":"20240404.01","manifest_name":"YouTube Music Player","open_issues":11,"stargazers_count":302,"topics":["youtube"],"last_fetched":1712225867.048943},"441369133":{"manifest":{"name":"SmartRent"},"description":"Home Assistant Custom Component for SmartRent Locks \ud83d\udd10, Thermostats \ud83c\udf21, Sensors \ud83d\udca7 and Switches\ud83d\udca1","downloads":265,"domain":"smartrent","etag_releases":"W/\"c38afbcbc8f75ba43cb68aa156975c5b96390dd609deec3acae04873d6e1af70\"","etag_repository":"W/\"8b2603456b0bd2260787d69ace72465c4e09fa77c824b92131a6fb115229cc64\"","full_name":"ZacheryThomas/homeassistant-smartrent","last_commit":"93aee31","last_updated":"2024-01-19T18:06:32Z","last_version":"v0.4.4","manifest_name":"SmartRent","open_issues":2,"stargazers_count":64,"topics":["smartrent"],"last_fetched":1712053409.496304},"655762463":{"manifest":{"name":"IPMI Connector"},"description":"IPMI connector for Home Assistant","domain":"ipmi","etag_releases":"W/\"f36978dc8ac770786ef051607daefe44fe194fb54ad3481b91bf0969287a1f8d\"","etag_repository":"W/\"60c1051ee3688e95559e753e78358625eb6a81dd1fc04aef28eb5462c186b45f\"","full_name":"ateodorescu/home-assistant-ipmi","last_commit":"c8576bc","last_updated":"2024-04-04T08:32:42Z","last_version":"v1.6.0","manifest_name":"IPMI connector","open_issues":6,"stargazers_count":27,"topics":["home-assistant-integration","ipmi","ipmi-sensor"],"last_fetched":1712225624.367785},"192604318":{"manifest":{"name":"iPhone Device Tracker"},"description":"A custom component for Home Assistant to detect iPhones connected to local LAN, even if the phone is in deep sleep.","downloads":4517,"domain":"iphonedetect","etag_releases":"W/\"d26e998707004a0a1981377fcbcfc8b1d89a5b206d47713295a413f19898aa7e\"","etag_repository":"W/\"43264c69c1cece2f4181688a4f4a28a71896d1d0d0e40571db2154a1a69dd2b8\"","full_name":"mudape/iphonedetect","last_commit":"0803321","last_updated":"2024-03-22T14:43:31Z","last_version":"1.4.1","manifest_name":"iPhone Device Tracker","open_issues":5,"stargazers_count":353,"topics":["iphonedetect"],"last_fetched":1712067455.066807},"264655935":{"manifest":{"name":"Entities Calendar"},"description":"A custom component for Home Assistant to allow regular entities to be used as a calendar","domain":"entities_calendar","etag_releases":"W/\"406bba93deaa6b43cea07e46005714210059073920cfb5e6e5a3d4619ebcc25b\"","etag_repository":"W/\"3b3cfb5aca59b69d7b97000cbcf9117f07bc02fb173d7df129a7a5f4e32912e6\"","full_name":"gadgetchnnel/entities_calendar","last_commit":"83dddaa","last_updated":"2023-10-05T03:35:54Z","last_version":"0.0.10","manifest_name":"Entities Calendar","open_issues":2,"stargazers_count":22,"topics":["calendar","entities-calendar"],"last_fetched":1710159953.402504},"328671547":{"manifest":{"name":"wattio"},"description":"Wattio Smart Home custom integration for Home Assistant","domain":"wattio","etag_releases":"W/\"0cc8fb4571f680c611f778dd76d80e71c75799bebf3f2d9d3e5f9d8c700acc3b\"","etag_repository":"W/\"01e80ea6bbf0be198ffd8759618ccc738706766c4a33549d5a5b5b4bacb68637\"","full_name":"dmoranf/home-assistant-wattio","last_commit":"bc63885","last_updated":"2022-07-21T18:31:02Z","last_version":"0.2.13","manifest_name":"Wattio Smart Home integration","stargazers_count":7,"topics":["home-assistant-component","wattio"],"last_fetched":1683368177.464978},"169641362":{"manifest":{"name":"BlueIris NVR"},"description":"Integration with Blue Iris Video Security Software","domain":"blueiris","etag_releases":"W/\"36f62c6426f9c89127641cbf0b578b7229815a600d4a9ef9bd1440882e8b2ed3\"","etag_repository":"W/\"ce14e4d73a865e16de67ee06d534f30a76b8d74deadf25263f2ddbce034e3ac4\"","full_name":"elad-bar/ha-blueiris","last_commit":"0506a25","last_updated":"2024-02-25T17:26:53Z","last_version":"v1.0.16","manifest_name":"Blue Iris NVR","open_issues":38,"stargazers_count":168,"last_fetched":1711772216.42861},"195308808":{"manifest":{},"description":"A Fronius Sensor for Home Assistant","domain":"fronius_inverter","etag_releases":"W/\"e43be72c8ee07c5727f8de961900be771d55ac5653e4d554ae3c8b7ed47ae57e\"","etag_repository":"W/\"4ab2ef83dea1a450f53369dd78211ee92e63d334f65423e60cbb925ad45c7004\"","full_name":"safepay/sensor.fronius","last_commit":"1afc703","last_updated":"2023-03-05T11:39:25Z","last_version":"v0.9.7","manifest_name":"Fronius","open_issues":20,"stargazers_count":79,"last_fetched":1711888097.514066},"248462859":{"manifest":{"name":"Alarm.com"},"description":"Custom component to allow Home Assistant to interface with Alarm.com","domain":"alarmdotcom","etag_releases":"W/\"ee9fe47a5997f89e86b2f55ff7985194a5f770ac7de2d431758d2a7463a99253\"","etag_repository":"W/\"9bd22f58496aab00dc33b85125a9cf84b3824a7619738f9c49a035108f86df56\"","full_name":"pyalarmdotcom/alarmdotcom","last_commit":"b157b4f","last_updated":"2024-04-04T07:12:45Z","last_version":"v3.0.13","manifest_name":"Alarm.com","open_issues":19,"stargazers_count":107,"topics":["alarm"],"last_fetched":1712219008.573612},"581264508":{"manifest":{"name":"\u00d6kofen Pellematic Compact"},"description":"A \u00d6kofen Pellematic Compact Integration based on JSON/TCP-Inteface for Home Assistant.","domain":"oekofen_pellematic_compact","etag_releases":"W/\"c81d7902988b41336e3cc4db0b73c9089090218280724c079a2618762e2d2c9a\"","etag_repository":"W/\"04145f4d019a94bdef95d5fb5aa46fa9096da864874a946c5a1e1ceb36e70a71\"","full_name":"dominikamann/oekofen-pellematic-compact","last_commit":"094fdee","last_updated":"2024-03-11T21:02:02Z","last_version":"v3.1.3","manifest_name":"\u00d6kofen Pellematic Compact","open_issues":1,"stargazers_count":26,"topics":["oekofen","oekofen-pellematic-compact"],"last_fetched":1710764659.329603},"523485043":{"manifest":{"name":"HIQ-Home"},"description":"HIQ-Home Integration for Home Assistant HACS Store","domain":"hiq","etag_releases":"W/\"506a1cd24b87769d9a9cf80d6bf82731ca164f14b1f39a8da52840f5cd8c0244\"","etag_repository":"W/\"6973beda172d2549d54560fdd9223769d433689d58e47147b2c8a660f8d8d820\"","full_name":"killer0071234/ha-hiq","last_commit":"25fe001","last_updated":"2024-04-01T17:38:55Z","last_version":"v0.2.4","manifest_name":"HIQ-Home","open_issues":2,"stargazers_count":3,"topics":["blind","cybro","cybrotech","hiq","hiq-home","homeassistant-custom-component","lightning","robotina","tremak"],"last_fetched":1711995609.27484},"382335433":{"manifest":{"name":"SAJ eSolar"},"description":"SAJ eSolar Portal Sensors","domain":"saj_esolar","etag_releases":"W/\"5cf53fa786356a2fc1f6db1d7a3a75e2c35837a050779cf1ae39baba280983d7\"","etag_repository":"W/\"03c0c0c2023c4bdd97dae3371a9eb77bf8d766e733b711c869dae64fc12b231e\"","full_name":"djansen1987/SAJeSolar","last_commit":"3678dc4","last_updated":"2024-02-19T20:43:45Z","last_version":"v1.5.1","manifest_name":"SAJ eSolar","open_issues":7,"stargazers_count":19,"topics":["esolar","intergration","saj","solar","solar-system"],"last_fetched":1711253897.899848},"512169290":{"manifest":{"country":["ZA"],"name":"CoCT Loadshedding Interface"},"description":"Fetches loadshedding data from City of Cape Town","domain":"coct_loadshedding","etag_releases":"W/\"4c667c4aa5868c5a87c95e63faced8f8555f8bbc8d25a0e2a8d55edaaebec5dd\"","etag_repository":"W/\"809579d009ebf3cc5ffd925b0b32a66c7b83a4f6fbecf5fb8234792b4e3831a2\"","full_name":"tinuva/ha-coct-loadshedding","last_commit":"99a1fd7","last_updated":"2023-07-19T06:51:59Z","last_version":"v1.0.8","manifest_name":"CoCT Loadshedding Interface","open_issues":2,"stargazers_count":20,"topics":["cape","cape-town","capetown","eskom","loadshedding","south-africa"],"last_fetched":1704522217.370568},"426814988":{"manifest":{"name":"Schedule State"},"description":"Home Assistant (HA) sensor that returns a string based on a defined schedule, enabling further automations","domain":"schedule_state","etag_releases":"W/\"4af680e7e54dd403a687b5388581aab5c6778e5ab9999a51ad65008bbc0cf11c\"","etag_repository":"W/\"b43cbee17cd8fb0d60ffbd59f9cfbf44f52832af52b8820e0594b532aac87e6b\"","full_name":"aneeshd/schedule_state","last_commit":"102bd95","last_updated":"2024-04-03T15:23:42Z","last_version":"0.19.4","manifest_name":"Schedule State","open_issues":5,"stargazers_count":38,"topics":["automation","scheduler","timetable"],"last_fetched":1712168177.029712},"236572107":{"manifest":{"country":["RU"],"name":"Yandex.Station"},"description":"\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u042f\u043d\u0434\u0435\u043a\u0441.\u0421\u0442\u0430\u043d\u0446\u0438\u0435\u0439 \u0438 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438 \u0443\u043c\u043d\u043e\u0433\u043e \u0434\u043e\u043c\u0430 \u0441 \u0410\u043b\u0438\u0441\u043e\u0439 \u0438\u0437 Home Assistant","domain":"yandex_station","etag_releases":"W/\"7b07336c3b67ed7f1a0b7c206163424b68a40d2d7aa495badbee9b5b8dcef8f0\"","etag_repository":"W/\"82ba902ee109fe7205af0ccd7d644a13c67acdefee1fb8f2ab0c59a828fd14dd\"","full_name":"AlexxIT/YandexStation","last_commit":"f17ecf2","last_updated":"2024-04-04T08:05:24Z","last_version":"v3.13.3","manifest_name":"Yandex.Station","open_issues":54,"stargazers_count":1201,"topics":["tts","yandex-station"],"last_fetched":1712225593.187488},"263757123":{"manifest":{"name":"NWS Alerts"},"description":"An updated version of the nws_alerts custom integration for Home Assistant","domain":"nws_alerts","etag_releases":"W/\"757632aa05d6bbd0edc57c2354a53fe8b8beb156dad57a74290947de45854831\"","etag_repository":"W/\"a65969ea34e0120ea4e0930907c5a3470702d9189a83dbc623088ffdfbb59f82\"","full_name":"finity69x2/nws_alerts","last_commit":"d131351","last_updated":"2023-11-05T17:44:52Z","last_version":"4.1","manifest_name":"NWS Alerts","open_issues":9,"stargazers_count":68,"topics":["alerts","assistant","home","weather"],"last_fetched":1711520337.854498},"610297310":{"manifest":{"name":"SickGear"},"description":"An Integration to allow Home Assistant and SickGear to be the best of friends","domain":"sickgear","etag_releases":"W/\"f0dcca031c90eacce67f51cc0ac21aed47212eb9bb6e4b3bf19bd1100537388c\"","etag_repository":"W/\"4daf1db79d2fb9fb59f5c2867201d7632f9b267897f95794deeecbf7020e81a8\"","full_name":"thisisthetechie/home-assistant-sickgear","last_commit":"c57ace0","last_updated":"2023-09-18T17:09:40Z","last_version":"Release_0.0.1a","manifest_name":"SickGear","open_issues":3,"stargazers_count":1,"topics":["home-assistant-integration","sickgear"],"last_fetched":1711995828.476705},"289251122":{"manifest":{"country":["SK"],"name":"GoodWe Inverter (experimental)"},"description":"Experimental version of Home Assistant integration for Goodwe solar inverters","domain":"goodwe","etag_releases":"W/\"af2be11246c3a49e8934594651346a4e15fc7419cb3e00dee1fd884a5b87f30f\"","etag_repository":"W/\"010e45235a8e2d0fa5798daa085bdc98c4ce3ac165a86ac5abee604894c66870\"","full_name":"mletenay/home-assistant-goodwe-inverter","last_commit":"9e25815","last_updated":"2024-03-26T21:09:37Z","last_version":"v0.9.9.16","manifest_name":"GoodWe Inverter","open_issues":24,"stargazers_count":125,"topics":["goodwe","pv-systems"],"last_fetched":1711829867.700692},"607766615":{"manifest":{"country":["IT"],"name":"HAM Radio Propagation"},"description":"Custom Integration that allows Home Assistant to receive information on Radio Propagation based on solar conditions and the degree of refraction of the Ionosphere. It also allows you to know the status for the different HF frequency bands and the maximum usable frequency through hundreds of stations installed on earth.","domain":"ham_radio_propagation","etag_releases":"W/\"81e4618cbcc972957f4f53016aded29be906403fcae7c22255734efe7c512a0e\"","etag_repository":"W/\"ba004748c6b2231a606d5887fb8fc5b5f031925c35cd0e41231b201883a4cac6\"","full_name":"emics/ham_radio_propagation","last_commit":"642de29","last_updated":"2023-12-07T11:02:14Z","last_version":"v1.1.6","manifest_name":"HAM Radio Propagation","open_issues":1,"stargazers_count":35,"topics":["assistant","ham-radio","home"],"last_fetched":1709180253.922208},"245694520":{"manifest":{"name":"Helios ventilation"},"description":"Custom component for Home Assistant to connect Helios ventilation system.","domain":"helios","etag_releases":"W/\"53ceb1093ca6991a9fbad6563f8faea7911f3eab42dd2c302b9791b551e83673\"","etag_repository":"W/\"3bebc2c5740327bb2cff979a7d7b7a00de147141a823177a5e7b19df21ae0994\"","full_name":"asev/homeassistant-helios","last_commit":"d435dfb","last_updated":"2022-11-07T22:03:36Z","last_version":"v0.5","manifest_name":"Helios","open_issues":13,"stargazers_count":10,"topics":["helios","ventilation"],"last_fetched":1704104072.50103},"194140521":{"manifest":{"name":"browser_mod"},"description":"\ud83d\udd39 A Home Assistant integration to turn your browser into a controllable entity and media player","domain":"browser_mod","etag_releases":"W/\"c1956f0f1ddbb2575c54d30f38086e6476a6096f70f567dcd2baa413e7173664\"","etag_repository":"W/\"eb9b9ceb3deac924e33839bb7ada17cdb4175888badd0afa22b2d5c69ec7ca1a\"","full_name":"thomasloven/hass-browser_mod","last_commit":"9174138","last_updated":"2024-01-13T17:04:30Z","last_version":"2.3.0","manifest_name":"Browser mod","open_issues":96,"stargazers_count":1184,"last_fetched":1712154011.308255},"608596416":{"manifest":{"country":["RU"],"name":"Taipit Cloud Meters"},"description":"\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0434\u043b\u044f Home Assistant, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0449\u0430\u044f \u043e\u0431\u043b\u0430\u0447\u043d\u044b\u0435 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0438 \u0422\u0430\u0439\u043f\u0438\u0442","domain":"taipit","etag_releases":"W/\"e269df8f1975a14d257cc3bf43dfc0f2e3b6086420bff865c1daecd7d6b1da8e\"","etag_repository":"W/\"4b99c336a28287df15a18d3c73965e047ee60afbeec8cf76ed71d6256cb34a67\"","full_name":"lizardsystems/hass-taipit","last_commit":"d49e340","last_updated":"2024-03-31T10:04:36Z","last_version":"v1.5.0","manifest_name":"Taipit","open_issues":1,"stargazers_count":4,"topics":["energy","smartmeter","taipit"],"last_fetched":1711887965.249306},"402156016":{"manifest":{"name":"Kamstrup 403"},"description":"Custom component that integrates the Kamstrup 403 heating system into Home Assistant. This component does also support a few other heating systems","domain":"kamstrup_403","etag_releases":"W/\"4220dec1d6d809f11f37b6d1a14ec5fcbfb9d54a1680891b5e0004a80843e9d9\"","etag_repository":"W/\"a792558a108f2732b812c5b8698d0401873e4d0e5d5a5d2279eac07d5e4e2a4d\"","full_name":"golles/ha-kamstrup_403","last_commit":"aae1b66","last_updated":"2024-03-18T21:09:59Z","last_version":"2.6.1","manifest_name":"Kamstrup 403","stargazers_count":63,"topics":["home-assistant-component","home-assistant-integration","kamstrup","kamstrup403","stadsverwarming"],"last_fetched":1712197530.083497},"246410785":{"manifest":{"name":"ICS"},"description":"Integration that displays the next event of an ics link (support reoccuring events)","domain":"ics","etag_releases":"W/\"0dfa2a13de3148b87b6a3fba4e5691299ca85048ba2b46b7ffa42ee24e7b44cf\"","etag_repository":"W/\"d0d5bc6296889967dfd274232a0de61a7f3d0c5092bac0195beba884d6a7c654\"","full_name":"KoljaWindeler/ics","last_commit":"1ac16d9","last_updated":"2022-02-10T18:31:39Z","last_version":"20220210","manifest_name":"ics","open_issues":22,"stargazers_count":51,"topics":["appointments","filtering","ics","reoccuring-events"],"last_fetched":1709922038.179859},"548554162":{"manifest":{"country":["CA","US","PR"],"name":"Waste Management"},"description":"Determines your next Waste Management (https://www.wm.com) pickup times for use in Home Assistant.","domain":"waste_management","etag_releases":"W/\"e63206a20a2f7069943ab23a8f953c7ebcf6c504871f921a83eff72d4c402f02\"","etag_repository":"W/\"f0d5a5ed61945627f04f586d3087beb839bca4345f23abdb08535c4e46cab6cd\"","full_name":"dcmeglio/homeassistant-waste_management","last_commit":"ea9c505","last_updated":"2023-02-27T19:35:10Z","last_version":"0.1.6","manifest_name":"Waste Management","open_issues":9,"stargazers_count":6,"topics":["garbage","recycle","waste-management"],"last_fetched":1706230621.218611},"420504770":{"manifest":{"country":["HU"],"name":"Water Quality FVM"},"description":"Water quality integration for Home Assistant with data provided by Budapest FVM","domain":"water_quality_fvm","etag_releases":"W/\"be500e794478266f03b426dbf40297a4f5ad40d38b40cea5e03b965e6d6a1d55\"","etag_repository":"W/\"3256fb3b9d2d45d9486cb9d2aac0986f34467580bc8020b2d9c9c9d95201dfb8\"","full_name":"amaximus/water_quality_fvm","last_commit":"234ce88","last_updated":"2024-04-02T10:20:51Z","last_version":"0.3.5","manifest_name":"Water Quality FVM","open_issues":2,"stargazers_count":4,"topics":["budapest","homeassistant-custom-component","hungary"],"last_fetched":1712060663.754827},"302985427":{"manifest":{"name":"Zidoo Media Player"},"description":"Home-assistant custom component and api wrapper for Zidoo Media Players","domain":"zidoo","etag_releases":"W/\"7849ee1dc15354bf91bb3971f6ebe0322ff346d6f90e12425389509061e6780e\"","etag_repository":"W/\"c14c350a8bc2cc07ad523669bfab9e58fb6042a3e88a8bee91dee0872b5a072b\"","full_name":"wizmo2/zidoo-player","last_commit":"699316f","last_updated":"2024-02-17T19:52:23Z","last_version":"v2.0.1","manifest_name":"Zidoo","open_issues":4,"stargazers_count":19,"topics":["media","player","video-player","zidoo"],"last_fetched":1712067590.58697},"221855213":{"manifest":{"name":"Auto Backup"},"description":"\ud83d\uddc3\ufe0f Improved Backup Service for Home Assistant that can Automatically Remove Backups and Supports Generational Backup Schemes.","downloads":30913,"domain":"auto_backup","etag_releases":"W/\"54f60c8db65c9f6b87e79bca2eb51a142448f7274568d2b77e6ba648d1c679cf\"","etag_repository":"W/\"a1738c58760baffd775abe8576d8f4868a0e92a11b06b7a346ea70cb0a2917f7\"","full_name":"jcwillox/hass-auto-backup","last_commit":"4c522ac","last_updated":"2024-01-10T15:41:31Z","last_version":"v1.4.1","manifest_name":"Auto Backup","open_issues":27,"stargazers_count":296,"topics":["auto-purge","backups","generational-backups","snapshots"],"last_fetched":1712132413.895659},"213346369":{"manifest":{"name":"ECHONETLite Platform"},"description":"A Home Assistant custom component for use with ECHONET enabled devices. ","domain":"echonetlite","etag_releases":"W/\"6bff99313d6e04439e15bc42c1a3d11d743f1af07f794767f9cefb67a4909003\"","etag_repository":"W/\"e1c5a47cbc454c701672091dd8bdf6320d3bb692da6c2397fdbf35702e8076e6\"","full_name":"scottyphillips/echonetlite_homeassistant","last_commit":"465b3bc","last_updated":"2024-04-01T12:32:22Z","last_version":"3.7.9","manifest_name":"ECHONET Lite","open_issues":10,"stargazers_count":109,"topics":["echonet-lite"],"last_fetched":1711981204.586721},"552555459":{"manifest":{"country":["NL","BE","CH","GB","AT"],"name":"LG Horizon"},"description":"Custom integration to control LG Horizon settop boxes for Ziggo(NL), Magenta(AT), UPC(CH), Virgin(GB, IE), Telenet(BE)","domain":"lghorizon","etag_releases":"W/\"0aa6420598f476c21917ac65f1bb73e6f0d826d3b385534a1614768f6bce8d3f\"","etag_repository":"W/\"9a48e602b210be9f3108d1454952927bcb49fd96f061de9cb8316fbaa6d7ed7e\"","full_name":"Sholofly/lghorizon","last_commit":"4fd5890","last_updated":"2024-02-10T19:13:57Z","last_version":"v0.5.9","manifest_name":"LG Horizon","open_issues":9,"stargazers_count":51,"topics":["arris","humax","lg-horizon","magenta","sunrise","telenet","virgin","ziggo"],"last_fetched":1710015560.859852},"220685552":{"manifest":{"name":"Popular Times"},"description":"Custom component for Home Assistant which generates a sensor to show popularity for a google maps place.","domain":"populartimes","etag_releases":"W/\"6c97c75aa3157595cd096a0654d2d58a20ee9d3833afe63d92d48090dfbf1735\"","etag_repository":"W/\"ce614f21c55a11eda8b062ca7a55fdd2acbd3ab52d4ad5cb5b36aa1bcff59574\"","full_name":"freakshock88/hass-populartimes","last_commit":"cff4518","last_updated":"2022-12-30T10:42:30Z","last_version":"0.26","manifest_name":"Popular Times","open_issues":1,"stargazers_count":30,"topics":["google-maps","google-places-api"],"last_fetched":1708380911.646777},"282509738":{"manifest":{"name":"OVH DynHost"},"description":"OVH DynHost Updater Component for https://www.home-assistant.io/","domain":"ovh","etag_releases":"W/\"b26a5b89548cdbd67fb1559bd40ec8fc53e0a6339fa92530298d9096e744ed91\"","etag_repository":"W/\"0fa83e28b8cd38444a8106e0adb32f530ca55033ea25f40f5c38bf28c9c67f2a\"","full_name":"GuilleGF/hassio-ovh","last_commit":"d47c16c","last_updated":"2022-08-08T13:04:12Z","last_version":"2.1.0","manifest_name":"OVH DynHost","open_issues":2,"stargazers_count":19,"topics":["ddns","ddns-updater","ovh","ovh-dynhost"],"last_fetched":1709662710.633833},"339124227":{"manifest":{"country":["NL"],"name":"Zonneplan ONE"},"description":"Unofficial Zonneplan ONE + connect integration for Home Assistant","domain":"zonneplan_one","etag_releases":"W/\"4ff42fd230eea685b85e75d782ee55d212465097e766ceb6347d2461f07169c0\"","etag_repository":"W/\"1dcc70a34d34e387c8efac47200c6e01eb115154afced62cf10f123061cec17a\"","full_name":"fsaris/home-assistant-zonneplan-one","last_commit":"639fe53","last_updated":"2024-04-01T14:13:16Z","last_version":"2024.3.0","manifest_name":"Zonneplan ONE","open_issues":1,"stargazers_count":85,"topics":["home-assistant-component","zonneplan","zonneplan-connect","zonneplan-one"],"last_fetched":1712002620.12567},"469351480":{"manifest":{"name":"De dietrich C230 ECO gas boiler"},"description":"De Dietrich C-230 boiler to Home Assistant integration","downloads":1,"domain":"diematic_3_c230_eco","etag_releases":"W/\"18a50731cb9ba8b5218b10b2bca9c49715c7c4ac8b590f6301c7e4f534127882\"","etag_repository":"W/\"80bf9acd9cfe30904850e849145b2599378dbd89895e16570cd38154fa76c3f4\"","full_name":"IgnacioHR/de-dietrich-c230-ha","last_commit":"1b75ef6","last_updated":"2024-02-07T13:20:35Z","last_version":"v1.0.8","manifest_name":"De Dietrich C-230 Eco","stargazers_count":3,"topics":["boiler","dedietrich"],"last_fetched":1707322857.395053},"464416924":{"manifest":{"name":"Power Pet Door"},"description":"Home Assistant plugin to enable control and monitoring of the Power Pet Door by High Tech Pet","domain":"powerpetdoor","etag_releases":"W/\"98558a77a438d23595be77e7d21a32c3c8a717422f9dde74eb8c58b10d0dea91\"","etag_repository":"W/\"12c9a5e882faf579857023cdadaad8ff9e0be9514cd4cfcc8c08908bbc852f18\"","full_name":"corporategoth/ha-powerpetdoor","last_commit":"166ae90","last_updated":"2024-02-27T13:20:12Z","last_version":"0.4.5","manifest_name":"Power Pet Door","open_issues":2,"stargazers_count":14,"topics":["dog","door"],"last_fetched":1710829048.197509},"265916869":{"manifest":{"name":"Melnor Raincloud"},"description":"Melnor Raincloud Home Assistant Integration","downloads":69,"domain":"raincloud","etag_releases":"W/\"3b4464e6393d2bd164dc971d191707e5e3925fda96facbf31a5cbd5a198b0032\"","etag_repository":"W/\"d0ee838c79e6970dce9b0a801c399af826787ababd89752b0d532e465ec31721\"","full_name":"vanstinator/hass-raincloud","last_commit":"cf06961","last_updated":"2022-05-30T18:58:16Z","last_version":"1.3.0","manifest_name":"Melnor RainCloud","stargazers_count":6,"topics":["assistant","home","irrigation","melnor","raincloud","sprinkler"],"last_fetched":1678624899.77911},"525588589":{"manifest":{"name":"Aquarea Smart Cloud"},"description":"Home Assistant integration for Panasonic Aquarea devices connected to Aquarea Smart Cloud","domain":"aquarea","etag_releases":"W/\"743d6a5a8472110a7ad41b0898eb2bc9e6793bc36165eb50b10a1b7842b6f91d\"","etag_repository":"W/\"e05c1364dd4ec3fe57f559222dfc4318f898e36bfbee46f65c1fbfc9274fb7d4\"","full_name":"cjaliaga/home-assistant-aquarea","last_commit":"15924ff","last_updated":"2024-04-01T21:47:16Z","last_version":"v0.7.1","manifest_name":"Aquarea Smart Cloud","open_issues":20,"stargazers_count":65,"topics":["aquarea","panasonic","panasonic-comfort-cloud","panasonic-smart-cloud"],"last_fetched":1712161005.070289},"555110808":{"manifest":{"name":"IamMeter Modbus"},"description":"IamMeterr Modbus custom_component for Home Assistant","domain":"iammeter_modbus","etag_releases":"W/\"3dc32f0905b44253e6c35466d1e6376ff36c69976683f33fe584f2c42d1746e8\"","etag_repository":"W/\"37750f0f7e9ebdd06dc86ee1bd39d1746c8f4b2ccb098eba2e6bde7e82fda35d\"","full_name":"lewei50/ha_iammeter_modbus","last_commit":"1242721","last_updated":"2024-04-02T01:35:22Z","last_version":"v1.0.12","manifest_name":"IamMeter Modbus","open_issues":1,"stargazers_count":1,"last_fetched":1712046058.275973},"617699018":{"manifest":{"name":"EIA Hourly Demand"},"description":"Home Assistant Component to retrieve Hourly Energy Demand Data from EIA by Balancing Authority","domain":"eia_hourly_demand","etag_releases":"W/\"38f3ea234b01973fb7698ba1267e5604221998e2ab3015effa9c8f295a80e530\"","etag_repository":"W/\"d71fb1f102fcb954dddefb1265055b90f9a58f363f1054dc4b985bfdcba86b89\"","full_name":"hokiebrian/eia_hourly_demand","last_commit":"711f0a0","last_updated":"2024-02-01T00:27:32Z","last_version":"v1.0.12","manifest_name":"EIA Demand Data by Balancing Authority","open_issues":1,"stargazers_count":4,"topics":["eia","energy","energy-monitor","homeassistant-custom-component","megawatts"],"last_fetched":1706749226.223647},"504337320":{"manifest":{"name":"Dremel 3D Printer"},"description":"Dremel 3D Printer integration for Home Assistant.","domain":"dremel_3d_printer","etag_releases":"W/\"245bc084c197cdde762a9c27c99c3a5cbc786522a045e639edff984fdcbd6097\"","etag_repository":"W/\"bf7ef08fbca20521ac5fb78fa9c34cd08fa6d5744ba624e117bd468bcb81be5b\"","full_name":"godely/ha-dremel-3d-printer","last_commit":"5b5f7a5","last_updated":"2023-11-17T07:03:09Z","last_version":"v2.1.0","manifest_name":"Dremel 3D Printer","stargazers_count":7,"topics":["3d","3d-printer","3d-printing","bosch","dremel","dremel-idea-builder","dremel-ideabuilder"],"last_fetched":1711995529.02991},"661342098":{"manifest":{"name":"SwitchBot Remote IR"},"description":"A Custom HomeAssistant Integration to control Switchbot Hub","domain":"switchbotremote","etag_releases":"W/\"155efdec12fce6c05e1e81d195ba4bb2db0bd2d173bb5fa8fbebcb257beb04ca\"","etag_repository":"W/\"a99efca9bd9904305772be1bbf177d968d1863c7aa17683bc7a6bd3a54a90131\"","full_name":"KiraPC/ha-switchbot-remote","last_commit":"b74f7aa","last_updated":"2024-03-23T16:40:53Z","last_version":"1.1.4","manifest_name":"SwitchBot Remote IR","open_issues":4,"stargazers_count":35,"topics":["python3","switchbot"],"last_fetched":1711217927.668101},"351604227":{"manifest":{"country":["se"],"name":"Brandrisk ute"},"description":"The custom compontnet will get fire risks and fire prohibition from the Brandrisk Ute API for the supplied position.","domain":"brandriskute","etag_repository":"W/\"e4b5c4fc02564ce409cfe3ea22470272b3b3fe851150c4ab81dc529c90cf2daa\"","full_name":"Sha-Darim/brandriskute","last_commit":"5cf3115","last_updated":"2022-06-05T20:43:41Z","manifest_name":"Brandrisk ute","stargazers_count":4,"topics":["fire-risks","risks","sensors"],"last_fetched":1678387569.750566},"351828005":{"manifest":{"name":"Dahua VTO"},"description":"Control Dahua VTO/VTH devices from Home Assistant","domain":"dahua_vto","etag_releases":"W/\"ccd0df2af9e65751158d9d1cd239ef587210c1936f56f3478e549db69d09f4c2\"","etag_repository":"W/\"49a796b3a13b01e82ccdeb710cb0cfb3a265c145a298dd6bd3d5d2ae33c7ca3c\"","full_name":"myhomeiot/DahuaVTO","last_commit":"a4c8520","last_updated":"2023-04-11T19:32:50Z","last_version":"1.0.7","manifest_name":"Dahua VTO","stargazers_count":128,"topics":["dahua"],"last_fetched":1711328511.849244},"535833284":{"manifest":{"name":"Chroma"},"description":"Control your Chroma-enabled devices from Home Assistant","domain":"chroma","etag_releases":"W/\"bec1de007067b03d4612ee75df97948eba619b7a5fa1c2f27526cbab67e35c82\"","etag_repository":"W/\"6d3e48a4bf1680c6ba296ecf665ddbf737a7afa1c004557dce1e96a0d6692db7\"","full_name":"Vaskivskyi/ha-chroma","last_commit":"cde7d28","last_updated":"2024-02-05T16:42:37Z","last_version":"0.3.0","manifest_name":"Chroma","open_issues":9,"stargazers_count":19,"topics":["chroma","razer","razer-chroma"],"last_fetched":1710339605.499972},"250866164":{"manifest":{"name":"Event sensor"},"description":"HomeAssistant custom sensor to track specific events","domain":"eventsensor","etag_releases":"W/\"944561bb5b8952a902888fef954d6461c4d9f83a409b9df52c6b69fe9fe045d5\"","etag_repository":"W/\"9df71b90fc49b0e63c0a5ac9570e111ba61524dfa5620b111bf236be8a446556\"","full_name":"azogue/eventsensor","last_commit":"c5e931e","last_updated":"2024-04-01T20:48:45Z","last_version":"v3.3.1","manifest_name":"EventSensor","open_issues":9,"stargazers_count":86,"last_fetched":1712009605.830046},"200665691":{"manifest":{"name":"ICS Calendar (iCalendar)"},"description":"Provides an ICS (icalendar) platform for the Home Assistant calendar","domain":"ics_calendar","etag_releases":"W/\"afe5dfc0139428739d2c1a14288ef6486c407ab2ae5cab51bf3382ba722b8fe9\"","etag_repository":"W/\"37af2d667dfaeb40ae12e5e4a4e7d9ab46e5c785985b60e5be1f49d69ceddd79\"","full_name":"franc6/ics_calendar","last_commit":"32c24c1","last_updated":"2024-03-25T23:22:48Z","last_version":"4.2.0","manifest_name":"ics Calendar","open_issues":19,"stargazers_count":116,"topics":["calendar","ics"],"last_fetched":1712053044.704118},"597539627":{"manifest":{"name":"Cielo Home"},"description":"Integration with Cielo Home","domain":"cielo_home","etag_releases":"W/\"c5902e7c02e32c9ca4ba08b820cfc6f64c5b64cc6647258304cbb2118a28d305\"","etag_repository":"W/\"77109b8625b1a00a2241854164690c77157be7afa49708a2e45c242bd74f2bd5\"","full_name":"bodyscape/cielo_home","last_commit":"efdf836","last_updated":"2024-02-04T14:05:23Z","last_version":"1.7.4","manifest_name":"Cielo Home","open_issues":2,"stargazers_count":37,"topics":["cielo","thermostat"],"last_fetched":1712002490.099619},"293488791":{"manifest":{"country":["PL"],"name":"Uonet+ Vulcan"},"description":"Vulcan inegration for home assistamt","domain":"vulcan","etag_releases":"W/\"069a2fe8f8beeaddb6c548c8306339114b22fd74b1de306acaebbb22e6b9d75c\"","etag_repository":"W/\"93fbd6efd648453c62bef4ffbaa88b42be03bb6802cf03336a8069b05ea653cb\"","full_name":"Antoni-Czaplicki/vulcan-for-hassio","last_commit":"ae01480","last_updated":"2024-03-18T07:04:30Z","last_version":"0.15.1","manifest_name":"Uonet+ Vulcan","open_issues":5,"stargazers_count":23,"topics":["timetable","vulcan"],"last_fetched":1711023725.268989},"213950645":{"manifest":{"name":"ElkoEP Lara"},"description":"Support for interface with an ElkoEP Lara devices","domain":"elkoep_lara","etag_releases":"W/\"671743000a42c57120a3d3441165ee38b6e79f8ca4d6c47741402cc4876aa455\"","etag_repository":"W/\"4bbefe92c4bf4b584a71c030fd86fb8e3fe149dc2fa6ecfae218d21815f64adf\"","full_name":"exKAjFASH/media_player.elkoep_lara","last_commit":"e0ac8b3","last_updated":"2022-04-21T20:37:03Z","last_version":"v0.3.1","manifest_name":"elkoep_lara","last_fetched":1684890808.360924},"290261325":{"manifest":{"name":"Adaptive Lighting"},"description":"Adaptive Lighting custom component for Home Assistant","domain":"adaptive_lighting","etag_releases":"W/\"fdb188e900f90150ce3230bfd12ef3ccb97e34385af793988200535ba9e8e624\"","etag_repository":"W/\"93a0bc65134c48e3fe8cc369447ea094b22b0a3b5c058ba381a663fc85951257\"","full_name":"basnijholt/adaptive-lighting","last_commit":"f2a124c","last_updated":"2024-04-03T21:59:40Z","last_version":"1.20.0","manifest_name":"Adaptive Lighting","open_issues":113,"stargazers_count":1563,"topics":["adaptive-lighting","automation","hue","iot","lights","sunrise","sunset","zigbee"],"last_fetched":1712204264.800883},"555221653":{"manifest":{"name":"ViVa Coastal Weather"},"description":"A modern Home Assistant integration for ViVa weather service from Swedish Sj\u00f6fartsverket","downloads":189,"domain":"viva","etag_releases":"W/\"0c5fab3913779fb0ce75f7e745520a1ed7b15fae0f111a6c358b5217d4d7456b\"","etag_repository":"W/\"bf56a1c7db8c800ae040a881b5afac62a4ca9743dab6aaeddcaabb480f14d69f\"","full_name":"astrandb/viva","last_commit":"79ce553","last_updated":"2024-04-01T17:48:57Z","last_version":"v1.0.5","manifest_name":"ViVa Coastal Weather","open_issues":6,"stargazers_count":5,"topics":["sealevel","sjofartsverket","viva"],"last_fetched":1711995362.115682},"209955487":{"manifest":{"country":["CZ"],"name":"BMR"},"description":"Control BMR heating regulation system from Home Assistant","domain":"bmr_hc64","etag_repository":"W/\"f2207e8cba546c92025ad5262be2f45c6b28e413361f853d2d1fc18b4910f298\"","full_name":"slesinger/HomeAssistant-BMR","last_commit":"a3b2b9f","last_updated":"2024-01-11T22:00:59Z","manifest_name":"BMR HC64","open_issues":1,"stargazers_count":4,"last_fetched":1711974710.769374},"248046910":{"manifest":{"name":"SamsungTV Encrypted"},"description":"Samsung TV Encrypted Models (H & J Series) custom component for Home Assistant","domain":"samsungtv_encrypted","etag_releases":"W/\"de13a5e4b1d1fbd52dc24a266e35c39d8c16619ea8200790d82bdfa33003c0a3\"","etag_repository":"W/\"12f76ef663a971f43d0181c7d62501bf66ff616ab44f33bb9b85bc5e5c0b7ab1\"","full_name":"sermayoral/ha-samsungtv-encrypted","last_commit":"da0f13f","last_updated":"2024-03-10T12:31:20Z","last_version":"2022.3.1","manifest_name":"SamsungTV Encrypted","open_issues":23,"stargazers_count":38,"topics":["iot","samsungtv"],"last_fetched":1711189213.603684},"517642950":{"manifest":{"name":"Apex"},"description":"Local Neptune Apex HA Integration (Aquarium Controller)","domain":"apex","etag_releases":"W/\"c1043d8988b740ca45aea1ef626ed5c45a0f15921afb53ff0c0c88671368a317\"","etag_repository":"W/\"3672914d22b7ea3bcce47ade3edd9ed40f8528b7d1d064e795b6b9b714622c7d\"","full_name":"itchannel/apex-ha","last_commit":"2e66e4f","last_updated":"2023-08-04T11:26:42Z","last_version":"1.14-Release","manifest_name":"Apex","open_issues":17,"stargazers_count":16,"topics":["aquarium","aquarium-controller"],"last_fetched":1710296659.144119},"418810115":{"manifest":{"name":"pfSense integration for Home Assistant"},"description":"pfSense integration with Home Assistant","domain":"pfsense","etag_releases":"W/\"ab442ac730bd04ef5bc91ea8380b1a983a05f043380b2be38a5d3bad90429750\"","etag_repository":"W/\"2f4829acb82ec84098a3209b03e2879e1c67943f5d9b687dd6ed96933449373b\"","full_name":"travisghansen/hass-pfsense","last_commit":"d10fa95","last_updated":"2024-02-17T15:26:52Z","last_version":"v0.6.5","manifest_name":"pfSense","open_issues":41,"stargazers_count":174,"topics":["hassio-integration","pfsense"],"last_fetched":1711175258.999849},"625309779":{"manifest":{"country":["BE"],"name":"Nexxtmove"},"description":"Home Assistant component for the Nexxtmove - Powerdale platform","domain":"nexxtmove","etag_releases":"W/\"97b4cf3f99d5241bb041281c1ce5b625288fd452edf77c86af66fdfc9aee7235\"","etag_repository":"W/\"18947b5530ca1c25e173e866aa867b6f7af57a6a8f21f07650925819748e2e9c\"","full_name":"geertmeersman/nexxtmove","last_commit":"aeb03a4","last_updated":"2024-03-28T14:21:25Z","last_version":"v0.9.3","manifest_name":"Nexxtmove","stargazers_count":9,"topics":["hacs-custom","nexxtmove","powerdale"],"last_fetched":1711642703.668},"409126039":{"manifest":{"name":"Solcast PV Solar"},"description":"Solcast Integration for Home Assistant","downloads":2309,"domain":"solcast_solar","etag_releases":"W/\"23120c7d58f2f45a30ce0cb661529ee3aac304b3902bde5b6ed7eb4e30a9d9a1\"","etag_repository":"W/\"cb08f25c68304970fd52d39fa2b392124c9209c473597b185a2246a2199484ce\"","full_name":"oziee/ha-solcast-solar","last_commit":"15c79af","last_updated":"2024-03-31T10:08:56Z","last_version":"v4.0.16","manifest_name":"Solcast PV Forecast","open_issues":1,"stargazers_count":155,"topics":["forecasting","pv","solar","solar-energy","solcast"],"last_fetched":1712118129.344736},"332911333":{"manifest":{"name":"Irrigation Unlimited"},"description":"\u2652Irrigation controller for Home Assistant","domain":"irrigation_unlimited","etag_releases":"W/\"2b1a4e2a1c0f867933273324d480f2d5295fcd9e7e68d0645f1ee4f8ebf7a3f7\"","etag_repository":"W/\"7653c91c79d300ef66bf5bc051d451b6e15c82d3b732a233b76989175c42cb5b\"","full_name":"rgc99/irrigation_unlimited","last_commit":"d268078","last_updated":"2024-03-11T05:14:36Z","last_version":"2024.1.0","manifest_name":"Irrigation Unlimited","open_issues":35,"stargazers_count":271,"topics":["garden-automation","irrigation","irrigation-control-system","irrigation-controller","sprinkler-controller","water","watering-controller","watering-system"],"last_fetched":1711995756.933941},"362058414":{"manifest":{"name":"Libratone Zipp"},"description":"Control a Libratone Zipp speaker within Home Assistant","domain":"libratone_zipp","etag_releases":"W/\"d0da391b51b02cd87aceba50b762af1a6f9542617c7c8d3e098dc11f7fc970d1\"","etag_repository":"W/\"ac8bb82fc37fdf673e83f7ef0b01987cc3e98c55691dbe258249399beb54d135\"","full_name":"Chouffy/home_assistant_libratone_zipp","last_commit":"a0f7067","last_updated":"2022-05-27T07:58:22Z","last_version":"3.0.5","manifest_name":"Libratone Zipp","stargazers_count":6,"topics":["home-assistant-integration","libratone","python3"],"last_fetched":1701598512.652188},"250488711":{"manifest":{"name":"Niu Scooter Integration"},"description":"niu scooter integration for Home assistant.","domain":"niu","etag_releases":"W/\"307b6eb0c05d0f2670c20b3a7e0d99587d70d3b616ff3841588909679f18e01c\"","etag_repository":"W/\"1ce6e189687f91c4b484f0a15fef791755e6a93c94698de95ef82b353732a03d\"","full_name":"marcelwestrahome/home-assistant-niu-component","last_commit":"1c12016","last_updated":"2024-03-09T19:01:18Z","last_version":"2.1.3","manifest_name":"Nui Scooters","open_issues":1,"stargazers_count":41,"topics":["niu","scooters"],"last_fetched":1710015418.265617},"192664631":{"manifest":{"country":["AT","BY","BE","HR","CZ","DK","EE","FI","FR","DE","HU","IT","KZ","LV","LT","NL","NO","PL","PT","RU","SK","SI","ES","SE","CH","GB","SA","AE"],"name":"Bosch Indego Mower"},"description":"Home Assistant Custom Component for Bosch Indego Lawn Mower","domain":"indego","etag_releases":"W/\"854e2c05b3e67cfc57f535e8c91290dca13a114a107bcfa9d25c7b87ef0d76be\"","etag_repository":"W/\"050b040b3a26272eaf0ecd763f591e658ba72f86b1c26f48a7682d4d16ec2198\"","full_name":"jm-73/Indego","last_commit":"201a435","last_updated":"2023-12-02T14:05:51Z","last_version":"5.6.1","manifest_name":"Bosch Indego Mower","open_issues":4,"stargazers_count":75,"topics":["bosch-mower","indego","iot"],"last_fetched":1711981000.009338},"550121200":{"manifest":{"name":"Weback vacuum"},"description":"Control vacuum using Weback app into HomeAssistant. Many brands using this application can be controlled as : Neatsvor, Tesvor, Abir, Orfeld, Valubot...","domain":"weback_vacuum","etag_releases":"W/\"12dbb87f1d1e5c42454a297f06d3b9705ff269fc569ed9071dfe2f0d109d215c\"","etag_repository":"W/\"1943687f8d1e676a06a8668f5c6389e7875414282b5ec4fb5af8b00a7e08a3b1\"","full_name":"Jezza34000/homeassistant_weback_component","last_commit":"0f073fd","last_updated":"2024-04-03T08:16:17Z","last_version":"1.1.8","manifest_name":"WeBack/Tesvor Vacuum","open_issues":2,"stargazers_count":25,"topics":["abir","component","neatsvor","tesvor","vacuum-cleaner","vacuum-robot","weback"],"last_fetched":1712153773.220734},"501368149":{"manifest":{"country":["DK"],"name":"Fuelprices DK"},"description":"Scraping of 5 types of fuel :fuelpump: from 8 different fuelcompanies in Denmark :denmark:.","domain":"fuelprices_dk","etag_releases":"W/\"ac16c1fd073163a183be853aabd6f2be140301c71f4747dc70d0435620da1655\"","etag_repository":"W/\"8e8e7be7fd3a2aa5dafbd5970506c3a0402e6365e5035a9984bbbb6fcffd5619\"","full_name":"J-Lindvig/Fuelprices_DK","last_commit":"c36d6a1","last_updated":"2024-02-06T21:41:40Z","last_version":"v1.6","manifest_name":"Fuelprices DK","open_issues":10,"stargazers_count":16,"topics":["denmark","economy","fuel-prices","scraping"],"last_fetched":1707509801.01624},"431440766":{"manifest":{"name":"HASS.Agent Notifier"},"description":"HASS.Agent Notifier integration. Adds notifications to HASS.Agent - a Windows based client for Home Assistant.","domain":"hass_agent_notifier","etag_releases":"W/\"90ffd55a34c9eaefd9c4ecb2e27964d7f4e0b13940f7d4518e55f7a5c7a1a63c\"","etag_repository":"W/\"7d77c9e8b6827552a2a04433c4a3c00d3ab22e7d6f62c38ad6b005e7cb907b8c\"","full_name":"LAB02-Research/HASS.Agent-Notifier","last_commit":"0d91ec0","last_updated":"2022-11-17T13:29:03Z","last_version":"v2022.10.25.1","manifest_name":"HASS.Agent Notifier","open_issues":3,"stargazers_count":67,"topics":["notifications"],"last_fetched":1709929004.94285},"269316095":{"manifest":{"name":"Overkiz (by Somfy) - Custom component"},"description":"Custom component for Home Assistant to interact with smart devices via Somfy TaHoma or other OverKiz based API's.","domain":"tahoma","etag_releases":"W/\"4eb439a1baff669de24c49491c0351ab9fa0f7bee85a0a30fdfdc4075f90cc27\"","etag_repository":"W/\"30795420ae79e17e7d906b042ade21cc7bc8dc1e9463228b29a2867153b4076d\"","full_name":"iMicknl/ha-tahoma","last_commit":"a26ad39","last_updated":"2023-12-15T23:20:50Z","last_version":"v2.15.1","manifest_name":"Overkiz (by Somfy) - Custom component","open_issues":15,"stargazers_count":151,"topics":["cozytouch","hi-kumo","nexity","overkiz","rexel","somfy","tahoma"],"last_fetched":1709835576.818779},"512007926":{"manifest":{"name":"Reolink Discovery"},"description":"ReoLink Discovery Protocol Integration for Home Assistant","domain":"reolink_discovery","etag_releases":"W/\"fc248b165765c45a98cce1960dd5ff0bc671ef5a8825c7236edc115c451d72fc\"","etag_repository":"W/\"ecd019dc1892a8dd2173c69f5e013c9d7eef52e53a0301a33401ef4d685dc58f\"","full_name":"xannor/ha_reolink_discovery","last_commit":"be64b1a","last_updated":"2023-11-08T19:03:45Z","last_version":"v2.0.0","manifest_name":"Reolink Discovery","open_issues":3,"stargazers_count":9,"topics":["component"],"last_fetched":1709951002.934859},"668476421":{"manifest":{"name":"Napoleon eFIRE"},"description":"Napoleon eFIRE Integration for Home Assisstant","downloads":67,"domain":"napoleon_efire","etag_releases":"W/\"f804dab6708421ffc5f27d33f64b39f7996bc24ea859f9dddf50d4f13b550f9e\"","etag_repository":"W/\"2cd8ee3c307c21f2b5f292d73efae76f8a4baf89a6c08b38078819dce5f45bb9\"","full_name":"kaechele/napoleon-efire","last_commit":"51387d0","last_updated":"2024-04-01T21:30:30Z","last_version":"v0.2.1","manifest_name":"Napoleon eFIRE","open_issues":2,"stargazers_count":1,"topics":["bluetooth","bluetooth-low-energy","efire","fireplace","home-assistant-component","napoleon"],"last_fetched":1712019717.370907},"295523408":{"manifest":{"name":"Salus iT600"},"description":"Home Assistant integration with Salus devices","domain":"salus","etag_releases":"W/\"84c0ed3302363a6d65fbfd61b897fc5ca9a8c6c47ae1d0ac928155747246679f\"","etag_repository":"W/\"1237dff681bde388d6eb7946bb1fb22329c4225c619ab9a938d8d34f383a47fa\"","full_name":"epoplavskis/homeassistant_salus","last_commit":"7b4a1da","last_updated":"2023-11-05T21:19:13Z","last_version":"0.5.1","manifest_name":"Salus iT600","open_issues":27,"stargazers_count":47,"last_fetched":1709555373.34353},"593780777":{"manifest":{"name":"52PI UPS Integration"},"description":"Home Assistant integration for the 52PI UPS","domain":"upsplus","etag_releases":"W/\"20a71d205bebab0204b9e88e91090c64431d0fd3d72deab74ad7184182dd8359\"","etag_repository":"W/\"89d176d31eb2538c472bbf817c1bf79369ea8def8e7aed011cb70a80875e813b\"","full_name":"archef2000/homeassistant-upsplus","last_commit":"9cac01b","last_updated":"2024-03-17T11:12:03Z","last_version":"v1.1.0","manifest_name":"UPS I2C","open_issues":1,"stargazers_count":8,"topics":["52pi","custom-integration","upsplus"],"last_fetched":1710706400.286379},"674163098":{"manifest":{"name":"MeasureIt"},"description":"Measure anything in Home Assistant based on time and conditions.","domain":"measureit","etag_releases":"W/\"3f2d7bf6f03760daec50b046ed3957f0104c283e73c6dbd0972e5f042797739d\"","etag_repository":"W/\"5992c252eb22c5e0194065c4f1a583246425ca91b59a5b053244ef1767cbfe08\"","full_name":"danieldotnl/ha-measureit","last_commit":"3267d25","last_updated":"2024-04-04T07:40:02Z","last_version":"v0.7.0","manifest_name":"MeasureIt","open_issues":3,"stargazers_count":113,"topics":["conditional","measuring","meter"],"last_fetched":1712225703.444495},"207881337":{"manifest":{"name":"Anniversaries"},"description":"Anniversary Countdown Sensor for Home Assistant","downloads":7509,"domain":"anniversaries","etag_releases":"W/\"a73990c142a4eeb0704bf84171727cb459a74884c06d07d0382ae416039224d1\"","etag_repository":"W/\"17940a22b7cbf5d7c5ee8ac850703e56ccb0e561f2dcc118390adec04a175730\"","full_name":"pinkywafer/Anniversaries","last_commit":"c09476f","last_updated":"2023-09-04T22:24:54Z","last_version":"5.2.0","manifest_name":"Anniversaries","open_issues":24,"stargazers_count":156,"topics":["anniversaries"],"last_fetched":1711909264.407904},"462065554":{"manifest":{"name":"Life Time Fitness"},"description":"Life Time Fitness integration for Home Assistant","downloads":2,"domain":"lifetime_fitness","etag_releases":"W/\"348ce1e7d9054d5f68662dfdf521b3a079e86f4cc4a1366f19b7393a381b62ef\"","etag_repository":"W/\"f1017579eb65a7e04ed5988ac7f7e51db01e709b63e0976de87ab21433479bfc\"","full_name":"GuyLewin/home-assistant-lifetime-fitness","last_commit":"4416ff8","last_updated":"2024-01-20T17:03:37Z","last_version":"1.2.0","manifest_name":"Life Time Fitness","stargazers_count":4,"topics":["lifetime"],"last_fetched":1707027479.042537},"369883961":{"manifest":{"name":"Silence Scooter Integration"},"description":"Home Assistant Integration for Silence Scooter","domain":"silencescooter","etag_releases":"W/\"4a0ca9797fa2aecfea7b1bfcb89427d0de755caf46c945616c881848a9ee64be\"","etag_repository":"W/\"e629a34138238131ddf7810688ca332bd6dc0f5c7f64cac1f9921d2aa36fed18\"","full_name":"lorenzo-deluca/homeassistant-silence","last_commit":"791c78e","last_updated":"2023-03-18T07:22:04Z","last_version":"v0.9.5","manifest_name":"Silence Scooter","open_issues":4,"stargazers_count":15,"topics":["electric-vehicles","silence","silence-s01","silence-scooter"],"last_fetched":1710857833.856591},"606225263":{"manifest":{"name":"Google Assistant SDK Custom"},"description":"Fork of Google Assistant SDK integration to allow getting responses from commands to Google Assistant","downloads":1306,"domain":"google_assistant_sdk_custom","etag_releases":"W/\"712163ac08d6a10a37c7a1503a46b4bd47cc3ca0ea9414dee81cf41b60786818\"","etag_repository":"W/\"d2c9251099e1f5f3d59fa52104b4bfe88bdc62d4ca76d07aea8693c5183ab1ca\"","full_name":"tronikos/google_assistant_sdk_custom","last_commit":"0908b6f","last_updated":"2024-02-02T18:40:39Z","last_version":"v0.1.1","manifest_name":"Google Assistant SDK Custom","stargazers_count":20,"topics":["google","google-assistant-api","google-assistant-sdk","home-assistant-component","homeassistant-custom-component"],"last_fetched":1711283388.08712},"282427417":{"manifest":{"name":"Public Transport Victoria"},"description":"Custom component for retrieving departure times for Public Transport Victoria.","domain":"public_transport_victoria","etag_releases":"W/\"c19e63cdb6106e3227d7739b835cf1e4841091c343afc89846c6b6c3d881f31b\"","etag_repository":"W/\"8df6db68206c06f796eb5b46fd97401a08c4c2b5316a9c7c0c35a2120b343553\"","full_name":"bremor/public_transport_victoria","last_commit":"8dea279","last_updated":"2022-06-20T00:23:49Z","last_version":"0.5","manifest_name":"Public Transport Victoria","open_issues":6,"stargazers_count":28,"topics":["australia","bus","ptv","public","train","tram","transport","victoria"],"last_fetched":1705753390.842393},"701792186":{"manifest":{"name":"Oncharger"},"description":"Home Assistant Oncharger EV integration","domain":"oncharger","etag_releases":"W/\"9fdbe6bc6119d5029018b7017c4c51448a855bd55f91e122cac7571f443ddf39\"","etag_repository":"W/\"6c3bcdde7822e47fedf01bdc57c8244ef51558fde35d8da023978a6f49e9a9a3\"","full_name":"krasnoukhov/homeassistant-oncharger","last_commit":"bd459d4","last_updated":"2024-03-12T09:26:45Z","last_version":"v1.4.0","manifest_name":"Oncharger","open_issues":2,"stargazers_count":3,"topics":["oncharger"],"last_fetched":1710857807.677799},"518498752":{"manifest":{"country":["CN"],"name":"HeFeng Weather Forecast for Home Assistant"},"description":"\u548c\u98ce\u5929\u6c14 homeassistant\u63d2\u4ef6","domain":"heweather","etag_releases":"W/\"4fe4575f1ed3ca3e1c7a1bbab6d92e793ebaabe71bd3c59434f70ba18aaa4a5c\"","etag_repository":"W/\"c981c6d43c10d879b039b9132eac734c090aae90939bd10db2d3860e9b654e52\"","full_name":"c1pher-cn/heweather","last_commit":"2e554c9","last_updated":"2024-03-27T15:03:10Z","last_version":"v1.0.0","manifest_name":"\u548c\u98ce\u5929\u6c14","open_issues":1,"stargazers_count":100,"topics":["weather"],"last_fetched":1711620862.9587},"181743867":{"manifest":{"name":"Brematic"},"description":"Custom component for Home Assistant to support Brematic devices","domain":"brematic","etag_releases":"W/\"b5459c0ae0b8942fba38d9b177bd96ab7c8780c3e6f443410322b552c4255368\"","etag_repository":"W/\"fdd5db0f3ff67e0d094f546d8d2a2f07f62029602fbc8c9f96cc1db5c491a954\"","full_name":"tefinger/hass-brematic","last_commit":"4e76898","last_updated":"2022-03-30T09:51:05Z","last_version":"v0.6.0","manifest_name":"Brematic","open_issues":2,"stargazers_count":15,"topics":["433mhz","brematic","brennenstuhl","gateway","intertechno"],"last_fetched":1706782909.540254},"398767994":{"manifest":{"name":"Wibeee (and Mirubee) energy monitor"},"description":"Home Assistant: Wibeee energy monitor custom component","downloads":252,"domain":"wibeee","etag_releases":"W/\"9112576aa105a39cb7ff2baff99ab2cff961ffcb096718e6442ca7080a64407f\"","etag_repository":"W/\"6f1d743b92b1369232ce8f8e1f916b12061269f77f6083504f11f44b8403cc74\"","full_name":"luuuis/hass_wibeee","last_commit":"ca326d9","last_updated":"2024-02-23T17:17:31Z","last_version":"v3.6.1","manifest_name":"wibeee","open_issues":3,"stargazers_count":19,"topics":["circutor","mirubee","smilics","wibeee"],"last_fetched":1712053182.099209},"573737078":{"manifest":{"country":["ALL"],"name":"SAJ eSolar Air"},"description":"Custom Integration of SAJ eSOLAR","domain":"saj_esolar_air","etag_releases":"W/\"868623bb3c53dee2cb345b289b5a83b1c50f6e5563ef4709bd4b0f9160933a37\"","etag_repository":"W/\"62bcb588efca21964d152282f5bee38dfa3f5147f865699fd351fc0f833732bf\"","full_name":"faanskit/ha-esolar","last_commit":"46294cf","last_updated":"2023-03-22T12:51:26Z","last_version":"V0.0.9","manifest_name":"eSolar","open_issues":5,"stargazers_count":5,"topics":["esolar","esolar-air","homeassistant-config","homeassistant-custom-component","saj","saj-h1","saj-inverters","saj-r5","solar"],"last_fetched":1710490733.451124},"396083412":{"manifest":{"name":"Midea AC LAN"},"description":"Auto-configure and then control your Midea M-Smart devices (Air conditioner, Fan, Water heater, Washer, etc) via local area network.","downloads":23851,"domain":"midea_ac_lan","etag_releases":"W/\"e3ccd7742cb58418cc01820b0338bc5efb2eb1bdc9a35eb78473a6b6eb1103ae\"","etag_repository":"W/\"4ac02111158d2c2f69a1efb88bc2e4817ffa6861b04973b8239340b3f57d8a4f\"","full_name":"georgezhao2010/midea_ac_lan","last_commit":"7c5231c","last_updated":"2024-03-28T14:35:34Z","last_version":"v0.3.22","manifest_name":"Midea AC LAN","open_issues":125,"stargazers_count":1059,"topics":["air-conditioner","air-purifier","cooker","dehumidifier","dishwasher","dryer","fan","humidifier","lan","midea","refrigerator","washer","water-heater"],"last_fetched":1712225777.302216},"698674167":{"manifest":{"name":"Cover Time Based"},"description":"Integration which allows cover control based on time.","domain":"cover_time_based","etag_releases":"W/\"de734c82e15bc1fe1e0e26b3295ae70bbe24636a6af746a0881c7a53648e7ddb\"","etag_repository":"W/\"9f1804921977bf7820589cb0ac8cfac853d95843ed3eb1ea116798349ec8c597\"","full_name":"Sese-Schneider/ha-cover-time-based","last_commit":"496e1e3","last_updated":"2024-03-15T09:01:04Z","last_version":"v2.0.1","manifest_name":"Cover Time Based","open_issues":5,"stargazers_count":5,"topics":["cover","tilt"],"last_fetched":1712106112.126185},"243122556":{"manifest":{"country":["NOR"],"name":"tide"},"description":"Tide a sensor for HASS.","domain":"tide","etag_releases":"W/\"7db31d3dfac8873920380d8b50d9432ee2bb1b0c7641b5a60f4bfa5c51f84991\"","etag_repository":"W/\"4534098a9d5ec0be0c0bffc0c6218c7118b1f461815435af49802ce32f19d557\"","full_name":"Hellowlol/ha-tide","last_commit":"6bc1842","last_updated":"2021-06-06T20:30:32Z","last_version":"0.0.2","manifest_name":"Tide","stargazers_count":4,"topics":["norway","tide"],"last_fetched":1678387353.088611},"334076222":{"manifest":{"name":"AstroWeather"},"description":"Asynchronous Astro Weather Forecast for Home Assistant","domain":"astroweather","etag_releases":"W/\"ca9d084af3b7a07d6fdbc6e1e6edbdb3f74da3455cf22a423418744b09effecc\"","etag_repository":"W/\"87b250986733c8700b5288aff744c1bc55f54d415aa23b191edae501e0476be4\"","full_name":"mawinkler/astroweather","last_commit":"f1cd47a","last_updated":"2024-03-24T10:26:15Z","last_version":"v0.42.3","manifest_name":"AstroWeather","open_issues":1,"stargazers_count":59,"topics":["7timer","astronomy","forecast"],"last_fetched":1712074922.53967},"257275420":{"manifest":{"name":"OpenMediaVault"},"description":"OpenMediaVault integration for Home Assistant","downloads":5306,"domain":"openmediavault","etag_releases":"W/\"3bac2c19971637be2267e1b6cccc31e51f4d269ba3a4d9184ae4fa84877458bc\"","etag_repository":"W/\"ecf382838b445b172ef7b6e623bdcdcea85b1dddbf6c3865dde9dca19f175a7c\"","full_name":"tomaae/homeassistant-openmediavault","last_commit":"374958a","last_updated":"2024-03-31T12:00:58Z","last_version":"v1.4.2","manifest_name":"OpenMediaVault","open_issues":10,"stargazers_count":97,"topics":["omv","openmediavault"],"last_fetched":1711894711.402995},"134057086":{"manifest":{"name":"Xiaomi Mi Electric Rice Cooker Integration"},"description":"Xiaomi Mi Electric Rice Cooker integration for Home Assistant","domain":"xiaomi_miio_cooker","etag_releases":"W/\"70e7e173fc536bb21ee411e997d98482788faf97114162f4ec360fef5ce10900\"","etag_repository":"W/\"ab2a2dc2213196041c99e2f527fad165a3c4e061df37fa013017c5ae6e4d7a6e\"","full_name":"syssi/xiaomi_cooker","last_commit":"5eb83d5","last_updated":"2023-12-21T20:52:54Z","last_version":"2023.12.0.0","manifest_name":"Xiaomi Mi Electric Rice Cooker","open_issues":29,"stargazers_count":134,"topics":["miio","miio-protocol","rice-cooker","xiaomi","xiaomi-cooker"],"last_fetched":1710260640.968347},"361961255":{"manifest":{"country":["NZ"],"name":"Metlink Wellington Transport"},"description":"Metlink Wellington Public Transport integration for Home Assistant","domain":"metlink","etag_releases":"W/\"3d94bdefe40238a8eb9ef349860dd16704826c1c7aa524675f12ba7c7a7c824c\"","etag_repository":"W/\"64513a3a5ba431f2ff872df80c010498dec085fb9f70a38c1bbd42f7032e7e84\"","full_name":"make-all/metlink-nz","last_commit":"a891cfa","last_updated":"2023-07-03T14:20:35Z","last_version":"1.0.9","manifest_name":"Metlink Wellington Transport","stargazers_count":9,"topics":["metlink","metlink-api","transport","wellington"],"last_fetched":1706077376.777608},"347985393":{"manifest":{"name":"Emulated color temp light"},"description":"Emulate SUPPORT_COLOR_TEMP for color lights that doesn't support color temp (like some Ikea Tradfri bulbs) - Home Assistant component","domain":"emulated_color_temp","etag_releases":"W/\"4e5fb6c896fefedde4b6fca81220335e1c873c4bbf355417b2b4a7e8326d7e8f\"","etag_repository":"W/\"51bb758251e2060de9a06a06aeb9e68ad599f2d663b4873475ee744758d5177f\"","full_name":"Mr-Groch/HA-Emulated-Color-Temp-Light","last_commit":"3ba11f8","last_updated":"2022-08-18T21:25:51Z","last_version":"0.1.8","manifest_name":"Emulated Color Temp Light","open_issues":2,"stargazers_count":7,"topics":["color-lights","color-temperature","ct","ikea-tradfri-bulbs","light"],"last_fetched":1710896393.945792},"255662264":{"manifest":{"name":"Landroid Cloud"},"description":"Landroid Cloud component for Home Assistant","downloads":3044,"domain":"landroid_cloud","etag_releases":"W/\"cc47601a450839b4a794cd550085f889d30fcb4cf58534d908a60dc4e2c250ab\"","etag_repository":"W/\"b793ea13095b22ae197d2ad32489ed017efdd92d8f08268ee4ff110b4050398a\"","full_name":"MTrab/landroid_cloud","last_commit":"c1523b2","last_updated":"2024-04-04T04:17:30Z","last_version":"v4.0.4","manifest_name":"Landroid Cloud","open_issues":12,"stargazers_count":225,"topics":["homeassistant-custom-component","kress","landroid","landxcape","mower-robot","worx"],"last_fetched":1712211713.764862},"265059207":{"manifest":{"name":"ThermIQ MQTT"},"description":"Home Assistant integration of ThermIQ-MQTT, providing control and logging of Thermia heatpumps ","domain":"thermiq_mqtt","etag_releases":"W/\"c8f7761f1a43adc713bf2a49bb997126fb206d105e4707f468e740e97ec0855e\"","etag_repository":"W/\"ae824b08a69bb0861f107a8b31d7fb6c4d46ff06bfc79d6b2ffc9fb12c0935f7\"","full_name":"ThermIQ/thermiq_mqtt-ha","last_commit":"4a164a1","last_updated":"2024-02-27T20:29:34Z","last_version":"v2.2.5","manifest_name":"ThermIQ MQTT Integration","stargazers_count":22,"topics":["bergvarme","danfoss","dhp","diplomat","g2","g3","ha","heatpump","optimum","thermal-pump","thermia","thermiq","thermiq-mqtt","varmepump"],"last_fetched":1711995828.338029},"560848165":{"manifest":{"name":"Compound definition for Home Assistant integration for Homey"},"description":"Homey compound device component","domain":"homey","etag_releases":"W/\"6fdc187fad6eef535de6c0b925acdc6f9d73654329b943f9bff432c3d4d11391\"","etag_repository":"W/\"b824573f6cc28a51a06a4c803e281eda1357a9eec088b9484ab759b69739958c\"","full_name":"RonnyWinkler/homeassistant.homey","last_commit":"e120404","last_updated":"2023-06-08T14:25:19Z","last_version":"1.1.0","manifest_name":"Homey compound device for Home Assistant app","stargazers_count":4,"topics":["compound","homey"],"last_fetched":1697984233.074449},"424346523":{"manifest":{"name":"Centrometal Boiler System"},"description":"Home Assistant custom component integration for Centrometal Boiler System","domain":"centrometal_boiler","etag_releases":"W/\"f08d2fbd2b2efd1642b51ef4e10885bacf380b4c2f63d93c0666acc0a2523b71\"","etag_repository":"W/\"f4a0e51079aded4a9a466bfc9c49028940220eecd297655e392f230027f11e76\"","full_name":"9a4gl/hass-centrometal-boiler","last_commit":"afa42ff","last_updated":"2023-12-08T15:21:43Z","last_version":"0.0.49","manifest_name":"Centrometal Boiler System","open_issues":1,"stargazers_count":5,"topics":["centrometal","peltec"],"last_fetched":1703873716.611399},"355159299":{"manifest":{"country":["ru"],"name":"Moscow PGU (\u0413\u043e\u0441\u0443\u0441\u043b\u0443\u0433\u0438 \u041c\u043e\u0441\u043a\u0432\u044b)"},"description":"Moscow PGU services for HomeAssistant","domain":"moscow_pgu","etag_releases":"W/\"8f87256d733692a1e4e23f34e8072c69eb9de2daed6421792356eb282dd759de\"","etag_repository":"W/\"9d454846fa402e63afd0b8ceac2e1f205947b62cf9b952163a55ae0e4496dfbe\"","full_name":"alryaz/hass-moscow-pgu","last_commit":"a0e68a7","last_updated":"2021-11-10T06:44:41Z","last_version":"v0.3.1","manifest_name":"Moscow PGU / \u0413\u043e\u0441\u0443\u0441\u043b\u0443\u0433\u0438 \u041c\u043e\u0441\u043a\u0432\u044b","open_issues":12,"stargazers_count":18,"topics":["gosuslugi"],"last_fetched":1710929589.295592},"223993584":{"manifest":{"name":"Passive BLE monitor integration"},"description":"BLE monitor for passive BLE sensors","domain":"ble_monitor","etag_releases":"W/\"99ebb66c3ea347cf9d68010433ac4202d81a70a35ea4138dd672ee7a112349ce\"","etag_repository":"W/\"298ea7f8a4a3fdf71df6df6f9934df19f04b060937ebdbab8a2478abab0f87a8\"","full_name":"custom-components/ble_monitor","last_commit":"af07174","last_updated":"2024-03-29T18:35:30Z","last_version":"12.10.4","manifest_name":"Passive BLE monitor","open_issues":65,"stargazers_count":1798,"topics":["atc","govee","inkbird","kegtron","mibeacon","mijia","mitemp-bt","qingping","scales","thermoplus","thermopro","thermplus","xiaomi","xiaomi-sensors"],"last_fetched":1712096156.831076},"323152128":{"manifest":{"name":"Crunch-O-Meter"},"description":"Crunch-O-Meter API as sensors in Home Assistant. See how many people are currently at your local gym","downloads":112,"domain":"crunch_o_meter","etag_releases":"W/\"6237ef0f2d35b025169c9708ba8cc030318aed717bcf35061590c8045bc62529\"","etag_repository":"W/\"4f1697f4df661860ec9b55280f442de2c68e4cf01fbe3038f6649ecf79e95ddc\"","full_name":"GuyLewin/home-assistant-crunch-o-meter","last_commit":"db48e5a","last_updated":"2021-06-14T13:06:16Z","last_version":"1.0.4","manifest_name":"Crunch-O-Meter","stargazers_count":2,"topics":["crunch","crunch-o-meter"],"last_fetched":1704831428.0202},"437278224":{"manifest":{"name":"Dell Printer"},"description":"Support DELL printers in Home Assistant","domain":"dell_printer","etag_releases":"W/\"77c74830948e2cf5c140176fd743a50be0345a63bfed91a87e61c5b06b2e19a8\"","etag_repository":"W/\"36360e5343ced5fb0b9e79c4aa77e14eb1e60bf48712e8f035f3ef7e0b635d09\"","full_name":"kongo09/hass-dell-printer","last_commit":"9e680c4","last_updated":"2022-06-26T17:26:42Z","last_version":"v0.1.6","manifest_name":"Dell Printer","open_issues":2,"stargazers_count":6,"topics":["dell","printer"],"last_fetched":1698886731.190987},"309178213":{"manifest":{"name":"controlid"},"description":"home-assistant service for control the controlid \ud83d\udeaa\ud83d\udd11","domain":"controlid","etag_releases":"W/\"dfd69f2ea3776d7e0269548f7bff12c7466650b167768b216d0975f37d77f3f4\"","etag_repository":"W/\"996dd10f7f13f20da49cd7058a9fc26af511928870877a05dcb62a47f9b5277d\"","full_name":"gtjadsonsantos/controlid","last_commit":"64c8927","last_updated":"2021-06-24T16:29:59Z","last_version":"v2021.1.0","manifest_name":"controlid","topics":["controlid"],"last_fetched":1678387347.25832},"325097827":{"manifest":{"country":["RU"],"name":"MegaD"},"description":"MegaD HomeAssistant integration","domain":"mega","etag_releases":"W/\"06c8b86f61ff2cf42ac05e9bbc6f51769d912141ade7332f4084f7ab5f2eafbb\"","etag_repository":"W/\"dd2d98fd6efe12252ee33357ec1ac6788b4daec93d78dda4714e033158071167\"","full_name":"andvikt/mega_hacs","last_commit":"21697d8","last_updated":"2024-03-12T16:37:52Z","last_version":"v1.1.7","manifest_name":"mega","open_issues":37,"stargazers_count":126,"topics":["custom-integration","megad"],"last_fetched":1712002462.693784},"188106531":{"manifest":{"name":"Mail and Packages"},"description":"Home Assistant integration providing day of package counts and USPS informed delivery images.","downloads":3645,"domain":"mail_and_packages","etag_releases":"W/\"bb5b8bc4376d541f53edf466efefb3d6a239f5e169f529113638a2b6d2698832\"","etag_repository":"W/\"540ccd51a33eae1be2601b3061219abd4ce13210aa1a981b2adaa981c692bc8b\"","full_name":"moralmunky/Home-Assistant-Mail-And-Packages","last_commit":"6abdb93","last_updated":"2024-04-04T01:43:48Z","last_version":"0.3.23","manifest_name":"Mail and Packages","open_issues":15,"stargazers_count":536,"topics":["home-assistant-config","lovelace-card","lovelace-custom-card"],"last_fetched":1712211703.497674},"201599575":{"manifest":{"name":"Emby Latest Media (2024)"},"description":"Home Assistant component to feed Upcoming Media Card with the latest releases on an Emby instance.","domain":"emby_upcoming_media","etag_releases":"W/\"99467fededc1b7c32e43d120125af84cd078d8b61114292b3f7e242d73b3faa3\"","etag_repository":"W/\"c0b68375ea0d5784102f8b9aa0fc86758de42096f3b21ecea6f32d56181d35d8\"","full_name":"gcorgnet/sensor.emby_upcoming_media","last_commit":"7e942ce","last_updated":"2024-02-18T19:25:56Z","last_version":"4","manifest_name":"Emby Latest Media","open_issues":12,"stargazers_count":19,"last_fetched":1712147142.109033},"177169766":{"manifest":{"name":"Wattbox"},"description":"Home Assistant WattBox Component","domain":"wattbox","etag_releases":"W/\"9577385d26b5697b4bddbac02fb04a8dae8e43084ce75b67738f830652291da5\"","etag_repository":"W/\"8e51db1458ae63ac13019f9a6bdf51fdd9f4d9a6ec194e99ce290ff33cfbabc9\"","full_name":"eseglem/hass-wattbox","last_commit":"47e381b","last_updated":"2024-03-10T18:23:27Z","last_version":"v0.8.2","manifest_name":"WattBox","open_issues":7,"stargazers_count":10,"topics":["battery","ups","wattbox"],"last_fetched":1710550567.121639},"646115401":{"manifest":{"name":"Zone4 Remote"},"description":"Control an Apart Zone 4 pre-amp from Home Assistant","downloads":1,"domain":"zone4","etag_releases":"W/\"3cb69c112273e75cf3d6406dd515fcc762ad4464911fcf27f1ffb8329f8d684b\"","etag_repository":"W/\"9c1036fa231c9e77ff59f845608e0aa5c70cccf32476f3c9f2d56d901541cbff\"","full_name":"samjsmart/ha-zone4","last_updated":"2023-05-31T18:13:51Z","last_version":"1.0.0","manifest_name":"Zone4 Remote","topics":["media","zone4"],"last_fetched":1696774585.032294},"578872078":{"manifest":{"country":["US"],"name":"Bouncie"},"description":"Home Assistant custom integration for Bouncie.com - track your car stuff in Home Assistant","downloads":2,"domain":"bouncie","etag_releases":"W/\"38275de4a8657dbfbcc16fc3fc99602ac05bd84b022d806ccf4c3f2b04bd7903\"","etag_repository":"W/\"916a44d8f49cafa3028df1fa2cab0106fb9b3a68d310d3bfb3c76978df43cc15\"","full_name":"mandarons/ha-bouncie","last_commit":"49d34fe","last_updated":"2024-01-31T14:47:56Z","last_version":"0.7.0","manifest_name":"Bouncie","open_issues":4,"stargazers_count":24,"topics":["car","car-metrics","home-assistant-custom-component"],"last_fetched":1711995652.789828},"603596768":{"manifest":{"name":"Haier hOn"},"description":"Home Assistant integration for Haier hOn: support for Haier/Candy/Hoover home appliances like washing machines and air conditioners in 28 languages.","downloads":4746,"domain":"hon","etag_releases":"W/\"fd10cc06325660ad2f8a8bde0c5259792d35eb04a51d137e40409eff5825b2ba\"","etag_repository":"W/\"c29c5b08060eba41d552f07708b6cd1efb70301b1b0ec0635c1eb8d4f4d4fa2b\"","full_name":"Andre0512/hon","last_commit":"6d2a6ce","last_updated":"2024-03-30T22:17:09Z","last_version":"v0.13.0","manifest_name":"Haier hOn","open_issues":43,"stargazers_count":1201,"topics":["candy","haier","haier-hon","home-assistant-integration","hoover"],"last_fetched":1712182322.502584},"472077314":{"manifest":{"country":["GB","US","PL"],"name":"World's Air Quality Index"},"description":"HACS World's Air Quality Index integration from waqi.info","domain":"worlds_air_quality_index","etag_releases":"W/\"63a2f2e6632d5187c7bceaaf60da042ee8b71dafca9f5bfcdfb877e59094f9a9\"","etag_repository":"W/\"43319ccae37490f7e857012844767e32ad1f17b843b6080b38f8f5e129b22286\"","full_name":"pawkakol1/worlds-air-quality-index","last_commit":"066db84","last_updated":"2024-01-15T19:40:52Z","last_version":"v1.1.0","manifest_name":"World's Air Quality Index","open_issues":1,"stargazers_count":39,"topics":["ha","pollution","waqi"],"last_fetched":1709482797.709854},"630565367":{"manifest":{"name":"Technische Alternative CoE"},"description":"Custom Home Assistant integration to read data from a C.M.I. via CoE","domain":"ta_coe","etag_releases":"W/\"484b4740485e0983d22dd49173e8b21829ba86b5eb6b0474c3ed4244dbb42b0c\"","etag_repository":"W/\"6a68724da7b24ca69812778406621e89a6060ebc1de8e01c7d8bf99dbc7ed8d6\"","full_name":"DeerMaximum/Technische-Alternative-CoE","last_commit":"a72069b","last_updated":"2024-01-28T17:13:21Z","last_version":"v1.4.0","manifest_name":"Technische Alternative CoE","open_issues":4,"stargazers_count":6,"last_fetched":1711995458.737757},"137126619":{"manifest":{"name":"Visonic Intruder Alarm - PowerMax and PowerMaster Series"},"description":"Visonic Custom Component for integration with Home Assistant","domain":"visonic","etag_releases":"W/\"68fde148dec170b75c7a1bb8f127273cb1d03b8f4a20b1e37d06abd10620b1f1\"","etag_repository":"W/\"a9e5174a4e5ca652a0ef3992bc6bd74b87e986dfe2b13588143ac1903ff3c751\"","full_name":"davesmeghead/visonic","last_commit":"ee84fc6","last_updated":"2024-03-25T20:02:50Z","last_version":"0.8.5.2","manifest_name":"Visonic Intruder Alarm","open_issues":15,"stargazers_count":78,"topics":["visonic"],"last_fetched":1711455918.468513},"509121113":{"manifest":{"name":"seven"},"description":"HACS supporting Home Assistant integration for seven","domain":"seven","etag_releases":"W/\"400a6ded9e87fc5ac8089f3a1b26f5b81327284b9751be9a3687a518defd5563\"","etag_repository":"W/\"53c48a69b4bd138dd6aadaa573f7209fcd0bbb7817430fffc1e1bee6d2978a2f\"","full_name":"seven-io/home-assistant","last_commit":"e7bc73c","last_updated":"2023-12-19T08:28:05Z","last_version":"v0.0.2","manifest_name":"seven","stargazers_count":3,"topics":["hassio-integration","home-assistant-integration","sms","tts"],"last_fetched":1708575711.717591},"672323037":{"manifest":{"name":"Bluetti BT"},"description":"Bluetti Integration for Home Assistant","domain":"bluetti_bt","etag_releases":"W/\"fe85500cdd81650ca8cc514a6792d1c371c6f94a70be5f0fbc4c4797eb58564e\"","etag_repository":"W/\"1783b188a2d91096c8823d1b87dceb284e2f9259be4e600d6f387d788e85c62e\"","full_name":"Patrick762/hassio-bluetti-bt","last_commit":"7f576df","last_updated":"2024-04-01T12:33:20Z","last_version":"0.0.11","manifest_name":"Bluetti BT","open_issues":17,"stargazers_count":18,"topics":["bluetooth","bluetti"],"last_fetched":1712038976.71248},"154417419":{"manifest":{},"description":"Home Assistant custom component for the newer (2016+) Philips Android TVs","domain":"philips_android_tv","etag_repository":"W/\"ce57db4bbf73673cad026a6fe58356935f4a5f34607437955e929c022df79241\"","full_name":"nstrelow/ha_philips_android_tv","last_commit":"9e9572d","last_updated":"2021-07-22T15:04:24Z","manifest_name":"Philips Android TV","open_issues":16,"stargazers_count":109,"topics":["philips-tv","tv"],"last_fetched":1711275542.724619},"311594993":{"manifest":{"name":"Presence Simulation"},"description":"Home Assistant Presence Simulation","domain":"presence_simulation","etag_releases":"W/\"f3cea0bb3f0177c0378d612a4150357d6e21758a8d6fcbe52a151764f3b9b058\"","etag_repository":"W/\"1174e4f29a30e697a5613c40ce672f8221f43fc7445af63931c8f38de7c1884c\"","full_name":"slashback100/presence_simulation","last_commit":"1d7f3ef","last_updated":"2024-03-28T10:59:14Z","last_version":"v4.5","manifest_name":"Presence Simulation","open_issues":3,"stargazers_count":398,"topics":["historic","presence","presence-simulation","simulation"],"last_fetched":1712219057.118491},"178838527":{"manifest":{"name":"Niko Home Control II"},"description":"Niko Home Control II Home Assistant Integration","domain":"nhc2","etag_releases":"W/\"7d77a622bd1e2b8d9a1955bf0da1a769f0719b68bc0063fd33f8c831dc0347b3\"","etag_repository":"W/\"174f6fa0d12700fe85cf9c77e6382e24b706ff1f559b011c02e138456e520aae\"","full_name":"filipvh/hass-nhc2","last_commit":"f8055fa","last_updated":"2023-01-08T16:29:48Z","last_version":"1.7.0","manifest_name":"Niko Home Control II","open_issues":31,"stargazers_count":37,"topics":["coco","domotica","nhc","nhc2","niko","niko-home-control"],"last_fetched":1710526758.756279},"448980525":{"manifest":{"name":"\ud83e\uddf0 ZHA Toolkit - Service for advanced Zigbee Usage"},"description":"\ud83e\uddf0 Zigbee Home Assistant Toolkit - service for \"rare\" Zigbee operations using ZHA on Home Assistant","downloads":6207,"domain":"zha_toolkit","etag_releases":"W/\"7a98d66af9095135c164eec9297b9ca15e39d613237f57226b9b037488f97472\"","etag_repository":"W/\"7d542f3db284430ca3de8294ca057470eb50301b447abd3bccef6892746115ca\"","full_name":"mdeweerd/zha-toolkit","last_commit":"ced7097","last_updated":"2024-03-13T22:32:34Z","last_version":"v1.1.10","manifest_name":"\ud83e\uddf0 ZHA Toolkit","open_issues":8,"stargazers_count":155,"topics":["home-assistant-component","zha","zigbee","zigpy"],"last_fetched":1711966793.272042},"531321012":{"manifest":{"name":"IAMMETER"},"description":"IAMMETER custom component for Home Assistant","domain":"iammeter_http","etag_releases":"W/\"1663bf1ebba7d473edf1185a99a4bfde9d1425ff0cde168a40bf9bf5de8b976b\"","etag_repository":"W/\"6fa092107fefa1be78782df3e431c6dae8d692a69816e648399f3d7869797393\"","full_name":"lewei50/ha_iammeter","last_commit":"bb44f4b","last_updated":"2024-04-01T08:57:25Z","last_version":"v1.0.15","manifest_name":"Iammeter_http","open_issues":1,"stargazers_count":4,"last_fetched":1711974547.034002},"259865897":{"manifest":{"country":["DE"],"name":"DRK Blutspende"},"description":"DRK Blutspende component for Home Assistant ","domain":"drkblutspende","etag_releases":"W/\"6dfa175f4774be69fd67ed796e79b14a7b3ff9433d1480dfca12387772739289\"","etag_repository":"W/\"449f44f10eb33f28c410fc9aeb7de2362a678d1814ccc15e7d50d8a3afc60420\"","full_name":"Bouni/drkblutspende","last_commit":"381d488","last_updated":"2023-06-09T14:19:36Z","last_version":"0.1.9","manifest_name":"DRK Blutspende","open_issues":1,"stargazers_count":4,"topics":["blutspende","drk"],"last_fetched":1712125011.8743},"520565579":{"manifest":{"name":"Theme Parks Waiting Times"},"description":"A Home Assistant integration that shows Theme Park waiting times using the ThemeParks.wiki API","domain":"themeparks","etag_releases":"W/\"fbbcdf1d179c84d4a4df36d54e28a224a5dfff64e97e02dc354f2988025dc198\"","etag_repository":"W/\"214ca4d1860085324ac12e0664c1e138672c007d6b92985b19149956a892aac3\"","full_name":"danielsmith-eu/home-assistant-themeparks-integration","last_commit":"4282b45","last_updated":"2024-03-15T15:24:43Z","last_version":"v1.2.3","manifest_name":"Theme Park Wait Times","open_issues":4,"stargazers_count":12,"topics":["api","queue","themeparks","times","wait"],"last_fetched":1711419623.66578},"319343045":{"manifest":{"name":"UltraSync"},"description":"Interlogix ZeroWire and Hills ComNav (NX-595E) UltraSync Security Panel for Integration for Home Assistant Comunity Store (HACS)","domain":"ultrasync","etag_releases":"W/\"c1913d153c8e7e66d30e30b7baf6b49149cff492daaa3a4c8434051121b028e3\"","etag_repository":"W/\"189679621c6cfdd9c5e43df9244bdb6e92bf53bd298f8ac829139d8f6c8ed582\"","full_name":"caronc/ha-ultrasync","last_commit":"30a4da8","last_updated":"2024-03-10T16:29:56Z","last_version":"v1.0.7","manifest_name":"UltraSync Alarm Panel Beta","open_issues":8,"stargazers_count":23,"topics":["comnav","homeassistant-custom-component","interlogix","nx-595e","security","ultrasync"],"last_fetched":1711873019.850947},"263179176":{"manifest":{"name":"Smart Irrigation"},"description":"Smart Irrigation custom component for Home Assistant","domain":"smart_irrigation","etag_releases":"W/\"e9949189580962b0f7743f0344a352d8df508b168b22b5bbba9d8c2267db41c1\"","etag_repository":"W/\"011dd5104ea94ff62653a0c541ce25d9da95e2477677c2b36bb99e2fc6c94a18\"","full_name":"jeroenterheerdt/HAsmartirrigation","last_commit":"9be3652","last_updated":"2024-04-03T15:21:42Z","last_version":"v2024.3.1","manifest_name":"Smart Irrigation","open_issues":4,"stargazers_count":287,"topics":["crop","evaporation","evapotranspiration","flow","grass","irrigation","lawn","openweathermap","rain","snow","sprinkler","sprinklers","water","watering"],"last_fetched":1712161168.926447},"139664351":{"manifest":{"name":"Alexa Media Player"},"description":"This is a custom component to allow control of Amazon Alexa devices in Home Assistant using the unofficial Alexa API.","downloads":49726,"domain":"alexa_media","etag_releases":"W/\"82046385abfd817b8dc9a407b25d97892557bf49fbd8c9d9dd2a4e5dad586ce3\"","etag_repository":"W/\"582971086c2c97a0080ce52a1b5d71f21993902288a7de52fd9df99c08cc6951\"","full_name":"alandtse/alexa_media_player","last_commit":"2344bcf","last_updated":"2024-03-20T17:35:36Z","last_version":"v4.9.2","manifest_name":"Alexa Media Player","open_issues":20,"stargazers_count":1297,"topics":["alexa"],"last_fetched":1712096067.053028},"272094506":{"manifest":{"name":"Blitzortung.org Lightning Detector"},"description":"Custom Component for fetching lightning data from blitzortung.org","domain":"blitzortung","etag_releases":"W/\"d8b3b6ccea35bd190fde57e396c6a3acb994d986fcb9cd635d85a183d7fabdbf\"","etag_repository":"W/\"a5ea8e0dd7b5a5803cffa872d674ea75cd7348ffa3f120ad3ca89289df433aad\"","full_name":"mrk-its/homeassistant-blitzortung","last_commit":"3833c6c","last_updated":"2024-03-08T14:50:33Z","last_version":"v1.3.1","manifest_name":"Blitzortung","open_issues":29,"stargazers_count":162,"topics":["blitzortung","lightning-network"],"last_fetched":1712082088.705594},"183212377":{"manifest":{"name":"Spotcast"},"description":"Home assistant custom component to start Spotify playback on an idle chromecast device as well as control spotify connect devices","domain":"spotcast","etag_releases":"W/\"ef3b0d2379caebe2bfb6ad266283a4bfaa05371ee2f87f6b5f496b8648c1b532\"","etag_repository":"W/\"6d1f907c57a86902fd5824c14478f483ca02407c7f250ffc4bee94c7fc168580\"","full_name":"fondberg/spotcast","last_commit":"80fe472","last_updated":"2024-03-21T23:26:19Z","last_version":"v3.7.3","manifest_name":"Spotcast","open_issues":39,"stargazers_count":627,"last_fetched":1712081925.197483},"408429126":{"manifest":{"name":"MQTT DiscoveryStream"},"description":"Extension of HA mqtt_statestream integration with discovery config publishing","domain":"mqtt_discoverystream","etag_releases":"W/\"5473d087611848c075a03f56dd66d1d5ca46f9c8a4d444d9e7b20ac13a995798\"","etag_repository":"W/\"aa933e7dc973a859afea3f6869aa31c4f6f4ec04f16a2f2ea675d220f9010916\"","full_name":"koying/mqtt_discoverystream_ha","last_commit":"f264356","last_updated":"2024-03-13T14:45:45Z","last_version":"v1.0","manifest_name":"MQTT Discoverystream","open_issues":5,"stargazers_count":8,"topics":["mqtt"],"last_fetched":1710348465.328594},"694160639":{"manifest":{"name":"Ryanair"},"description":"Ryanair Home Assistant Integration ","domain":"ryanair","etag_releases":"W/\"3c2a2b5e4b55310dbe2429a3d8738e02e4afeca5352173b6dd1f0eae6c924f51\"","etag_repository":"W/\"8a1f49734925a290d993a5aaa88a112b1e51e6be5124a49e73aa4cfffdf08078\"","full_name":"jampez77/Ryanair","last_commit":"c1f333f","last_updated":"2024-01-01T17:49:06Z","last_version":"2023.12.0","manifest_name":"Ryanair","open_issues":10,"stargazers_count":3,"topics":["ryanair"],"last_fetched":1711491379.027829},"143340728":{"manifest":{"country":["NL"],"name":"ATAG One"},"description":"Atag One Custom components for Home-Assistant","domain":"atagone","etag_releases":"W/\"e416ca85b756f4ffdbea563b922a1780795d3c12bd45e2d22c5096033970abb7\"","etag_repository":"W/\"a15991552052a0dcf09a58783ce56b609339afce9b4a287e43341f75f0dc7cb0\"","full_name":"herikw/home-assistant-custom-components","last_commit":"cd9a1ad","last_updated":"2024-01-03T22:16:58Z","last_version":"v3.0.7","manifest_name":"ATAG One","open_issues":3,"stargazers_count":11,"topics":["atag","thermostat"],"last_fetched":1705422027.404805},"262854926":{"manifest":{"name":"Meteobridge Datalogger Integration"},"description":"The Meteobridge Integration adds support for retrieving current weather data from a Meteobridge datalogger connected to a local Weather Station.","domain":"meteobridge","etag_releases":"W/\"ef7bd886a5d2fc220471ad5cb11edc44f54d7fde4ed017f0d8787087bd9f0a00\"","etag_repository":"W/\"8a948a8a04acbaa32171f1599238d02185bf1a44960f18f4d5c76a67c4c6ef5a\"","full_name":"briis/meteobridge","last_commit":"df5365a","last_updated":"2023-02-24T16:31:12Z","last_version":"v3.3.4","manifest_name":"Meteobridge Datalogger","open_issues":5,"stargazers_count":10,"topics":["meteobridge"],"last_fetched":1711390665.946145},"497924778":{"manifest":{"name":"elkbledom"},"description":"Home Assistant custom component for LED STRIP NAME ELK BLEDOM","domain":"elkbledom","etag_releases":"W/\"12c1e99e5ef1891046b7048d0be51d186793b2f7e4c9d6cec9e95b488fedd41f\"","etag_repository":"W/\"25901815a2750170b040054599202ea82459199de242b079633acb981e9fffe6\"","full_name":"dave-code-ruiz/elkbledom","last_commit":"29bc39c","last_updated":"2024-01-15T08:25:18Z","last_version":"1.1.6","manifest_name":"ElkBLEDOM","open_issues":5,"stargazers_count":59,"topics":["hacs-custom","led-controller","ledstrips","light"],"last_fetched":1712204344.857136},"227452940":{"manifest":{"name":"Wyze"},"description":"Home Assistant Integration for Wyze devices.","domain":"wyzeapi","etag_releases":"W/\"dec90e57de86a10970d5368270b5c3b747af763bde223adf42f895808c7def87\"","etag_repository":"W/\"1c0f662d8244d1e9cf7c0f5ca320062c918f7e9c88e672f93095ce266973e608\"","full_name":"SecKatie/ha-wyzeapi","last_commit":"ba3438e","last_updated":"2024-03-22T00:18:58Z","last_version":"0.1.24","manifest_name":"Wyze","open_issues":8,"stargazers_count":682,"topics":["bulb","switch","wyze","wyze-bulbs","wyze-switchs"],"last_fetched":1712106107.283087},"319744131":{"manifest":{"name":"TapHome"},"description":"TapHome integration into Home Assistant.","domain":"taphome","etag_repository":"W/\"975110bd74eda94bb890567401003fb890479c4f4b06b12562a6d9dff6305685\"","full_name":"martindybal/taphome-homeassistant","last_commit":"3cb6ca8","last_updated":"2024-03-26T07:42:48Z","manifest_name":"TapHome","open_issues":4,"stargazers_count":8,"topics":["taphome"],"last_fetched":1711448386.039414},"582268944":{"manifest":{"name":"EPEX Spot"},"description":"Adds EPEX Spot data to Home Assistant.","domain":"epex_spot","etag_releases":"W/\"9e92dcb8f86f168b407de60ebc0575ab6af536bb7e56e59cf7686ba4b4cc6ca4\"","etag_repository":"W/\"e4f4f616414fd7e8d79e045296105d7679b32ea86ecbc03b60a4058485eb6cf5\"","full_name":"mampfes/ha_epex_spot","last_commit":"91a3490","last_updated":"2024-03-15T19:28:39Z","last_version":"2.3.5","manifest_name":"EPEX Spot","open_issues":1,"stargazers_count":98,"topics":["awattar","energy-prices","epex","epex-spot","smard","smartenergy","tibber"],"last_fetched":1712074911.798094},"686741369":{"manifest":{"country":["ES"],"name":"Espa\u00f1a - UFD Distribuci\u00f3n Electricidad"},"description":"Importa en el panel de energ\u00eda el consumo y coste de electricidad desde ufd.es y ree.es. Calcula las facturas desde cnmc.gob.es.","domain":"pvpc_energy","etag_releases":"W/\"6694eaa71cbce2c00a5b8c06d0024b5aabf9d5f03ccb1dbb0fe61236e76b6b28\"","etag_repository":"W/\"a4138c1650cdf71500b233d8a2300a90c89a0c2826bbebc889af3bf8fedcba65\"","full_name":"yinyang17/pvpc_energy","last_commit":"d0a5984","last_updated":"2024-03-18T06:50:05Z","last_version":"v0.2.1","manifest_name":"PVPC Energy","open_issues":3,"stargazers_count":7,"topics":["billing","electricity-consumption","energy-dashboard","pvpc"],"last_fetched":1712075086.894407},"544947025":{"manifest":{"name":"Chargecloud.de"},"description":"Fetches real-time status of public ev chargers from chargecloud.de","domain":"chargecloud","etag_releases":"W/\"870d436972a20d7ef30b1079a2025eaef9179aad4fa9afc73ac92e07ccb13c64\"","etag_repository":"W/\"8d964192bb0323aef922c428d6addb21ab4350286c89a2e6d568bc430c406b90\"","full_name":"functionpointer/home-assistant-chargecloud-integration","last_commit":"eb77c38","last_updated":"2024-03-15T00:17:37Z","last_version":"v1.2.3","manifest_name":"chargecloud","open_issues":2,"stargazers_count":4,"topics":["electric-vehicle-charging-station","electric-vehicles"],"last_fetched":1710469341.196367},"479221839":{"manifest":{"name":"Swatch"},"description":"HomeAssistant Integration For Swatch: Color detection in images to capture presense of known objects.","domain":"swatch","etag_releases":"W/\"2f18d067db95df1f5e460092ad81759c678a6d05f31e316248161218782fc1b8\"","etag_repository":"W/\"fd68a90bc0f80e401ae5ca14f1be950f9806be79ff412da3e61c071f0bd31560\"","full_name":"NickM-27/swatch-hass-integration","last_commit":"5cdc583","last_updated":"2024-02-03T13:11:22Z","last_version":"1.1.3","manifest_name":"Swatch","open_issues":2,"stargazers_count":13,"topics":["ai","camera","home-assistant-integration","object-detection","opencv"],"last_fetched":1711981123.641841},"197983504":{"manifest":{},"description":"Support for Denkovi IOT Relay modules in HomeAssistant","domain":"denkovi","etag_releases":"W/\"506d097ec58e7fdb962cb7756badcb21303fdc5886626f4cf1575c79a64bbeb2\"","etag_repository":"W/\"73bed6efc8ce63a4d8dcc45d8768ab1fb3fd0ebd545f0f49547dbeb422de23a6\"","full_name":"rdehuyss/homeassistant-custom_components-denkovi","last_commit":"16d3384","last_updated":"2022-01-04T15:00:15Z","last_version":"v2.0.2","manifest_name":"Denkovi","stargazers_count":5,"topics":["denkovi"],"last_fetched":1678379727.658926},"279861920":{"manifest":{"name":"Reverso TTS / tts"},"description":"ReversoTTS component for HomeAssistant","domain":"reversotts","etag_releases":"W/\"33d72aad00712bce72284e59a1acc47a090e16e7d34f1e974c827d7aedf13bcb\"","etag_repository":"W/\"b57e659c94001ff8e1acfad564100182156a6b9f8780c076eda6cbabae5bf15b\"","full_name":"rt400/ReversoTTS-HA","last_commit":"30d4c26","last_updated":"2021-05-23T17:14:46Z","last_version":"1.0.2","manifest_name":"Reverso TTS","open_issues":1,"stargazers_count":39,"topics":["reversotts","tts"],"last_fetched":1705194600.369625},"332651510":{"manifest":{"name":"Baby Buddy"},"description":"This custom integration provides sensors for Baby Buddy API endpoints.","downloads":4,"domain":"babybuddy","etag_releases":"W/\"33e8c461012e82fdc283577492a8bcd759f3c2d0decbee54ff8ae335b3c8129d\"","etag_repository":"W/\"f6b675df4a8f6d6015c72a0035c13a2ad0c1c46ad12cb081d0cc12f4b9bda45c\"","full_name":"jcgoette/baby_buddy_homeassistant","last_commit":"8b0980a","last_updated":"2023-12-17T02:13:55Z","last_version":"v2.7.2","manifest_name":"Baby Buddy","open_issues":15,"stargazers_count":57,"topics":["baby","home-assistant-component","parents"],"last_fetched":1711995576.684663},"299967654":{"manifest":{"name":"HiFiBerry"},"description":"This is a custom component to allow control of HifiberryOS devices in Home Assistant using the audiocontrol2 REST API.","domain":"hifiberry","etag_repository":"W/\"68732329e3aebe7b9a4cbcbecb6a685168b294c59181fdaff4e0f560539549f1\"","full_name":"willholdoway/hifiberry","last_commit":"1f0a3be","last_updated":"2023-10-07T12:08:20Z","manifest_name":"HiFiBerry","open_issues":7,"stargazers_count":43,"topics":["hifiberry","internet-of-things","iot"],"last_fetched":1708021482.054293},"266595512":{"manifest":{"name":"Casambi"},"description":"Home assistant Integration for Casambi Cloud lights","domain":"casambi","etag_releases":"W/\"e43bfac8e3621ba1f2cdd8a5fb94920fd9e9b94ed718689f3d4a9853a8c3b77d\"","etag_repository":"W/\"7519ff88dfff3b0e5361e6cc3bde3acac4d645a714d236142daa57b2bde21148\"","full_name":"hellqvio86/home_assistant_casambi","last_commit":"8f85ea4","last_updated":"2024-01-30T16:05:48Z","last_version":"v0.127","manifest_name":"casambi","open_issues":1,"stargazers_count":24,"topics":["casambi"],"last_fetched":1711016196.838729},"698694783":{"manifest":{"name":"Davis Vantage"},"description":"Davis Vantage custom component integration for Home Assistant","domain":"davis_vantage","etag_releases":"W/\"cd1404163a97485ed30a7801c60efcf5c80057125a87c784d4e18b3dd1e28eab\"","etag_repository":"W/\"629096c0386b76df21695875d2d2c4871f8e7a155f357d89ffd5703012a4777b\"","full_name":"MarcoGos/davis_vantage","last_commit":"43e6647","last_updated":"2024-03-07T19:47:24Z","last_version":"v1.1.13","manifest_name":"Davis Vantage","open_issues":1,"stargazers_count":5,"topics":["davis-weatherlink","weather-station"],"last_fetched":1711347734.528417},"271398374":{"manifest":{"name":"Saver"},"description":"This custom component allows you to save current state of any entity and use its data later to restore it.","downloads":1488,"domain":"saver","etag_releases":"W/\"5bcbdf34752af0977e89ba279614b02be9ec789428bd0663880ead6822e087cf\"","etag_repository":"W/\"c694a367102274849e015c6776a23e6916191c02e45002253b8102b6cb146902\"","full_name":"PiotrMachowski/Home-Assistant-custom-components-Saver","last_commit":"f6f4de7","last_updated":"2023-09-30T21:12:14Z","last_version":"v1.2.1","manifest_name":"Saver","open_issues":2,"stargazers_count":59,"topics":["automation","helper","save","script","variable"],"last_fetched":1711822964.208676},"166045890":{"manifest":{},"description":"Provides Home Assistant sensors for multiple Dutch and Belgium waste collectors","domain":"afvalbeheer","etag_releases":"W/\"ce9347dd79cd9da4d1256a959390721f9fc5af0570432c4a3d88f01c9b0ebdff\"","etag_repository":"W/\"2932ff460fc2d46f5b05a4a73862e7a41120fc3b743875fd28f2eb74d12bc296\"","full_name":"pippyn/Home-Assistant-Sensor-Afvalbeheer","last_commit":"4660b93","last_updated":"2024-03-25T10:11:18Z","last_version":"v5.3.2","manifest_name":"Afvalbeheer","open_issues":18,"stargazers_count":251,"topics":["belgium","dutch","hassio-integration","waste-collectors"],"last_fetched":1711995740.5793},"237102126":{"manifest":{"country":["PL"],"name":"Warsaw ZTM Information"},"description":"Home Assistant (hass.io) custom component for Warsaw public transport","domain":"ztm","etag_releases":"W/\"c0d3723638d798ce565d978000ef4b58c7ddeba5be1575f291baa5c2290422ad\"","etag_repository":"W/\"16dd460483819f0bbb486671a4a78d2f52ec855068e6b4eabee8c393f8dcf3f2\"","full_name":"peetereczek/ztm","last_commit":"2d4c148","last_updated":"2024-03-17T21:20:33Z","last_version":"0.2.2","manifest_name":"Warsaw ZTM Information","open_issues":1,"stargazers_count":10,"last_fetched":1712161306.385783},"357930725":{"manifest":{"name":"Shinobi Video NVR"},"description":"Shinobi Video custom component for HA","domain":"shinobi","etag_releases":"W/\"ee53cd4ae67f44e23862652e90c97424f61cb84123102c26c51fc51167558361\"","etag_repository":"W/\"7d572c65c67659411bf220743714c65050c71a748400f5541ad1b0b8cea29dc5\"","full_name":"elad-bar/ha-shinobi","last_commit":"b11c780","last_updated":"2023-12-30T09:00:01Z","last_version":"v3.0.7","manifest_name":"Shinobi Video NVR","open_issues":2,"stargazers_count":48,"topics":["shinobi"],"last_fetched":1710649050.788524},"517783998":{"manifest":{"name":"Termux API integration"},"description":"Getting information about Android system via Termux:API","domain":"termux_api","etag_releases":"W/\"b3ec1cb7bee8888e5e07e8d5ef333e9748a2a3f23886bc40796d509333edf0fc\"","etag_repository":"W/\"a5374c9b82409e72b748a1fc1632177e9159280469160bd10148d616467ceea7\"","full_name":"Vova-SH/termux-api","last_commit":"4793082","last_updated":"2024-02-19T18:34:00Z","last_version":"v1.0.1","manifest_name":"Termux API integration","stargazers_count":4,"topics":["android","termux","termux-api"],"last_fetched":1708950670.4923},"291157903":{"manifest":{"name":"RRD Recorder"},"description":"RRD Custom Component for Home Assistant","domain":"rrd_recorder","etag_releases":"W/\"69f6612aca33dc3cdac824f6452431fe24528f5848138826e669bbdede78c065\"","etag_repository":"W/\"eb4984b94c8dc5477c4acd6e327350f70a07e46ee6443883102370db87fc958e\"","full_name":"dgomes/ha_rrd_recorder","last_commit":"34eab1e","last_updated":"2024-03-30T22:09:50Z","last_version":"0.2.0","manifest_name":"RRD Recorder","open_issues":4,"stargazers_count":11,"topics":["home-assistant-component","rrdtool"],"last_fetched":1711846927.792294},"568434741":{"manifest":{"name":"ha_heliotherm"},"description":"Home Assistant Custom Component for Heliotherm Heatpumps","downloads":1,"domain":"ha_heliotherm","etag_releases":"W/\"3195d6154fd69cee390ed5cf9b03abf42708f969029bb0a8f4a24d5d8165d61e\"","etag_repository":"W/\"bd2fbe153a3ba7c9f2fa778981128b883ca15d4607a87840533806c97ba5eaf0\"","full_name":"mbuchber/ha_heliotherm","last_commit":"b6ac1de","last_updated":"2024-03-31T10:59:21Z","last_version":"v1.0.24","manifest_name":"HaHeliotherm","open_issues":2,"stargazers_count":12,"topics":["heatpump","heliotherm","homeassistant-custom-component"],"last_fetched":1711887986.504734},"483269510":{"manifest":{"name":"OilFox Sensor"},"description":"HomeAssistant Sensor for Oilfox ","domain":"oilfox","etag_releases":"W/\"764b284ac0357f9083c67244e3477176dd8912a216e74690adbad5c413c2a06b\"","etag_repository":"W/\"5db9c57b38e0ecd009441a742fa36298330306f7c2483c4dd57af7fc42b9e27a\"","full_name":"chises/ha-oilfox","last_commit":"561e10c","last_updated":"2024-03-10T11:37:46Z","last_version":"v1.1.0","manifest_name":"OilFox","open_issues":2,"stargazers_count":27,"topics":["homeassistant-custom-component","oiflox"],"last_fetched":1710800017.032083},"580152298":{"manifest":{"name":"Polar"},"description":"Polar integration for Home Assistant","domain":"polar","etag_releases":"W/\"e5ff7ece75076d2c19f2237e0c824ec7ed6b1d2e1db2042e929adddb5482dbff\"","etag_repository":"W/\"57ec2de3f28a334d030b898337a4b61dfd9db3f7e9c1c995220150d243528851\"","full_name":"Aohzan/hass-polar","last_commit":"a891e75","last_updated":"2023-08-08T18:15:38Z","last_version":"1.2.1","manifest_name":"Polar","stargazers_count":11,"topics":["home-assistant-integration","polar","polar-accesslink","polar-electro"],"last_fetched":1705241506.985767},"717185121":{"manifest":{"name":"Amazon CloudWatch"},"description":"A Home Assistant custom component to send values directly to Amazon CloudWatch.","downloads":34,"domain":"amazon_cloudwatch","etag_releases":"W/\"554b6174f017d82c2d1e74be9d789dd27c0fddc2b3d74e2a4d7b6fb77341defa\"","etag_repository":"W/\"1295fd1965055f9900bd497d602ec12aaf094a4bc2abddb9cf851333d8c96fb8\"","full_name":"Mallonbacka/custom-component-cloudwatch","last_commit":"5b36403","last_updated":"2024-04-01T14:11:42Z","last_version":"v1.1.1","manifest_name":"Amazon CloudWatch","topics":["aws","cloudwatch","metrics"],"last_fetched":1711981069.49673},"560307075":{"manifest":{"country":["DK"],"name":"Aula"},"description":"Fetches information from Aula about your children ","downloads":533,"domain":"aula","etag_releases":"W/\"210213b364053f876d9a64c2f4e6dba42cd526835a4c40bcd2b9d1fbc0ecbed3\"","etag_repository":"W/\"7916ca60143aa4b9b8a8c95f7b8c899c979e193a12269cb4e405e5e553f11ae3\"","full_name":"scaarup/aula","last_commit":"be754cb","last_updated":"2024-04-04T04:06:40Z","last_version":"v0.1.37","manifest_name":"Aula","open_issues":15,"stargazers_count":46,"last_fetched":1712219041.067511},"297379398":{"manifest":{"name":"Tractive"},"description":"Custom component for Tractive","domain":"tractive_custom","etag_releases":"W/\"a07db54e19f16c459bea97e188eff248ca04a31f3c6f74f00e9090db0a6115e6\"","etag_repository":"W/\"68cb511b44c48bdac9545b1b8285e310f5b9f1fda2e9b0d5cc83ec2ac07cd131\"","full_name":"Danielhiversen/home_assistant_tractive","last_commit":"1c85a48","last_updated":"2021-12-20T09:30:02Z","last_version":"0.3.1","manifest_name":"Tractive Custom","stargazers_count":34,"topics":["tractive"],"last_fetched":1705479558.21351},"374314958":{"manifest":{"name":"ABB Power-One PVI SunSpec"},"description":"HA Custom Component to integrate data from ABB/Power-One/FIMER PV Inverters that support SunSpec Modbus (Sunspec M1, M101, M103, M160), natively or through the VSN300 wifi logger card.","downloads":287,"domain":"abb_powerone_pvi_sunspec","etag_releases":"W/\"201e8f426821b521fffaac6b2e944d386142540bd29af2e4dfcb1eda6ebd6523\"","etag_repository":"W/\"f78c4835940a7cc5250b502e7eb01575c23ea3a4d5dd45954c3d27763b5607b2\"","full_name":"alexdelprete/ha-abb-powerone-pvi-sunspec","last_commit":"cb14a66","last_updated":"2024-04-01T21:24:51Z","last_version":"v3.4.1","manifest_name":"ABB Power-One PVI SunSpec","open_issues":4,"stargazers_count":23,"topics":["abb","fimer","home-assistant-component","inverter","modbus","modbus-tcp","power-one","sunspec"],"last_fetched":1712009568.614346},"325962977":{"manifest":{"name":"EMSC Earthquake RSS Feed"},"description":"EMSC Home Assistant Integration","domain":"emscrss","etag_repository":"W/\"7bdbf062cb6516011e48d06be0fb7c51e2f780244aa56765d1a35411ff7fce82\"","full_name":"msekoranja/emsc-hacs-repository","last_commit":"3248bde","last_updated":"2024-04-02T11:09:26Z","manifest_name":"EMSC Earthquake RSS Feed","open_issues":3,"stargazers_count":4,"last_fetched":1712060991.966602},"200035037":{"manifest":{"name":"Discord Game"},"description":"Home Assistant custom component to get online and game status of Discord users","domain":"discord_game","etag_releases":"W/\"3ab600cec1f4e0afa0ca56489573385637da29e81002e568b56f7b502af68469\"","etag_repository":"W/\"32e5752fa92778482eb0fedba3f5272b422dbe792111f33cfc3d0bb0f7056cb3\"","full_name":"LordBoos/discord_game","last_commit":"89b34fb","last_updated":"2023-11-29T16:31:20Z","last_version":"5.0.4","manifest_name":"Discord Game","open_issues":3,"stargazers_count":53,"last_fetched":1711743534.912583},"589771870":{"manifest":{"country":["BE","NL"],"name":"Youfone"},"description":"Youfone Home Assistant custom component HACS to get Youfone mobile phone subscription and usage details for Belgium and Netherlands.","domain":"youfone_be","etag_releases":"W/\"5fd1f5294f53cbca2b9f2cfebf9c173d27faec6e52356a7c1d5f0eeb0ead566d\"","etag_repository":"W/\"24d0f425c7c28578edd9fee55fd5a3b0dfd0998484ba1fa2ec1d13009b1856f7\"","full_name":"myTselection/youfone_be","last_commit":"57ec0b0","last_updated":"2024-03-10T12:25:52Z","last_version":"4.5.0","manifest_name":"Youfone.be","open_issues":1,"stargazers_count":3,"topics":["youfone"],"last_fetched":1710080249.089363},"365332200":{"manifest":{"country":["US","FR","ES","DE"],"name":"PiJuice UPS Hat"},"description":"Home Assistant integration to support PiJuice UPS Hat and retrieve values to sensors.","domain":"pijuice","etag_releases":"W/\"120216551357adaceed772d300010e22b215d4367014de7f9e2dac602713f28d\"","etag_repository":"W/\"03c13d9313941e0e6f26bbb10b2bfb5ada45515868a4586cea26c1bebb15aeb9\"","full_name":"Racailloux/home-assistant-pijuice","last_commit":"cc07e57","last_updated":"2024-01-20T08:03:38Z","last_version":"1.2.5","manifest_name":"PiJuice UPS HAT","open_issues":2,"stargazers_count":14,"topics":["battery","hat","integrations","pijuice","raspberry-pi","sensors","ups","voltage"],"last_fetched":1711405158.968416}} ================================================ FILE: tests/fixtures/v2-plugin-data.json ================================================ {"214792276":{"manifest":{"name":"Xiaomi Fan Lovelace Card"},"description":"Xiaomi Smartmi Fan Lovelace card for HASS/Home Assistant.","etag_releases":"W/\"2642ad4a3b1d9d1cf19b748c18ec5716707efe487b7247f88747c602d3843c96\"","etag_repository":"W/\"9455804239da4e263cf8a68a91bbde60fb99a7a33516edfa1cc644e2260a737d\"","full_name":"fineemb/lovelace-fan-xiaomi","last_commit":"9697d45","last_updated":"2022-06-06T14:18:26Z","last_version":"v1.3.5","open_issues":2,"stargazers_count":40,"last_fetched":1709612158.530956},"236945951":{"manifest":{},"description":"Graph of Buienradars rain forecast ","downloads":4102,"etag_releases":"W/\"437ef3479505ffd52695348c0f2bf753d0002109cbd45a8702c6d9b00d962729\"","etag_repository":"W/\"9bdd2b2d6a61db0d7d97f07cab928783e6332d7eb2c10de22159de2f9b6aaf02\"","full_name":"lukevink/lovelace-buien-rain-card","last_commit":"5300def","last_updated":"2022-11-09T07:37:14Z","last_version":"0.0.4","open_issues":14,"stargazers_count":52,"topics":["buienradar","chartjs","forecast","graph"],"last_fetched":1710173814.39993},"231674882":{"manifest":{"name":"template-entity-row"},"description":"\ud83d\udd39 Display whatever you want in an entities card row.","etag_releases":"W/\"fcbd56cb2497761a238e0261df342416b8c8072e54bd575bd90fd0a133357234\"","etag_repository":"W/\"bfc1995231ca7a96ba8f0525370705649dc48d7ac36e188c2919c17e0581967f\"","full_name":"thomasloven/lovelace-template-entity-row","last_commit":"c225304","last_updated":"2024-02-12T09:12:04Z","last_version":"v1.4.1","open_issues":15,"stargazers_count":196,"last_fetched":1711484153.245469},"197715418":{"manifest":{},"description":"A Home Assistant Lovelace card to report MiFlora plant sensors based on the HA Plant Card.","etag_releases":"W/\"1ccfa36cd797f4486bc5755842d238572a601c9d3341ded424bf4eb39287179b\"","etag_repository":"W/\"e30805b7172b3e3cb07438bf94a40a479277aee99f58fd3f72744229f2d9ea7f\"","full_name":"RodBr/miflora-card","last_commit":"889ee81","last_updated":"2023-04-16T12:17:24Z","last_version":"0.1.0","open_issues":17,"stargazers_count":21,"last_fetched":1712009692.907468},"273007955":{"manifest":{"name":"Power Usage Card with Regular Expressions"},"description":"Lovelace pie chart card that displays current energy usage","etag_repository":"W/\"6bbeabd783c434f9810d03bd401ee7d1c49aa7856642d14dd80ff63f6602aa22\"","full_name":"DBa2016/power-usage-card-regex","last_commit":"cf6d4cd","last_updated":"2022-07-26T02:31:34Z","open_issues":5,"stargazers_count":9,"topics":["lovelace-custom-card","power-usage"],"last_fetched":1711743243.919619},"392931946":{"manifest":{"name":"Aria2 card"},"description":"An aria2 card for home assistant","downloads":342,"etag_releases":"W/\"b5890f01aa4cd1b0b1fae8dda3a6076448c2b723dc72a99ce0752edef7084846\"","etag_repository":"W/\"72b08154565d2ad87cb7f656beb11c45f830047958052ef7a284cea4b308239c\"","full_name":"deblockt/aria2-card","last_commit":"4d60360","last_updated":"2022-09-20T13:30:10Z","last_version":"0.1.0","open_issues":1,"stargazers_count":4,"topics":["aria2","download-manager"],"last_fetched":1699446216.353418},"329411371":{"manifest":{"name":"HA Dashboard"},"description":"A custom dashboard for Home Assistant with sidebar","downloads":3431,"etag_releases":"W/\"df67cb81198bbe5b3ebb7823d1210c2a77b80d69ed7701299d8a61f99bf78e67\"","etag_repository":"W/\"fb4c92fbcf85087465845c6952d9f5a1721e2abc90d0c8b347f06a862578c58e\"","full_name":"wassy92x/lovelace-ha-dashboard","last_commit":"c1e02e8","last_updated":"2023-04-27T09:59:32Z","last_version":"v1.1.2","open_issues":9,"stargazers_count":27,"last_fetched":1709864503.363976},"498794033":{"manifest":{"name":"Slider Button Card"},"description":"A button card with integrated slider","downloads":23363,"etag_releases":"W/\"1c34ac927129443193551e95f3d1fed385b952091c7b6d229a0977ac485d034b\"","etag_repository":"W/\"140bd48180e1e06acd49742d48fe3b3bd8d7e8e3cf63fc83bdfd26d6d7ad4eec\"","full_name":"custom-cards/slider-button-card","last_commit":"bfa9081","last_updated":"2023-10-17T04:02:06Z","last_version":"v1.13.0","open_issues":30,"stargazers_count":99,"topics":["button-card","card","lovelace-custom-card","slider"],"last_fetched":1711836768.917116},"236317072":{"manifest":{"name":"Pie Chart Card"},"description":"Generalized Lovelace pie chart card","etag_repository":"W/\"03a3e8f4f6c84c980dfc6d2b9e71dcf2ef2175a84e904541886d2ede11368c10\"","full_name":"sdelliot/pie-chart-card","last_commit":"03a951f","last_updated":"2020-03-07T21:19:19Z","stargazers_count":12,"last_fetched":1711743350.356347},"376904517":{"manifest":{"name":"Timer Bar Card"},"description":"A progress bar display for Home Assistant timers","downloads":12966,"etag_releases":"W/\"59b8130868807586fba0d10a8b46a8cf7a0080de61dde9acbcca3364c111dea7\"","etag_repository":"W/\"37b36c7c26e0e01fab000e0fe7efd30de86c0c330a3b1cf78f39bd305e3a6c30\"","full_name":"rianadon/timer-bar-card","last_commit":"a24cb42","last_updated":"2024-04-01T17:34:52Z","last_version":"v1.30.0","open_issues":40,"stargazers_count":304,"last_fetched":1712175421.734659},"286860710":{"manifest":{"name":"Cover Position Preset Row"},"description":"Plug-in for Home Assistant that provides an easy means to set 3 fixed positions for a programmable cover entity.","etag_releases":"W/\"e1c44ab8a1010b55b8dc57579cf5f0800a327e0ff7a41ce14ec7e53dab48361f\"","etag_repository":"W/\"9a4b891003efb7e4575204795facb93e136e8a0dd037a495c28402fc7b084e28\"","full_name":"finity69x2/cover-position-preset-row","last_commit":"4b1215c","last_updated":"2024-03-22T09:26:22Z","last_version":"3.2","open_issues":2,"stargazers_count":20,"topics":["cover","lovelace-custom-card"],"last_fetched":1711102494.722382},"187245418":{"manifest":{"name":"bignumber-card"},"description":null,"etag_releases":"W/\"f05a39341d31fdd0a3a35b1d748bd97c41a8e0ce1c8fb6a27601a459c247104b\"","etag_repository":"W/\"1aee9c1212ef44db2fb7095c1e379b77942577a4e8c70a87448c3f962e22aae6\"","full_name":"custom-cards/bignumber-card","last_commit":"20f0911","last_updated":"2022-01-31T15:47:59Z","last_version":"0.0.6","open_issues":18,"stargazers_count":110,"last_fetched":1709388673.840096},"296396632":{"manifest":{"country":["DK"],"name":"Rejseplanen S-Tog Card"},"description":"Lovelace card for listing departures from Rejseplanen sensors, in the style of S-Tog departure boards.","etag_releases":"W/\"9a0f6572d977c86e2984cf132d43804a68cfe29bd024acd0f1a803ff7cb07ead\"","etag_repository":"W/\"25831987f3fbbf6b48294e02274b8d23cd3d0ef93e6f6983a2dbe19d31f453bb\"","full_name":"DarkFox/rejseplanen-stog-card","last_commit":"a182b83","last_updated":"2023-01-06T14:35:56Z","last_version":"1.5.0","open_issues":2,"stargazers_count":5,"topics":["denmark","lovelace-card","rejseplanen","rejseplanen-sensors"],"last_fetched":1706144411.553258},"179491130":{"manifest":{},"description":"A group element for picture-elements with dynamic toggle capability","downloads":1467,"etag_releases":"W/\"25ba3be4ebfe2a4b894d7547d5fe361c8b03ab4daa60ad330fd234784f29948a\"","etag_repository":"W/\"cbed02f3aa61440772b9a38acd031db072d925dee48f0c8d68cb9b6fa400affb\"","full_name":"custom-cards/group-element","last_commit":"cd973e2","last_updated":"2023-02-16T13:58:24Z","last_version":"0.9.2","stargazers_count":60,"last_fetched":1709288021.77514},"257102434":{"manifest":{"name":"FKF Budapest Garbage Collection Card"},"description":"FKF Budapest Garbage Collection Card for Home Assistant/Lovelace","downloads":525,"etag_releases":"W/\"735fc99e6adcf961bdb8df02afc57fab574cc0624072dece78d668e801f09db8\"","etag_repository":"W/\"122e4b7ec8b6ec8d282774200b0ce3d5c36d1eca385625ae3c60d0d87961c6be\"","full_name":"amaximus/fkf-garbage-collection-card","last_commit":"419fc74","last_updated":"2022-09-16T08:09:59Z","last_version":"0.9.0","stargazers_count":10,"topics":["budapest","hungary","lovelace-custom-card"],"last_fetched":1704917650.499152},"156434866":{"manifest":{"name":"layout-card"},"description":"\ud83d\udd39 Get more control over the placement of lovelace cards.","etag_releases":"W/\"f414bcadd16b4b90d823b62fd4abbde086ad9e46c4a6b5a2a591d750516b9c9c\"","etag_repository":"W/\"a20db38e6816fdb873027859c4b32f107fe6fd31cee4393d9a279d6aebf2751a\"","full_name":"thomasloven/lovelace-layout-card","last_commit":"16d834f","last_updated":"2024-03-20T11:35:38Z","last_version":"v2.4.5","open_issues":84,"stargazers_count":958,"last_fetched":1712211511.477279},"249942054":{"manifest":{"name":"hui-element"},"description":"\ud83d\udd39 Use built-in elements in the wrong place","etag_repository":"W/\"59d3ab01c284eca7a2141165ed7e39af8e092d9382e1a8d75712cad44fd8e8f4\"","full_name":"thomasloven/lovelace-hui-element","last_commit":"1a80547","last_updated":"2023-11-22T21:08:49Z","open_issues":3,"stargazers_count":98,"last_fetched":1711491277.563718},"268163975":{"manifest":{"name":"mini climate card"},"description":"Minimalistic climate card for Home Assistant Lovelace UI","downloads":70,"etag_releases":"W/\"0dcedb14c5f12b3a2ab27d1b4de0162bacc9632938d9cce5ebcacbcc17ccc2f3\"","etag_repository":"W/\"28be98070771936b632fa9d37069f0e29c9ce31ea2a752546064be7fb7e8bd36\"","full_name":"artem-sedykh/mini-climate-card","last_commit":"2b37f13","last_updated":"2024-04-01T08:13:35Z","last_version":"v2.7.2","open_issues":29,"stargazers_count":255,"topics":["automation","climate","climate-entity","custom","hacktoberfest2021"],"last_fetched":1711966462.507106},"248954055":{"manifest":{"name":"Stack In Card"},"description":"\ud83d\udee0 group multiple cards into one card without the borders","downloads":79144,"etag_releases":"W/\"b129f652acbd570887b8d5fd756e1d3bd1734ecfe08516acf51446d7b5a1a463\"","etag_repository":"W/\"bb2168468172297b51a389ce5067d1d74b7e47e4a116821aa99cd497dee2da2c\"","full_name":"custom-cards/stack-in-card","last_commit":"6d8401d","last_updated":"2024-04-02T20:01:27Z","last_version":"0.2.0","open_issues":46,"stargazers_count":247,"last_fetched":1712088797.539355},"492996183":{"manifest":{"name":"Hue-Like Light Card"},"description":"This card provides a Hue-like way to control your lights in Home Assistant.","downloads":6835,"etag_releases":"W/\"2e3f93c3185541e08aa34a65acf4293e0f000174557c68906a84e77f9f1fc42a\"","etag_repository":"W/\"6fa6f5feccc5c6fd6fe83684a63b54b3b084e73f1fb905fd5f58c94783ee7648\"","full_name":"Gh61/lovelace-hue-like-light-card","last_commit":"17ef0c4","last_updated":"2024-04-01T06:02:04Z","last_version":"v1.6.1","open_issues":21,"stargazers_count":91,"topics":["hue","hue-lights-control","light","lovelace-card","rgb-lights"],"last_fetched":1712031373.965715},"237887092":{"manifest":{"name":"Climate thermostat card"},"description":"Thermostat Lovelace card","etag_releases":"W/\"4f73f765f7bb7637a7f2ffd3d298392529bab851cd927bf3b51280662e6349e9\"","etag_repository":"W/\"76a8570e1c40019a77a9d2f3d807ab0155cc15575afbf31b24d99e8bcb30800d\"","full_name":"fineemb/lovelace-thermostat-card","last_commit":"f95cd32","last_updated":"2023-04-14T11:01:13Z","last_version":"v1.3.0","open_issues":18,"stargazers_count":106,"last_fetched":1712081877.644692},"638230244":{"manifest":{"name":"Energy Flow Card Plus"},"description":"An upgraded Energy Distribution Card for Home Assistant, with added features like Individual Devices and refined UI enhancements, while maintaining the Energy Dashboard's original design.","downloads":13479,"etag_releases":"W/\"36c0404481f2b9224e2eb0307c476f64aa3b4aa78ac3d97a244226d9621ad188\"","etag_repository":"W/\"4e0c2d88d1ce2d4f51c717b9494fc31c79c918b3a9f079268f274bac03736051\"","full_name":"flixlix/energy-flow-card-plus","last_commit":"c528d98","last_updated":"2023-10-19T02:51:26Z","last_version":"v0.1.2.1","open_issues":35,"stargazers_count":97,"topics":["automation","cards","customization","dashboard","diy","energy","green","renewable-energy","renewables","visualization"],"last_fetched":1712192216.309746},"708207040":{"manifest":{"name":"Twitch Followed Live Streams Card"},"description":"This card is for home assistant to see all your streamers that are currently live","etag_releases":"W/\"ddce89706c11c48d937a2e35cf8a3a040ed427674a84084a0b23a07efab58edd\"","etag_repository":"W/\"ce74a7bfc30c20d7c288ad55ca3fe33abfd1c103fb52f3de118637970a40f679\"","full_name":"stefmde/HomeAssistant-TwitchFollowedLiveStreamsCard","last_commit":"ae4ba87","last_updated":"2024-02-12T16:14:27Z","last_version":"v2.1.0","open_issues":2,"stargazers_count":6,"topics":["streams","twitch"],"last_fetched":1711909012.411446},"520644302":{"manifest":{"country":["FR"],"name":"TAM Card"},"description":"Montpellier Lovelace TAM card displays next two crossing times of the tramway or bus in Montpellier, France.","etag_releases":"W/\"02dc435a6b3aaf5ce10ec265644a022aeb8801ef6c919180967359d85e0f0d48\"","etag_repository":"W/\"bb1c693bc6b58eeb5699f3071816a9351c6fb314f2e187e9a683ee898a3b734d\"","full_name":"MathisAlepis/lovelace-tam-card","last_commit":"1da7287","last_updated":"2024-03-20T19:26:07Z","last_version":"v3","open_issues":2,"stargazers_count":8,"topics":["lovelace-custom-card","montpellier","public-transport","tam"],"last_fetched":1710965739.815935},"260940136":{"manifest":{"name":"HA (Lovelace) Card Weather Conditions"},"description":"Weather condition card (Lovelace) for Home Assistant.","etag_releases":"W/\"a5b414e5900b07cba40d0eb94d22aedb27f30bb2b45cce526a234b3a63172f8b\"","etag_repository":"W/\"125d2c128298d2bca17181d733cd93fab7fbbe0ae944c7a0fa596bd35ccea370\"","full_name":"r-renato/ha-card-weather-conditions","last_commit":"149b55e","last_updated":"2024-03-01T08:20:10Z","last_version":"1.9.14","open_issues":59,"stargazers_count":182,"topics":["card","weather-conditions"],"last_fetched":1711729070.418142},"488086721":{"manifest":{"name":"Platinum Weather Card"},"description":"This is a fully customisable weather card for Home Assistant with a graphical configuration.","downloads":19750,"etag_releases":"W/\"e6c7901a4a279af06d1dd03c788328cc320733886da41d67f9bddb6d93850435\"","etag_repository":"W/\"e5c0d70c7a902ed8b43f88181a615f9411921c4babbf10b61b9b012e83a849b7\"","full_name":"Makin-Things/platinum-weather-card","last_commit":"4c3d6b8","last_updated":"2024-02-29T13:46:16Z","last_version":"1.0.5","open_issues":38,"stargazers_count":123,"topics":["frontend","weather","weather-forecast"],"last_fetched":1712225695.681611},"313270182":{"manifest":{"name":"kibibit Frosted Cards"},"description":"Make Cards and Popups blur everything behind them.","etag_releases":"W/\"f59b9b20422493990e4fe5b5be0a6ff863aa4cd7c5fc83f768d27d97898330cb\"","etag_repository":"W/\"6249c8fa7d64c4598bd7626a14473a51ff1e58ab4f2aea39a9fb07c734b53503\"","full_name":"Kibibit/kb-frosted-cards","last_commit":"5e1586e","last_updated":"2022-06-19T17:40:45Z","last_version":"v1.3.1","open_issues":7,"stargazers_count":9,"topics":["effect","frosted-glass"],"last_fetched":1704903531.236242},"245239101":{"manifest":{"name":"Lovelace Card Preloader"},"description":"Allows preloading of Lovelace cards as a work around for changes in Home Assistant 0.107","etag_releases":"W/\"3ffbc7e13455e767a28ca1b47dc39c847e00aa35ec0c6e481ab113680f572d08\"","etag_repository":"W/\"b70ad6fdd3313480f6cabc867110e8231bd9031090bf1f3eca4260db06b7f858\"","full_name":"gadgetchnnel/lovelace-card-preloader","last_commit":"49e93da","last_updated":"2023-03-04T06:21:16Z","last_version":"0.0.5","open_issues":9,"stargazers_count":23,"last_fetched":1706739202.296438},"634013716":{"manifest":{"name":"sixdegrees-card"},"description":"Lovelace card, like a gauge but only in six degrees","etag_releases":"W/\"9b8ec3b2bce8e3530c9f40e8092c7e567900ef1acc0b20855eec30a3d9f9bda9\"","etag_repository":"W/\"df695f042fc3b34c930855e5066795a3abb734ee3f28b56abfa5874153670f54\"","full_name":"krissen/sixdegrees-card","last_commit":"9acf884","last_updated":"2023-08-23T11:39:01Z","last_version":"v1.0.0","open_issues":1,"stargazers_count":2,"topics":["gauge"],"last_fetched":1692799997.871109},"545945955":{"manifest":{"name":"Formula One Card"},"description":"Present the data of Formula One in a pretty way","etag_releases":"W/\"08925462425b9c13e7111f89d63ff795804ec96cccb8dfc4e8bad16126241542\"","etag_repository":"W/\"d6b73856a673aa4ed95d6286becc08feb6d6e3d96875b6ed0513a0f94d980ec1\"","full_name":"marcokreeft87/formulaone-card","last_commit":"d024778","last_updated":"2024-04-01T06:24:06Z","last_version":"1.9.2","open_issues":8,"stargazers_count":125,"topics":["card","f1","formula1","formulaone","homeassistant-frontend","lovelace-custom-card"],"last_fetched":1712009661.022627},"691458765":{"manifest":{"name":"Circular timer card"},"description":"Custom Home Assistant card to display timer countdowns using D3.js","etag_repository":"W/\"0dc5fbc383b8fba0f0b67a5affe76ba59720b22ee23e58dc9f4600f53dc5b2aa\"","full_name":"karlis-vagalis/circular-timer-card","last_commit":"eaf2521","last_updated":"2023-12-29T11:31:42Z","open_issues":6,"stargazers_count":27,"topics":["d3js","lit-element","lovelace-custom-card","timer"],"last_fetched":1711635317.782386},"205261230":{"manifest":{"name":"HTML Jinja2 Template card"},"description":"This card displays provided Jinja2 template as an HTML content of a card. It uses exactly the same engine as Home Assistant in Developer tools.","etag_releases":"W/\"1426ef6947a002584be063808b043f4fa496923b04290acba6c059cecbedc250\"","etag_repository":"W/\"a40a6ebfd2bd63a73aaa35aebae71cce2dce8ec2c8058c05b68d3b7cb04ead97\"","full_name":"PiotrMachowski/Home-Assistant-Lovelace-HTML-Jinja2-Template-card","last_commit":"bf1ca67","last_updated":"2023-07-07T02:53:40Z","last_version":"v1.0.2","open_issues":12,"stargazers_count":62,"topics":["jinja2","lovelace-card"],"last_fetched":1711016094.928453},"505459170":{"manifest":{"name":"TV Remote Card (with touchpad and haptic feedback)"},"description":"\ud83d\udcfa TV Remote Card (with touchpad and haptic feedback)","downloads":12025,"etag_releases":"W/\"d3ec2d1f63e8217d5c070f158f427a4794df32e01b7bccbc3616535490ae0fa1\"","etag_repository":"W/\"7962f02f1aaceaf87b8215d56ab0a57d9ec4c7575c5c6ad21d119c9f19dab2cc\"","full_name":"usernein/tv-card","last_commit":"c8f0a76","last_updated":"2023-05-19T10:50:30Z","last_version":"v0.5.2","open_issues":22,"stargazers_count":95,"topics":["automation","card","remote","tv"],"last_fetched":1711433945.957666},"286038496":{"manifest":{"name":"Compass Card"},"description":"A Lovelace card that shows a directional indicator on a compass for Home Assistant","downloads":10497,"etag_releases":"W/\"fcb7e00d79f008a970e6f29c6540b51002810189aef27728fb9757105598622b\"","etag_repository":"W/\"ffaa97fbbe1119c058545bbb38f9214ed04a7c7d4d3e493064941eb8c1b88851\"","full_name":"tomvanswam/compass-card","last_commit":"803da41","last_updated":"2024-03-12T04:10:59Z","last_version":"v2.0.0","open_issues":25,"stargazers_count":151,"topics":["compass","lovelace-card"],"last_fetched":1712045910.631043},"179808576":{"manifest":{"name":"BHA Icon Pack"},"description":"Additional icons for Home Assistant to accompany the MDI icons","etag_repository":"W/\"90491f78133ad643e79b1021207e209eeb706aedc5eb02bd82e19c5ce104325c\"","full_name":"hulkhaugen/hass-bha-icons","last_commit":"284d636","last_updated":"2023-09-18T07:02:59Z","open_issues":6,"stargazers_count":156,"topics":["icons","iconset","svg-icons"],"last_fetched":1709036533.825338},"158756598":{"manifest":{"name":"state-switch"},"description":"\ud83d\udd39Dynamically replace lovelace cards depending on occasion","etag_releases":"W/\"c8f4169a535bb5aa4d8b4c40ab7d75ee72343cb4d49a8b11f9b11509ba32b562\"","etag_repository":"W/\"0d0cf2b87232e7cd4d580f519ebfbe11522c31420b1717e146d4b101632c1459\"","full_name":"thomasloven/lovelace-state-switch","last_commit":"8f02700","last_updated":"2023-01-08T19:43:39Z","last_version":"1.9.5","open_issues":45,"stargazers_count":369,"last_fetched":1712067244.880592},"287840715":{"manifest":{"name":"OZW Network Visualization Card"},"description":"Lovelace custom card for visualizing the ZWave network with the OpenZWave (beta) integration.","etag_repository":"W/\"6146c0b01d7d2f8a8bf926717d66c77f8086f51cbdff96181fea8cd382b41602\"","full_name":"abmantis/ozw-network-visualization-card","last_commit":"05443f9","last_updated":"2022-06-05T22:24:45Z","stargazers_count":30,"topics":["ozw","zwave","zwave2mqtt"],"last_fetched":1678386270.79243},"291480917":{"manifest":{"country":["CN"],"name":"Colorfulclouds Weather Card"},"description":"\u8fd9\u662f\u4e00\u4e2a\u9002\u7528\u4e8e\u5f69\u4e91\u5929\u6c14\u96c6\u6210\u7684Lovelace\u5361\u7247","etag_releases":"W/\"c7e04493d0d5ba63027727861b58dfc0a4132d33aaebf62ebb17b95f514ca1b7\"","etag_repository":"W/\"a26cbc0e1c00cbd60ee83d3c66d7428fdce88a5fd13f1b5567f0f58e7ac5e403\"","full_name":"fineemb/lovelace-colorfulclouds-weather-card","last_commit":"6f5cb22","last_updated":"2023-11-08T04:26:31Z","last_version":"v1.3.3","open_issues":12,"stargazers_count":69,"topics":["lovelace-custom-card","weather"],"last_fetched":1711500912.783848},"447474061":{"manifest":{"name":"Irrigation Unlimited Card"},"description":"A companion card for the Irrigation Unlimited integration","downloads":1352,"etag_releases":"W/\"3fe92c50eca9d25792482ee47856190b1fce73a87f20f51fdbbf9ff7d906d08c\"","etag_repository":"W/\"f8309b1ecb17f197671673d1f7a15a42b53e2fa9af03214d64a8393b987af011\"","full_name":"rgc99/irrigation-unlimited-card","last_commit":"81a42cd","last_updated":"2024-01-28T23:59:36Z","last_version":"2024.1.0","open_issues":3,"stargazers_count":15,"topics":["irrigation","irrigation-controller","sprinkler-controller","watering"],"last_fetched":1711933339.167228},"457767453":{"manifest":{"name":"Skolmat Card"},"description":"Home Assistant Lovelace card to display the food menu in Swedish schools.","etag_releases":"W/\"1b5e8b7d8644c30251d77dd67b9e8befd2aaea735077047df06fe7bef9d90152\"","etag_repository":"W/\"a19b35c98af2c74cc58ec5e168fc14ac33bb6179fefaa2d76556ee6eca4bc406\"","full_name":"Kaptensanders/skolmat-card","last_commit":"6a578e3","last_updated":"2023-02-07T20:21:10Z","last_version":"v1.2.0","open_issues":1,"stargazers_count":9,"topics":["home-assistant-component","lovelace-card","lovelace-custom-card","skola","skollunch","skolmat"],"last_fetched":1708783902.583557},"261262884":{"manifest":{"name":"Time Picker Card"},"description":"\ud83d\udd70\ufe0f Time Picker Card for Home Assistant's Lovelace UI","downloads":9680,"etag_releases":"W/\"29be8df9277282659e7ea1947132994101a793f8f648316573eb4b570995e324\"","etag_repository":"W/\"bc6fc3263e57b9460f3f632934e924c46d380e86049493ab7515da5854a3468f\"","full_name":"GeorgeSG/lovelace-time-picker-card","last_commit":"bbec594","last_updated":"2023-07-18T22:02:59Z","last_version":"1.4.0","open_issues":11,"stargazers_count":203,"topics":["lovelace-card","lovelace-custom-card"],"last_fetched":1711649798.98597},"321773656":{"manifest":{"name":"themable-grid"},"description":"\ud83c\udc39 Lovelace responsive grid card that can be tweaked in your theme definition.","downloads":2538,"etag_releases":"W/\"f2469420bd9e9f223d732dc2dfb1f09c1e469fbac1775d8d97c9bfffd2049979\"","etag_repository":"W/\"34b9860308ea17b6308ca4f03f7f08db4504100930ccf223bbbf5741a400a7a5\"","full_name":"nervetattoo/themable-grid","last_commit":"ccd6243","last_updated":"2022-12-21T10:40:03Z","last_version":"v2.1.1","open_issues":7,"stargazers_count":30,"topics":["lovelace-card","lovelace-custom-card"],"last_fetched":1704550397.018745},"150781994":{"manifest":{"name":"fold-entity-row"},"description":"\ud83d\udd39 A foldable row for entities card, containing other rows","etag_releases":"W/\"0fda92d77be5f049daa33ad520b4d5820c10a0723b3dce1b08c371be9e227ce7\"","etag_repository":"W/\"e2bbae542bce9c4d0381d0f63175d2f3ef9e32d57a01baf0da258b5e7a59a86d\"","full_name":"thomasloven/lovelace-fold-entity-row","last_commit":"419ec48","last_updated":"2023-03-04T05:08:58Z","last_version":"2.2.0","open_issues":21,"stargazers_count":539,"last_fetched":1711707358.561824},"190927524":{"manifest":{"name":"card-mod"},"description":"\ud83d\udd39 Add CSS styles to (almost) any lovelace card","etag_releases":"W/\"fc7162a8f1768d6919ef351eed890a8d0f9cf1a7442d0d421cd0d6a0313e90bf\"","etag_repository":"W/\"7933192b1b05c9fceb3d8ed29878e53011f649f104238caee6e3e36f4ae66088\"","full_name":"thomasloven/lovelace-card-mod","last_commit":"f59abc7","last_updated":"2024-03-13T21:48:53Z","last_version":"v3.4.3","open_issues":55,"stargazers_count":962,"last_fetched":1712204361.318254},"182113743":{"manifest":{},"description":"A custom Lovelace text input row for use in entities cards","etag_releases":"W/\"afa7f12ba761bf2e2ec0a886c47c290e153634ff48772f8d004071e4cc2c38f9\"","etag_repository":"W/\"0da589341b2abc7bac890c159e069e6b8cf6360ae6f340b8eac0cb2e5dd3df15\"","full_name":"gadgetchnnel/lovelace-text-input-row","last_commit":"e831bad","last_updated":"2023-12-07T17:47:24Z","last_version":"v0.0.11","open_issues":4,"stargazers_count":33,"last_fetched":1708035162.724072},"332589148":{"manifest":{"name":"Big Slider Card"},"description":"A card with a big slider for light entities in Home Assistant","downloads":4910,"etag_releases":"W/\"d825fa7bd419c18fad78956d021f4fcbd395c476b6bbc8b048aa3bac60b3825a\"","etag_repository":"W/\"d486968b7a1654a15b28a130702dffb1767871f2521280b75c61ff695955d301\"","full_name":"nicufarmache/lovelace-big-slider-card","last_commit":"d1556bd","last_updated":"2024-02-28T23:31:24Z","last_version":"1.1.5","open_issues":20,"stargazers_count":51,"topics":["big-slider","card","light","lovelace-card","lovelace-custom-card","lovelace-slider","slider","slider-card"],"last_fetched":1712045888.035248},"143850865":{"manifest":{},"description":"This card give you a list of your wishlist items.","etag_releases":"W/\"6476b0d2fd60690f340ac4f51b464984f5d63b31bb4c641aa7ac501a2c2e25b4\"","etag_repository":"W/\"85a3c7d55db468996b2bf22c72c5e3c10bf16c51a4efb9f9b17847a583723bed\"","full_name":"custom-cards/beer-card","last_commit":"c48a090","last_updated":"2021-01-13T09:25:20Z","last_version":"0.2.4","stargazers_count":3,"last_fetched":1704903452.418909},"191580766":{"manifest":{"name":"Light with profiles"},"description":"Turn on lights based on light_profiles.csv","etag_releases":"W/\"b67c3e457c915d3b2478bdbe87427b89ac5fdb7af10ab7ed238e8397f5c3b75b\"","etag_repository":"W/\"1c1a9f382192f962e40a24fd51af074a38b4592e4b6edd05e975da20b64499a2\"","full_name":"tcarlsen/lovelace-light-with-profiles","last_commit":"ee282f3","last_updated":"2022-06-12T20:39:16Z","last_version":"2.3.0","open_issues":2,"stargazers_count":62,"topics":["light","light-profiles","lovelace-card","profiles"],"last_fetched":1708100252.330068},"665501829":{"manifest":{"name":"Weather Chart Card"},"description":"Custom weather card with charts.","downloads":6790,"etag_releases":"W/\"ca92527c4e30bc995087f118fd5663ec99946ef17d3f664466dfe302c1003fc4\"","etag_repository":"W/\"dd7b154d515d612e3b122458539f5efe79a32600d6598bcfe33d7ce89f5301b3\"","full_name":"mlamberts78/weather-chart-card","last_commit":"930a68b","last_updated":"2024-03-29T15:20:25Z","last_version":"V2.4.5","open_issues":9,"stargazers_count":166,"topics":["card","weather"],"last_fetched":1712182406.036328},"439367892":{"manifest":{"name":"Better Thermostat UI"},"description":"a custom card for a better thermostat in home assistant based on better_thermostat intigration","downloads":29447,"etag_releases":"W/\"0aa0fec01668b15f5e82c30ef25ade4663543a3a8a817bb8c9492fff8c06c1b3\"","etag_repository":"W/\"af91136645bffb6f8fdea9a4ad88f2ae58433e9be5da471e9ff13b039fb32f3f\"","full_name":"KartoffelToby/better-thermostat-ui-card","last_commit":"4d50fea","last_updated":"2024-03-24T22:25:39Z","last_version":"2.2.0","open_issues":45,"stargazers_count":179,"topics":["thermostat"],"last_fetched":1712175373.243967},"159711605":{"manifest":{"name":"Secondaryinfo Entity Row"},"description":"Custom entity row for HomeAssistant, providing additional types of data to be displayed in the secondary info area of the Lovelace Entities card","etag_releases":"W/\"cd2f42c9badb67a77dd8382e9813f92a56a0456db33b3b046008de11b44800c2\"","etag_repository":"W/\"cf9a1c09023d8b9e8fd3a164b8a6eef0f1897b6cc051c39166533405fa3125cd\"","full_name":"custom-cards/secondaryinfo-entity-row","last_commit":"2ea0f5d","last_updated":"2021-06-05T21:12:36Z","last_version":"5.0","open_issues":19,"stargazers_count":165,"last_fetched":1710407467.112228},"197759180":{"manifest":{},"description":"Quickly search for entities from a Lovelace card.","etag_repository":"W/\"f549629638cbfa4924fe8e280c6039e0af40b26de789dc97f5743dbf6ce1842b\"","full_name":"postlund/search-card","last_commit":"d4a0bb7","last_updated":"2023-11-03T05:22:12Z","open_issues":17,"stargazers_count":101,"last_fetched":1710087388.991851},"218178802":{"manifest":{"name":"Local Conditional card"},"description":"This card can show and hide a specific card on current device while not affecting other windows. It does not require any integration to run.","downloads":3295,"etag_releases":"W/\"908bd7d4be806699dc9c1f3588d6137c401de498727f644ae11bce8f69234ccb\"","etag_repository":"W/\"d9e97b80fc86a3c25253071a0e8fead4dbb481d419e8a1d92e332490d12a8541\"","full_name":"PiotrMachowski/Home-Assistant-Lovelace-Local-Conditional-card","last_commit":"65b0545","last_updated":"2023-07-07T02:53:33Z","last_version":"v2.1.0","open_issues":3,"stargazers_count":61,"topics":["lovelace-card"],"last_fetched":1710792932.725751},"201292040":{"manifest":{"name":"Zigbee2mqtt Networkmap Card"},"description":"Home Assistant Custom Card to show Zigbee2mqtt network map","downloads":5960,"etag_releases":"W/\"985bb37c2c6c70ec1297991666e49204d29f294e093d0316058d87e3fc5dd298\"","etag_repository":"W/\"79d768b36ec7293d211072e7a01d5b5c6dd4dd9568f0c08ac95a0221049a8033\"","full_name":"azuwis/zigbee2mqtt-networkmap","last_commit":"358c5fb","last_updated":"2024-03-28T20:10:09Z","last_version":"v0.9.0","open_issues":5,"stargazers_count":219,"topics":["zigbee2mqtt"],"last_fetched":1712132175.593988},"308752409":{"manifest":{"name":"Charger Card"},"description":"A lovelace card for electrical vehicle (EV) home chargers and charging robots.","downloads":3245,"etag_releases":"W/\"5d6824709338bde6cf9235a39195c18fdba79980ac8f32c9a02c62083719b44c\"","etag_repository":"W/\"8178abf310850de52c01e3acdf58bc0d39dae01b1e609b78b700bd15040a9eaf\"","full_name":"tmjo/charger-card","last_commit":"fb83c2b","last_updated":"2024-03-09T23:17:35Z","last_version":"v0.2.7","open_issues":13,"stargazers_count":79,"topics":["charger","charging-robot","easee","elbil","electric-vehicle","evcharger"],"last_fetched":1711188889.418537},"146194325":{"manifest":{"name":"button-card"},"description":"\u2747\ufe0f Lovelace button-card for home assistant","downloads":97961,"etag_releases":"W/\"720acca2dc3eed7b354c9d2621aa3c39eee074463b51b4bb135623c0d9f86c48\"","etag_repository":"W/\"c315c894f80cd3e4bfb79bfc10ca324de1ffd7fcf7050e0f1cdf3a076e337048\"","full_name":"custom-cards/button-card","last_commit":"2562b84","last_updated":"2024-02-01T11:24:39Z","last_version":"v4.1.2","open_issues":198,"stargazers_count":1720,"last_fetched":1712153541.021641},"283578257":{"manifest":{"name":"power-distribution-card"},"description":"A Lovelace Card for visualizing power distributions.","downloads":4836,"etag_releases":"W/\"da61b16ed9021b1757bebcc5a46488a50d34dc64cb2f10350cb9b2b0878e3cbc\"","etag_repository":"W/\"a9081eab962d63454238063d8e5c1296ef4a968496b1b7c236308254d4539068\"","full_name":"JonahKr/power-distribution-card","last_commit":"3bef10c","last_updated":"2024-01-05T19:58:37Z","last_version":"v2.5.11","open_issues":9,"stargazers_count":194,"topics":["e3dc","lovelace-card"],"last_fetched":1711801285.302911},"491303842":{"manifest":{"name":"Datetime Card"},"description":"A minimalistic card for Home Assistant Lovelace UI which shows how many days it has been between any input_datetime and today.","downloads":1702,"etag_releases":"W/\"a88489d230cde42c55d24f79fa06ce34d4d290b3254cbf815d529212254b511c\"","etag_repository":"W/\"1c93adab67b308db1449fefb1c93462bc7b9dde97844974854281ebd327f48b6\"","full_name":"a-p-z/datetime-card","last_commit":"fe06474","last_updated":"2023-12-19T16:08:14Z","last_version":"v1.0.4","open_issues":6,"stargazers_count":19,"topics":["lovelace-custom-card","svelte"],"last_fetched":1710799939.46539},"362551242":{"manifest":{"name":"Update Time Card"},"description":"Simple last-updated card for Home assistant lovelace","etag_releases":"W/\"719d730fe55f69b1e5d242773e800e1c87f79f1dac2e69d84d54f77e7b39f12f\"","etag_repository":"W/\"72b0f70c3c1e6ef13c5e84ff1e2735e57b84330a317ab06795f3a617318b4fb1\"","full_name":"itobey/update-time-card","last_commit":"9580c83","last_updated":"2023-04-03T23:03:48Z","last_version":"2.0.0","stargazers_count":6,"topics":["clock","dashboard","e-ink","last-updated","lovelace-custom-card"],"last_fetched":1711846867.677961},"633889686":{"manifest":{"country":["IL"],"name":"Silent bus card"},"description":"Bus card for homeassistant - Israel","etag_releases":"W/\"e7b4c81b3aba7adcbd6b73e5281a0559aedaef3a5182c08428deb4097f50bcd2\"","etag_repository":"W/\"19fb1ad04d06ac76b5ac5d75be3d863d4994034405c10e2f9d20548487b98195\"","full_name":"silentbil/silent-bus","last_commit":"eb48d5d","last_updated":"2023-09-22T14:05:57Z","last_version":"v1.15","open_issues":2,"stargazers_count":23,"topics":["bus","card","frontend"],"last_fetched":1707848317.250454},"594389396":{"manifest":{"name":"Energy Overview Card"},"description":"A simple card which displays energy usage details of one or multiple entities.","downloads":4967,"etag_releases":"W/\"cb2a8f46d0cff6bc41663e87e770a553350ad265ca7b63aabc3471f8b75d50e2\"","etag_repository":"W/\"f4f12768ae66db76d988062fcbfaa7db8ee28c14b2b9542b96b03af13e607114\"","full_name":"Sese-Schneider/ha-energy-overview-card","last_commit":"6b1612d","last_updated":"2024-01-09T10:12:47Z","last_version":"v2.5.0","open_issues":7,"stargazers_count":48,"topics":["energy","energy-monitor","power","shelly-3em"],"last_fetched":1708964285.491044},"466196192":{"manifest":{"name":"Header Cards"},"description":"Header Cards","etag_releases":"W/\"a5ff6dd0665b784cfccfffa8bd777abc0bcfbc8d9e45a9d333c3f86eaa9a7d76\"","etag_repository":"W/\"5c080eb8ab6fef483a0adf695f64c74472c4f964b261637f22b13506936e8c39\"","full_name":"gadgetchnnel/lovelace-header-cards","last_commit":"8b45d44","last_updated":"2023-04-06T10:44:52Z","last_version":"0.0.10","open_issues":10,"stargazers_count":37,"topics":["cards","header"],"last_fetched":1704773826.683302},"321140869":{"manifest":{"name":"Auto Reload"},"description":"Custom home assitant lovelace for UI auto reload","etag_repository":"W/\"cc6db0f5ef1b6b90e61d708cd27c1444370f86dafaf0abebfed973c4b35d8ba5\"","full_name":"ben8p/lovelace-auto-reload-card","last_commit":"733d5bc","last_updated":"2023-05-24T20:46:18Z","open_issues":7,"stargazers_count":33,"topics":["lovelace-card"],"last_fetched":1711736135.128257},"454440949":{"manifest":{"name":"Room Card"},"description":"Show multiple entity states, attributes and icons in a single card in Home Assistant's Lovelace UI","etag_releases":"W/\"491fd274da4975dfa468f118e7a4cd3acea1b52079b16130ac2da9dfce011b15\"","etag_repository":"W/\"247427f74a0ebfed8e1b79a3f40036a02cd50017362cb2380d9ab3aa70ae0867\"","full_name":"marcokreeft87/room-card","last_commit":"f180f07","last_updated":"2024-04-01T08:54:55Z","last_version":"1.08.03","open_issues":11,"stargazers_count":179,"topics":["attribute","card","entities","format","homeassistant-frontend","lovelace-custom-card","room"],"last_fetched":1711966567.638759},"454670742":{"manifest":{"name":"AstroWeather Card"},"description":"Lovalace Card for the AstroWeather Integration","etag_releases":"W/\"2208c116981a164b485d304f47b2e8c6a6da060920dc83fded7d45b2c320f45d\"","etag_repository":"W/\"7fd974a75edde2cb16eb1ede3ef0ea67977e8122d68c14273a762e0328e35fc6\"","full_name":"mawinkler/astroweather-card","last_commit":"89f1aa1","last_updated":"2024-01-16T07:24:40Z","last_version":"v0.42.1","open_issues":2,"stargazers_count":17,"topics":["7timer","astronomy","forecast","lovelace-card"],"last_fetched":1707596033.128176},"640556013":{"manifest":{"name":"Energy Entity row"},"description":"Lovelace HA entity row to integrate with energy-date-selection","downloads":3177,"etag_releases":"W/\"f4627d24201239210118158ac16c9aaf7bef115dbbc48bf77eb5e60be3898395\"","etag_repository":"W/\"e4a52edc4345c2488c518e9856d2feb580afad086ed167ea4a1ef722e4986b33\"","full_name":"zeronounours/lovelace-energy-entity-row","last_commit":"06ee451","last_updated":"2023-05-16T06:26:50Z","last_version":"v1.0.0","open_issues":1,"stargazers_count":7,"topics":["energy-consumption","lovelace-entity-row"],"last_fetched":1712045911.171079},"279157206":{"manifest":{"name":"Water Heater Card"},"description":"Water Heater card for Home Assistant's Lovelace UI","etag_releases":"W/\"349def047db3ce964d39fec7cf5cd21a9f603129f6e18364c1c5659132018e4d\"","etag_repository":"W/\"a9a621d2f370761b5d4570a69c7d1a45cbf7588e18a3269e7956ff2dad8ffe74\"","full_name":"rsnodgrass/water-heater-card","last_commit":"e1597e3","last_updated":"2022-09-09T06:27:18Z","last_version":"0.0.2","open_issues":1,"stargazers_count":7,"last_fetched":1711441071.050747},"497322919":{"manifest":{"name":"Upcoming Media Card"},"description":"\ud83d\udcfa A card to display upcoming episodes and movies from services like: Plex, Kodi, Radarr, Sonarr, and Trakt.","downloads":10601,"etag_releases":"W/\"0fe064df5edd76d7ce35742d887498a5d5e5a40738d0d0a621e11c74a3c4c869\"","etag_repository":"W/\"fdb3ef1ee0f6640162d85a4b0e1a53361e4f02639b59744ad31595a20d538176\"","full_name":"NemesisRE/upcoming-media-card","last_commit":"53c633e","last_updated":"2022-05-31T15:30:28Z","last_version":"0.4.4","open_issues":1,"stargazers_count":24,"topics":["customization"],"last_fetched":1712125067.211277},"701044448":{"manifest":{"country":["AD","AR","AU","BH","BE","CA","DK","DE","EE","ES","FI","FR","HK","HR","IS","IN","IE","IL","IT","JO","KW","LV","LB","LT","LU","MO","HU","MT","NL","NZ","NO","OM","PL","PT","QA","RO","SA","SH","SG","SI","SK","ZA","CH","SE","TR","AE","GB","US","AT","CZ","GR","BG","JP","KR"],"name":"SugarTV Card"},"description":"A custom lovelace card for Home Assistant that provides a better way to display Dexcom data.","etag_releases":"W/\"69a6713d5e5e8d062eba5dc16b4c1a9b0a8b2a16f3f5f44abbfcc23e3ca1e40a\"","etag_repository":"W/\"95414a566a2386ab669402e4d76a8b358caba2e976e18eff7a821443e42e6803\"","full_name":"wiltodelta/homeassistant-sugartv-card","last_commit":"38f7d50","last_updated":"2024-02-01T17:22:11Z","last_version":"v0.3.1","open_issues":1,"topics":["dexcom","homeassistant-custom-component"],"last_fetched":1706818524.552275},"186765704":{"manifest":{},"description":"A fluffy banner card for Home Assistant \ud83e\udd70","downloads":45055,"etag_releases":"W/\"0a6495f39aaa6c8d41ae9c79831b0d29fe02f7ecb90f8d26e8b7fd0effd9c5df\"","etag_repository":"W/\"8fcd48edcac00644046a4547c82c9b54744a124aa4dd87a448628fc711855433\"","full_name":"nervetattoo/banner-card","last_commit":"554c77c","last_updated":"2023-02-03T04:52:53Z","last_version":"0.13.0","open_issues":75,"stargazers_count":585,"last_fetched":1711155315.736747},"559360809":{"manifest":{"name":"Linked Lovelace"},"description":"Create cards that can be re-used, updated, and handle templated data.","downloads":504,"etag_releases":"W/\"b13a9b23a9b2e4df394a9ab982b12790ceb8cedfd0ca14aaa64c7ed89f603d2d\"","etag_repository":"W/\"451b940d5b9700dfa9e156ef7dc0f23b1b14ce9f18351958d59e03d7bd4544fb\"","full_name":"daredoes/linked-lovelace-ui","last_commit":"44ec07e","last_updated":"2024-03-26T20:36:42Z","last_version":"2.2.2","open_issues":2,"stargazers_count":24,"topics":["javascript","typescript"],"last_fetched":1712045803.597734},"202546107":{"manifest":{},"description":"Extras for the synthwave inspired theme for Home Assistant","etag_releases":"W/\"ef39c78fff8a10d4b77433aa2de6853467c400fc8b2fd0d42b3440529e1f88eb\"","etag_repository":"W/\"eb31c42d934ee4d709fa7dcc47b3ecae6561666f2de520a0c0bb6118cea54fa9\"","full_name":"bbbenji/synthwave-hass-extras","last_commit":"2a2542d","last_updated":"2020-10-30T00:24:02Z","last_version":"0.2.4","open_issues":1,"stargazers_count":14,"last_fetched":1696940639.984874},"156292058":{"manifest":{"name":"Flex Table - Highly customizable, Data visualization"},"description":"Highly Flexible Lovelace Card - arbitrary contents/columns/rows, regex matched, perfect to show appdaemon created content and anything breaking out of the entity_id + attributes concept","etag_releases":"W/\"f4e162cbbee95c86e1f55ca26de744418ddb59b426182ff5b42770ba0bc9d0c7\"","etag_repository":"W/\"4e34933f31f0ece786f35ba561698dc72bd23ba67a8757f563917f2b9f21d1ff\"","full_name":"custom-cards/flex-table-card","last_commit":"2bd1c62","last_updated":"2024-03-21T11:58:13Z","last_version":"v0.7.6","open_issues":30,"stargazers_count":184,"topics":["data-table","data-visualization","flexible-table","high-configurability","javascript","single-file","table-visualization"],"last_fetched":1711110153.911301},"281453608":{"manifest":{"name":"badge-card"},"description":"\ud83d\udd39 Place badges anywhere in the lovelace layout","etag_repository":"W/\"b9b8b270eb02482bf0587701a41d27cddd62fcdc7d0d22085cc3adbe20fe6c45\"","full_name":"thomasloven/lovelace-badge-card","last_commit":"5bf6f72","last_updated":"2023-03-05T07:44:24Z","open_issues":6,"stargazers_count":73,"last_fetched":1711469909.442696},"265313034":{"manifest":{"name":"Refreshable picture card"},"description":"a refreshable picture card for HACS","etag_releases":"W/\"f44da9d47cbac9013d001fb04d560181210567503ed0f7ccf7af421c321a2a57\"","etag_repository":"W/\"92f762f936ccb7a3334d8d00df0e40f832173b7976ad3de0b62954ea37c5f0e3\"","full_name":"dimagoltsman/refreshable-picture-card","last_commit":"a173411","last_updated":"2023-09-23T20:34:08Z","last_version":"0.2.1","open_issues":19,"stargazers_count":31,"last_fetched":1708855946.953593},"437989480":{"manifest":{"name":"Centrometal Boiler Display Card"},"description":"Lovelace Centrometal Boiler Card","etag_releases":"W/\"798fd2f4f0f39805044a02eb8e7a579711ef8b6c28f6c2689e75a33f4dbcf834\"","etag_repository":"W/\"ad31b4613c9cbd7a25b9e406ad73bda59b9606b4f823f541750847128239b93d\"","full_name":"9a4gl/lovelace-centrometal-boiler-card","last_commit":"ae36972","last_updated":"2023-12-29T17:01:38Z","last_version":"0.0.25","stargazers_count":4,"topics":["centrometal","homeassitant","pellet","peltec"],"last_fetched":1703873722.338079},"286408741":{"manifest":{"country":["NO"],"name":"Posten Card"},"description":"A Lovelace card to display Norwegian mail delivery days","downloads":2107,"etag_releases":"W/\"64b707261d1ccdc9db51d55a51bfdd39dd35e82e7158beeeaba1c78c50238074\"","etag_repository":"W/\"2e6ff428d1d9a1a7625a1f20cb116eecbb2c9f72430cc6c2ae4ea2a9afe0dde5\"","full_name":"ezand/lovelace-posten-card","last_commit":"3a00f67","last_updated":"2023-01-04T16:22:44Z","last_version":"1.0.1","open_issues":14,"stargazers_count":15,"topics":["lovelace-card","mail-delivery"],"last_fetched":1712045814.357165},"452251255":{"manifest":{"name":"Browser Control Card"},"description":"Control your browser from a Home Assistant lovelace card: full screen, disable screen lock, zoom, reload page...","downloads":1960,"etag_releases":"W/\"c6fbf8c30db92152c27984b4fc1157139e7950646bfd66bc4508a95731f9f608\"","etag_repository":"W/\"82070d2c0857c56c39110d6369a2c7143d8686b3fbcfb47279b5866a4be33b6e\"","full_name":"mathoudebine/homeassistant-browser-control-card","last_commit":"47e6b16","last_updated":"2023-10-20T10:29:06Z","last_version":"v1.3.1","open_issues":3,"stargazers_count":9,"topics":["browser","browser-control","card","fullscreen","lock","refresh","reload","sleep","wake-on-lan","zoom"],"last_fetched":1710051392.782719},"283542587":{"manifest":{"name":"Lovelace Clock Card"},"description":"Basic analog clock for Lovelace","etag_releases":"W/\"92bf6ed8a29a9280cfb85cabec5be44336e44b2d7efe8b80dbbae01cc3e81c0f\"","etag_repository":"W/\"4c96d110cbaee9275d508fec16a7b9457ad226096c1eb4ead02cf46a44ec0365\"","full_name":"Villhellm/lovelace-clock-card","last_commit":"7a89550","last_updated":"2020-11-24T17:31:42Z","last_version":"v0.4.1","open_issues":5,"stargazers_count":45,"topics":["analog","clock"],"last_fetched":1704989973.502936},"622713177":{"manifest":{"name":"GivTCP Power Flow Card"},"description":"A power distribution card for Home Assistant specifically for GivTCP users","downloads":2247,"etag_releases":"W/\"6891907c3c5e38a75ab4a723aa0e39675f3591331ab9c1440a7908a0abee5153\"","etag_repository":"W/\"c9c83a54a44472b92c0965a0790351496632830ab460428ba853e75f6bcba256\"","full_name":"VeniVidiVici/givtcp-power-flow-card","last_commit":"bfef24b","last_updated":"2024-04-03T16:55:19Z","last_version":"v.0.6.2","open_issues":8,"stargazers_count":4,"topics":["givenergy","givtcp"],"last_fetched":1712168292.031954},"271886611":{"manifest":{"name":"Plant Picture Card"},"description":"Like a picture glance card, but for plant data","etag_releases":"W/\"39d693a523f53204134d57b521bf68ab1f3feb722019061bc110420fc844672d\"","etag_repository":"W/\"981662025e7ea44882f5197e4eebe1e21ade82e656a4172a82b62117fd299a31\"","full_name":"badguy99/PlantPictureCard","last_commit":"eb06132","last_updated":"2022-07-07T21:55:54Z","last_version":"v0.1.4","open_issues":2,"stargazers_count":12,"topics":["image","lovelace-card","plants"],"last_fetched":1697936294.786404},"335713085":{"manifest":{"name":"Todoist Card"},"description":"Todoist card for Home Assistant Lovelace UI.","etag_releases":"W/\"076a962206e55191ff3eebe181f6b259d563591463f05a3138466d314c81c63a\"","etag_repository":"W/\"0d2ae1f19c86d97c3c8607e998339fef349af4e9440a441d249140171d3f59dc\"","full_name":"grinstantin/todoist-card","last_commit":"f235188","last_updated":"2023-12-15T11:58:39Z","last_version":"v1.1.3","open_issues":16,"stargazers_count":62,"topics":["todoist"],"last_fetched":1710224236.514902},"168744428":{"manifest":{"name":"Light Entity Card"},"description":"Control any light or switch entity","downloads":22288,"etag_releases":"W/\"53855ba1a34142a1c192aad51baeb52efaafc64c6169401f5338ab4fd4ddb87b\"","etag_repository":"W/\"85512bf6432e35c3824d0cca24cf36355a11d469cefc5d44859dc035a077c896\"","full_name":"ljmerza/light-entity-card","last_commit":"e721039","last_updated":"2024-01-08T16:56:45Z","last_version":"6.1.3","open_issues":41,"stargazers_count":218,"topics":["color-picker","home-assisttant","light-entity"],"last_fetched":1712175383.611139},"167744584":{"manifest":{"name":"auto-entities"},"description":"\ud83d\udd39Automatically populate the entities-list of lovelace cards","etag_releases":"W/\"a2e29a02f21d77f68f1b81543f50c6ab41c901df2e240980e2ae62b7617ccadf\"","etag_repository":"W/\"30959d5e2cbd61cab78b531b0c47983740e50a230b89f187d9ab16dc5fc79264\"","full_name":"thomasloven/lovelace-auto-entities","last_commit":"843e84b","last_updated":"2024-04-03T18:28:37Z","last_version":"v1.13.0","open_issues":96,"stargazers_count":1110,"last_fetched":1712192305.818496},"614083491":{"manifest":{"name":"Horizon Card"},"description":"Sun Card successor: Visualize the position of the Sun over the horizon.","downloads":31046,"etag_releases":"W/\"c3f8b6ffd4b689cbef4744a9bb736f623b079e17a36a333e8c13c491c7ae921c\"","etag_repository":"W/\"caf9b7b10e60449c7c7818d3c96c64e4a677d090101d189c305aebd813d6d8ca\"","full_name":"rejuvenate/lovelace-horizon-card","last_commit":"d0a1c87","last_updated":"2024-04-01T11:06:58Z","last_version":"v1.0.0","open_issues":54,"stargazers_count":364,"topics":["home-assistant-sun-card","homeassistant-sun-card","lovelace-card","sun-card"],"last_fetched":1712211500.787478},"275672933":{"manifest":{"name":"Select list Card"},"description":"Select List Card displays an input_select entity as a list in lovelace","downloads":10847,"etag_releases":"W/\"4d5a7e41c3d9de6c8a476f0f6be243f20b25d1750d47326ac7013176a6e01932\"","etag_repository":"W/\"b00dd49101302a7183c26405984f05c07b64a1e70d4a49a0400b863bf044cfa9\"","full_name":"mattieha/select-list-card","last_commit":"9446704","last_updated":"2024-02-09T07:28:06Z","last_version":"v1.2.0","open_issues":25,"stargazers_count":57,"topics":["lovelace-custom-card"],"last_fetched":1712074688.208974},"235449701":{"manifest":{"name":"Lightalarm Card"},"description":"\u23f0 Lovelace Card to Control Light Alarm Properties","etag_releases":"W/\"de7fdff81e1f30469899660630fe44580749af00421e9f4f44391dbd6ccd4596\"","etag_repository":"W/\"dc5b226172af3d9648c0a188309a49661c388acb3088fe9075454851dc3bf847\"","full_name":"chaptergy/lightalarm-card","last_commit":"c6d8540","last_updated":"2023-07-18T20:41:09Z","last_version":"v4.0.1","open_issues":2,"stargazers_count":36,"last_fetched":1708359422.584714},"254206234":{"manifest":{"name":"PVPC Hourly Pricing Card"},"description":"Home Assistant Lovelace custom card to use with Spain electricity hourly pricing (PVPC) integration","downloads":16,"etag_releases":"W/\"24b031e5a93f74dde988f47db7164d0c5adfcc04881bf2f2b8a2a81c1cec5f63\"","etag_repository":"W/\"958933984dc6a76a8e6a88777606a994ac16b8be2d14b5ddb52eeda7c5a94f07\"","full_name":"danimart1991/pvpc-hourly-pricing-card","last_commit":"cc8c748","last_updated":"2024-04-02T14:25:43Z","last_version":"1.14.1","open_issues":3,"stargazers_count":75,"topics":["esios","graphics","lovelace-card","lovelace-custom-card","pvpc","ree"],"last_fetched":1712074609.052418},"394082552":{"manifest":{"name":"Frigate Card"},"description":"A Lovelace card for Frigate in Home Assistant","downloads":49306,"etag_releases":"W/\"ccb1e2efe3fe6261ecbcd470138464361e94acceb53edd627a3a53ee3add0be9\"","etag_repository":"W/\"7602d64bd0283ba24eba94a6d48bfc8964db55cafbd5b1053804f7ebc43b5b97\"","full_name":"dermotduffy/frigate-hass-card","last_commit":"6307daf","last_updated":"2024-04-02T20:07:26Z","last_version":"v5.2.0","open_issues":69,"stargazers_count":439,"topics":["cctv","frigate","nvr"],"last_fetched":1712182332.781782},"164022050":{"manifest":{},"description":"Check Button Card is a button that tracks when it is last pressed, for the Home Assistant Lovelace front-end using MQTT auto discovery.","downloads":7216,"etag_releases":"W/\"e5dc428d891ff930b423bc172d66dff682d045615a4e822854899305dbd9db68\"","etag_repository":"W/\"b7caf89fd51d60a6f894bdd6340fd3f9f7e033d522b5a5e63b8ab4c500f79ecc\"","full_name":"custom-cards/check-button-card","last_commit":"d8350ca","last_updated":"2021-12-22T18:23:08Z","last_version":"1.3.0","open_issues":12,"stargazers_count":103,"last_fetched":1709928725.074201},"241706284":{"manifest":{"name":"Button Text Card"},"description":"Custom, \"neumorphism\" Lovelace card","etag_releases":"W/\"9b6785df4e7b5022b7e2badc334cacfec561b5a359f078298d54929a3334ff5a\"","etag_repository":"W/\"a5bb3e41ea5946ea83e12105dd20ffd4152f0434c6b841b46b02931ea44be55d\"","full_name":"Savjee/button-text-card","last_commit":"5a469d5","last_updated":"2023-04-06T05:55:03Z","last_version":"v0.6.5","open_issues":8,"stargazers_count":116,"topics":["lovelace-card","templating","typescript"],"last_fetched":1709288138.940419},"184333163":{"manifest":{"name":"Lovelace Card Templater"},"description":"Custom Lovelace card which allows Jinja2 templates to be applied to other cards","etag_releases":"W/\"c5c0c7faab6b6f0af61e61899cc8b2d0594497201fceded616575252c753e827\"","etag_repository":"W/\"0276b40033e78a31a37845cb4bd52f18c3909878d4b413417e2f65cd77874763\"","full_name":"gadgetchnnel/lovelace-card-templater","last_commit":"61b62fd","last_updated":"2023-01-07T15:41:51Z","last_version":"0.0.17","open_issues":26,"stargazers_count":110,"last_fetched":1712225651.435461},"683553739":{"manifest":{"name":"Keep Texts in Tabs"},"description":"Keep texts in Home Assistant dashboards tabs when icons are added to them","downloads":1539,"etag_releases":"W/\"1cde3b8c8a7302a291b5339f14b29e528400c49b5c024c3784f01da976bc2f7c\"","etag_repository":"W/\"c60fb0020af95e888929f955d09be27df9b64a84b2749aa161dd094001562741\"","full_name":"elchininet/keep-texts-in-tabs","last_commit":"698cf1b","last_updated":"2024-04-01T12:18:32Z","last_version":"v1.2.0","stargazers_count":25,"topics":["custom-plugin","hacs-plugin","keep-texts-in-tabs","tabs-management","tabs-texts"],"last_fetched":1711974295.605488},"180464361":{"manifest":{"name":"Travel Time Card"},"description":"show travel times for you travel time sensors","downloads":1829,"etag_releases":"W/\"e01990bd28e8aa58bcf8055385d7b7a384bb74ba31d75f9c024a425b72c94a1f\"","etag_repository":"W/\"589a40bc0370aa371e62b0fce903b5b06ad654ff42f649a08c72e81eb0d58a03\"","full_name":"ljmerza/travel-time-card","last_commit":"9e3c93d","last_updated":"2023-07-11T01:04:26Z","last_version":"2.0.0","open_issues":21,"stargazers_count":27,"last_fetched":1706977024.480532},"330454534":{"manifest":{"name":"La Marzocco Config Card"},"description":"Lovelace card to configure network-connected La Marzocco espresso machines","downloads":116,"etag_releases":"W/\"e44a1bc956586cf65f2fa8048da71b9b6333440e6ac40baef47cc97c789a7d73\"","etag_repository":"W/\"dd9845418ffda6a84974633a5156830ab730ec4ebbc7df52f47c7a7625ac432f\"","full_name":"rccoleman/lovelace-lamarzocco-config-card","last_commit":"c088684","last_updated":"2022-11-15T05:00:39Z","last_version":"v1.0.0","stargazers_count":2,"topics":["automation","espresso","lamarzocco","lovelace-card","lovelace-custom-card"],"last_fetched":1711649872.298275},"147764937":{"manifest":{"name":"surveillance-card"},"description":"A custom component for displaying camera feeds in the style of a surveillance system.","etag_releases":"W/\"8ab2ec9a47f605adadf84a139f3fdb3686cddbfcd5fc6fcf8b28e47c0db17d78\"","etag_repository":"W/\"4c4f99f766cac20f14edbbd3294796fa93ba80d13401fa1548b496749c77c487\"","full_name":"custom-cards/surveillance-card","last_commit":"4f9ead3","last_updated":"2023-05-15T22:13:17Z","last_version":"0.0.7","open_issues":17,"stargazers_count":235,"topics":["camera","motion","security"],"last_fetched":1711080903.338646},"174016256":{"manifest":{"name":"Lovelace Home Feed Card"},"description":"A custom Lovelace card for displaying a combination of persistent notifications, calendar events, and entities in the style of a feed.","etag_releases":"W/\"c59c17ce065701fd7f6a19fcdb722713b2e2ba9f2d048deb97049d4a0f9411bd\"","etag_repository":"W/\"941f1a8ec52ed732d1889d9609db890c6e0210f28ab2804e748614a1e568e79c\"","full_name":"gadgetchnnel/lovelace-home-feed-card","last_commit":"b927fdd","last_updated":"2024-02-23T19:04:02Z","last_version":"0.6.5","open_issues":44,"stargazers_count":229,"last_fetched":1711908932.430505},"236664033":{"manifest":{"name":"Swipe Glance Card"},"description":":point_up_2: Swipe Glance Card","downloads":3553,"etag_releases":"W/\"1ae2e31974929d86b39be1667eb2f1b4a7895c84016857491751e263343c9cd4\"","etag_repository":"W/\"ed3a88ec8df9273ba295f053fd9629769caa3cab8551ffc70667f3517f2ae74a\"","full_name":"dooz127/swipe-glance-card","last_commit":"9b4f41a","last_updated":"2023-01-04T14:06:20Z","last_version":"0.3","open_issues":14,"stargazers_count":12,"topics":["automation"],"last_fetched":1712045814.13498},"260597137":{"manifest":{"name":"Air Purifier Card"},"description":"\u7528\u4e8eLovelace\u7684\u5c0f\u7c73\u7a7a\u6c14\u51c0\u5316\u5668\u5361\u7247","etag_releases":"W/\"d72dd4babe41f550e7fa5c99b63a59443d79a7997fb72cec4199d9fc4e66af2a\"","etag_repository":"W/\"a32afa31231e94ee311ef64cd784fa881287c8cee364466002f26b8661129b01\"","full_name":"fineemb/lovelace-air-filter-card","last_commit":"a20f6b2","last_updated":"2022-06-02T18:43:53Z","last_version":"v1.1.3","open_issues":9,"stargazers_count":13,"last_fetched":1706976971.658428},"214786112":{"manifest":{"name":"Swiss Army Knife custom card"},"description":"The versatile custom Swiss Army Knife card for Home Assistant allows you to create your unique visualization using several graphical tools, styling options and animations.","etag_releases":"W/\"6e23cae93cadea237a780860660a625246c370450d5127f0062c5cd26bf19801\"","etag_repository":"W/\"4604cc1a91ae398b1ba43c61279d57fc55217142b4f646bec51f21345d044eb5\"","full_name":"AmoebeLabs/swiss-army-knife-card","last_commit":"b19d4d8","last_updated":"2023-09-02T13:29:17Z","last_version":"v2.5.1","open_issues":46,"stargazers_count":206,"topics":["home-assistant-custom-card","lovelace-card","lovelace-custom-card","material-3","svg"],"last_fetched":1711397603.861906},"197960232":{"manifest":{},"description":"our groceries lovelace card","etag_releases":"W/\"7ba1c300aa71d013a278d20e19ab61759a38724f59a9c879632a5703d34aea18\"","etag_repository":"W/\"22110ad66f282078259dbab3632b3fbd745da48f02f811339a8f490e5d4b6109\"","full_name":"ljmerza/our-groceries-card","last_commit":"44a3c4e","last_updated":"2023-03-21T20:01:43Z","last_version":"1.6.1","open_issues":9,"stargazers_count":30,"last_fetched":1704773866.220652},"163363577":{"manifest":{"name":"Bar Card"},"description":"Customizable Animated Bar card for Home Assistant Lovelace","downloads":80202,"etag_releases":"W/\"7a8bc7e86cb657bb1a439fca81b840c47deb80286f78c0c318054e423f573c3a\"","etag_repository":"W/\"72250177d9d980f520ea56243dad3a57ed2938668bfd63d9a4465b6ae70b15b3\"","full_name":"custom-cards/bar-card","last_commit":"3bf4796","last_updated":"2023-09-29T13:53:10Z","last_version":"3.2.0","open_issues":71,"stargazers_count":335,"last_fetched":1712139268.170813},"689793414":{"manifest":{"country":["CZ"],"name":"Anchor Card"},"description":"An anchor (scroll to) card for Home Assistant!","downloads":1476,"etag_releases":"W/\"cf4f25de275c5e2cfbee1b5eea73685642bfb14703619b2c91f469f867be9bea\"","etag_repository":"W/\"9861eb734c0bcc37ddfe13224a656293df900700fe395b6bc1b9903e664005c3\"","full_name":"ShadowAya/anchor-card","last_commit":"54b4fa6","last_updated":"2024-02-28T18:54:03Z","last_version":"v3.1","open_issues":1,"stargazers_count":32,"topics":["lovelace-custom-card","scrolling"],"last_fetched":1710886434.06729},"667615978":{"manifest":{"name":"O365 Card"},"description":"A custom card for Home Assistant to show your Inbox, To Do and Teams Last Message from Office365","etag_releases":"W/\"b9d668f1efd770cfedb7839d8bb371be8451bab1c1d2b27c22fb786dd8a824ef\"","etag_repository":"W/\"366064c07ed414e6e8cc2bc8dec62ba6205458449eb2b54fcc1a45d8e2d126ef\"","full_name":"fixtse/o365-card","last_commit":"c05fbdd","last_updated":"2024-01-23T21:38:42Z","last_version":"v1.0.6","stargazers_count":9,"topics":["hacs-plugin","inbox","javascript","lovelace-custom-card","office365","outlook","teams","todo"],"last_fetched":1712009613.371685},"289188530":{"manifest":{"name":"Tesla style solar power card"},"description":"Home assistant power card mimicking the one tesla provides for the powerwall app.","etag_releases":"W/\"228350c0fe43f1b246b58bccb4ac06e7e175442565c4810461acb35f6db41861\"","etag_repository":"W/\"7ca0de52954c3522e7376fd37791d922cd7125402072d14cd8d7b0b976794075\"","full_name":"reptilex/tesla-style-solar-power-card","last_commit":"55b06a1","last_updated":"2023-11-29T12:31:39Z","last_version":"v1.3.2","open_issues":58,"stargazers_count":205,"topics":["battery","card","eletric-car","power","solar-energy"],"last_fetched":1712081962.379787},"244872232":{"manifest":{"name":"Paper Buttons Row"},"description":"Adds highly configurable buttons that use actions and per-state styling.","downloads":35158,"etag_releases":"W/\"92293d6f5b73ea092649377d8f0669b07823a1cdc9357c7b956b42ae6f5a2e5e\"","etag_repository":"W/\"4ff067012b6a5695a7e8c40d633c459709301554c7ad3270aa406fff2ac55ccf\"","full_name":"jcwillox/lovelace-paper-buttons-row","last_commit":"81bd9af","last_updated":"2024-04-04T04:00:32Z","last_version":"2.1.3","open_issues":56,"stargazers_count":253,"topics":["actions","buttons","haptic","paper"],"last_fetched":1712211448.097451},"238414582":{"manifest":{"country":["PL"],"name":"Custom Card for Warsaw ZTM Information"},"description":"Custom Lovelace card for Warsaw public transport","etag_releases":"W/\"37f99340fe7edfb3368b9275952bdfa43079b3e4e2e7c68b5e1b4f2c4980f37b\"","etag_repository":"W/\"381d3701575b79ce9df95c7cee5425062c2954b0fc87ede8850cea9836f9f630\"","full_name":"peetereczek/ztm-stop-card","last_commit":"7de7866","last_updated":"2024-03-15T14:39:51Z","last_version":"v0.2.0","stargazers_count":5,"last_fetched":1710792927.65515},"194824532":{"manifest":{"country":["FR"],"name":"M\u00e9t\u00e9o France Weather Card"},"description":"Weather Card with animated icons for Home Assistant Lovelace adapted to display all informations from M\u00e9t\u00e9o France integration","etag_releases":"W/\"8584a3237328038851223f20ae8e512b1f9e2f2d5358d891c7d11b9f7ded15fa\"","etag_repository":"W/\"4bf645299491180ec857486e777087cf9eb4dce09e621152baee241267182dce\"","full_name":"Imbuzi/meteo-france-weather-card","last_commit":"d03d5f8","last_updated":"2023-10-04T18:41:55Z","last_version":"v1.15","open_issues":11,"stargazers_count":26,"topics":["animated-icons","lovelace-card","meteo-france","weather"],"last_fetched":1712019531.498876},"236127727":{"manifest":{"name":"Camect Camera Card"},"description":"A custom card which exposes Camect video streams via the Home Assistant Lovelace interface. To use this card, you MUST have already installed the Camect HACS integration.","etag_releases":"W/\"fab3e76dbe6fa83d7bd028393c6849417bd4098b14a8f0c814c13237057efa5e\"","etag_repository":"W/\"eb5aafb348be8d57cba7fa7d4117d9fc2701890a68c74834b4cb5fcad0bdad53\"","full_name":"pfunkmallone/HACS-camect-custom_card","last_commit":"1a02464","last_updated":"2024-02-25T21:28:21Z","last_version":"2024.02.25","open_issues":2,"stargazers_count":5,"topics":["camect"],"last_fetched":1709216217.427882},"185304888":{"manifest":{},"description":null,"downloads":596,"etag_releases":"W/\"cc51ae55a6f2262cc90a63e7e5dbaf4145ae2e3d83841d7d62f365f0e663773d\"","etag_repository":"W/\"ba969ca3a0d5764723372881382c1029dbe5eeff779df5eac93b886e1a8b3870\"","full_name":"custom-cards/text-action-element","last_commit":"3c8ec01","last_updated":"2023-02-16T13:53:44Z","last_version":"0.3.0","open_issues":1,"stargazers_count":7,"last_fetched":1709288027.232196},"187245461":{"manifest":{},"description":"Entity Attributes","etag_releases":"W/\"84376be8bc39cd3951e6a777124f511980886f86cdde40ec036d2accc04e9298\"","etag_repository":"W/\"a8a8ea1a77ffc8014a6c5b13a0abdc9b4385b0a1c774635c50d091ae2390a345\"","full_name":"custom-cards/entity-attributes-card","last_commit":"9530504","last_updated":"2021-06-05T21:05:54Z","last_version":"0.1.2","open_issues":15,"stargazers_count":64,"last_fetched":1709288021.402155},"619284862":{"manifest":{"name":"Auto generating Mushroom dashboard strategy"},"description":"A strategy to automatically generate a dashboard using mushroom cards","downloads":3858,"etag_releases":"W/\"7ad38178d81c24efb8714e59027f4e971f53ed78b1fea295ce426be2d0d5d318\"","etag_repository":"W/\"bdac762d740826e8ef8c4973843d1b0d94411bb35ed693dfe19fc49e449b7de3\"","full_name":"AalianKhan/mushroom-strategy","last_commit":"d7f100d","last_updated":"2024-03-12T06:36:02Z","last_version":"v2.1.0","open_issues":15,"stargazers_count":311,"topics":["mushroom-strategy","strategy"],"last_fetched":1712060641.787575},"646272989":{"manifest":{"name":"TailwindCSS Template Card"},"description":"Custom card for Home Assistant that renders html code with TailwindCSS styles into the dashboard","downloads":1234,"etag_releases":"W/\"9c7a05679f9592bc2deb569a8df5b22e3a6cd228e493fe09c339ecea05e22e45\"","etag_repository":"W/\"66f62031dab765cf5278a5e2e49ead74aee67855b80750661d67d5f2c566aad5\"","full_name":"usernein/tailwindcss-template-card","last_commit":"f2bf762","last_updated":"2023-12-19T14:06:59Z","last_version":"v3.1.1","open_issues":3,"stargazers_count":32,"topics":["daisyui","dashboard","preact","tailwind","tailwindcss","twind"],"last_fetched":1710332682.133918},"373832981":{"manifest":{"name":"Digital Clock"},"description":"A custom digital clock card for Home Assistant","downloads":30957,"etag_releases":"W/\"59ed0714ce8afd541df5a6db2dd63d3284ca181dbf083c71aaa4573d4448e3cc\"","etag_repository":"W/\"803573ead9c8dda304587c1af85a17e8caf0a404a2002e685ec58a43d85e3270\"","full_name":"wassy92x/lovelace-digital-clock","last_commit":"ce7d40f","last_updated":"2024-01-16T17:48:48Z","last_version":"v1.2.4","open_issues":8,"stargazers_count":81,"topics":["lovelace-card"],"last_fetched":1711988303.913061},"649637656":{"manifest":{"name":"GivTCP Battery Card"},"description":"A simple battery card for Home Assistant for GivTCP users","downloads":8,"etag_releases":"W/\"8f2e9d5ddb51a51759166fa64f8eac72e1fe3d6f222e5950952c23860ea7bcc5\"","etag_repository":"W/\"59783e4b4419cbcc410681d152804c50e3f01a924761fb7e49ad62531900f6fe\"","full_name":"Codegnosis/givtcp-battery-card","last_commit":"86dbf3a","last_updated":"2024-03-28T12:18:35Z","last_version":"v0.2.4","stargazers_count":5,"topics":["givenergy","givtcp"],"last_fetched":1711635249.062342},"370997019":{"manifest":{"name":"WebOS Keyboard Card"},"description":"Type on your WebOS TV using this lovelace card","etag_repository":"W/\"ef4ed7297f5d146aaecc2d7749aa791f43a8bd5bf304c009e416049b620f2394\"","full_name":"bernikr/lovelace-webos-keyboard-card","last_commit":"81a66a9","last_updated":"2024-01-13T20:24:46Z","stargazers_count":6,"topics":["card","input-method","keyboard","remote","webos"],"last_fetched":1711736140.412465},"423082071":{"manifest":{"name":"Flipdown Timer Card"},"description":"Flipdown Timer Card for Home Assistant Lovelace","downloads":7410,"etag_releases":"W/\"aca9539ae81f0eba03f246b91946ca614996e352cf07abe8ccbbc870f20b1b17\"","etag_repository":"W/\"f170d0728676f23e3209bc173a7974550be6fcc88284cb66af5a61554d9f23b0\"","full_name":"pmongloid/flipdown-timer-card","last_commit":"944c027","last_updated":"2022-11-18T16:12:38Z","last_version":"v0.4","open_issues":12,"stargazers_count":64,"topics":["timer"],"last_fetched":1710792937.713365},"237532750":{"manifest":{"name":"Harmony Card"},"description":"A Home Assistant Lovelace Care for Harmony Integration","downloads":3318,"etag_releases":"W/\"a72511a039be725169c1070ae0171254cb92893e7cb293ea4b185867889a2268\"","etag_repository":"W/\"d61a0af2859284bca91af9a763e5e59e35be5ded3d55dd1f2f89822f8b3b9610\"","full_name":"sbryfcz/harmony-card","last_commit":"ce2a57a","last_updated":"2024-02-05T01:48:57Z","last_version":"v0.14.3","stargazers_count":101,"last_fetched":1709655442.35911},"572297252":{"manifest":{"name":"IrrigationProgram Custom Card"},"description":"Companion card for Irrigation-V5","downloads":1484,"etag_releases":"W/\"d116b4d557f97ed5fb55944837ef4cefe817fda67f11c24b0ac07014024a2069\"","etag_repository":"W/\"fab9e4fca4d383609f73cd9691afe3e035a5516919f247b8f5bb0b2ac85219b2\"","full_name":"petergridge/Irrigation-Card","last_commit":"8279010","last_updated":"2023-10-06T03:03:20Z","last_version":"V5.2.4","open_issues":2,"stargazers_count":14,"topics":["irrigation","irrigation-v5"],"last_fetched":1707186010.06661},"181124811":{"manifest":{"name":"Radial Menu Element"},"description":"\u2b55 Radial Menu Element","downloads":1242,"etag_releases":"W/\"39c787786426ad09c3429f66b094d42facc6388194f465d40beddb1c38586b56\"","etag_repository":"W/\"7bda85fa5b6326727af6762679933988c89923ca45c77f2f20504d23e7999740\"","full_name":"iantrich/radial-menu","last_commit":"c5dea6b","last_updated":"2023-01-20T00:58:16Z","last_version":"1.6.1","open_issues":5,"stargazers_count":62,"last_fetched":1707228832.559588},"197245179":{"manifest":{},"description":"Lovelace card for hass-aarlo integration.","etag_releases":"W/\"657b5c85609baa3bb85be8f536f3d134baf894937d84e5d86eabd5f4dd828d99\"","etag_repository":"W/\"56a1b217cbbce655db0f7ac6be86d02bd1904191bf655c3dad7ada3e9733d705\"","full_name":"twrecked/lovelace-hass-aarlo","last_commit":"eec8e48","last_updated":"2023-09-02T17:56:32Z","last_version":"v0.2.6.1","open_issues":37,"stargazers_count":73,"topics":["arlo","camera","lovelace-card","streaming"],"last_fetched":1710281642.717737},"431901513":{"manifest":{"name":"Fluid Level Background Card"},"description":"This card wraps any other cards and renders a fluid background behind them.","downloads":1513,"etag_releases":"W/\"100ccf9a9bec0b22c2b6bff6d166f6d8919e00c53e22b8c453b9136906910f5d\"","etag_repository":"W/\"707dde92b06bbe6446c5298f7101e04ad52b61c29dce4c2c9e02dae50652f151\"","full_name":"swingerman/lovelace-fluid-level-background-card","last_commit":"fe0fe41","last_updated":"2024-03-25T01:47:30Z","last_version":"v0.1.5","open_issues":10,"stargazers_count":22,"topics":["lovelace-card"],"last_fetched":1712045910.044339},"194037195":{"manifest":{},"description":"A custom card for displaying information provided by Beerbolaget (https://github.com/Ceerbeerus/beerbolaget).","etag_releases":"W/\"befba5197becd3d8a364effbdb46f33299cc37503dadfaf4179a0e60699810fe\"","etag_repository":"W/\"c738c716b887262391d524d53db1064974c27486fc45e4b79da69733668529e0\"","full_name":"Ceerbeerus/beerbolaget-card","last_commit":"ac8da42","last_updated":"2020-08-07T06:24:51Z","last_version":"0.1.55","stargazers_count":3,"last_fetched":1678386288.772862},"231145540":{"manifest":{"name":"NextBus Card"},"description":"A card giving richer public transit display using NextBus sensors.","downloads":323,"etag_releases":"W/\"a800ee26b27c78d90f609f4018204e608c1c0e1ed35bb6d8b814dabf4ae85a29\"","etag_repository":"W/\"6c312528093149fc8fbc1ae8c3be22c764e28284b48fd609cc53634ce67158ae\"","full_name":"dcramer/lovelace-nextbus-card","last_commit":"4f69bcb","last_updated":"2023-01-04T13:48:39Z","last_version":"0.2.0","open_issues":11,"stargazers_count":7,"topics":["lovelace-custom-card","nextbus","public-transit"],"last_fetched":1694196941.012227},"237812136":{"manifest":{"country":["RU"],"name":"Yandex Icons"},"description":"\u0418\u043a\u043e\u043d\u043a\u0438 \u042f\u043d\u0434\u0435\u043a\u0441 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432 \u0434\u043b\u044f Home Assistant","etag_releases":"W/\"eee7599cabe1eb6592f8f2842d1a4f38c8d0e58777fb445b9dfe7efff2cc7561\"","etag_repository":"W/\"5d7493469b0f05a93be7dd77051c2bef256904d0e7110b94a06921ec92585838\"","full_name":"iswitch/ha-yandex-icons","last_commit":"fa838b3","last_updated":"2023-12-07T20:36:35Z","last_version":"2023.12.0","open_issues":2,"stargazers_count":60,"topics":["icon-pack","icons","yandex"],"last_fetched":1708272960.920647},"449218690":{"manifest":{},"description":"Thermal Comfort custom icons for Home Assistant to accompany the MDI icons","etag_releases":"W/\"10b56c5244e9bfe6af4110542ad8a545ad6e86c8ea7662752f86af39f245882e\"","etag_repository":"W/\"96e798dae14cc06ea41fd523cec7fed913381e50c6c4f424c9732b35fabd9bbe\"","full_name":"rautesamtr/thermal_comfort_icons","last_commit":"a49201e","last_updated":"2022-01-29T15:14:16Z","last_version":"1.3.0","open_issues":1,"stargazers_count":30,"topics":["absolute-humidity","dew-point","dew-point-perception","frost-point","frost-risk","heat-index","icons","iconset","simmer-index","simmer-zone","thermal-perception"],"last_fetched":1709115372.220192},"292008305":{"manifest":{"name":"Steam Card"},"description":"A Home Assistant card for Steam integrations","etag_releases":"W/\"5f799d671f06584de85e7899ee6e07321265a9a9e2d4846c138fd92e8b6c6fc9\"","etag_repository":"W/\"bfcd1643a6b2ea27c3a0d79b73e0345084a1c0c52db5c90b801e40cee29f4cd3\"","full_name":"Kibibit/kb-steam-card","last_commit":"e794375","last_updated":"2023-04-21T15:14:57Z","last_version":"v1.1.1","open_issues":12,"stargazers_count":22,"topics":["card","steam"],"last_fetched":1712045861.573762},"256292682":{"manifest":{"name":"Battery State Card / Entity Row"},"description":"Battery state card for Home Assistant","downloads":26935,"etag_releases":"W/\"3e96dd30a582cd621d1cf0759a0030b3bf9ff219505d4be7d041f1dc30f7c259\"","etag_repository":"W/\"e9b45771f78643e64f0bcf112a729de0605e68fcb2da2c6de3f89b6dd84feabf\"","full_name":"maxwroc/battery-state-card","last_commit":"35344fc","last_updated":"2024-03-21T15:20:33Z","last_version":"v3.2.1","open_issues":19,"stargazers_count":777,"topics":["battery","lovelace-custom-card"],"last_fetched":1711980850.161254},"175927964":{"manifest":{"name":"Podcast Card"},"description":"\ud83c\udfa7 Podcast Player Card","downloads":1395,"etag_releases":"W/\"dc2742d0aa36de588cf80c40b0b5d5cfa2d8066950aea7281d80cff90dda661d\"","etag_repository":"W/\"9af7834df9260a20123fa21fc19a61bda010af3169de6f5c545eae4a85665b20\"","full_name":"iantrich/podcast-card","last_commit":"c07fba7","last_updated":"2023-07-11T01:43:27Z","last_version":"1.0.9","open_issues":5,"stargazers_count":22,"last_fetched":1697609898.685563},"497829589":{"manifest":{"name":"FR24 card"},"description":"Lovelace card for showing Dump1090 data from FR24 in Home Assistant","etag_releases":"W/\"bc1d168f1a7ca63dcbc4f2463e652cfa0a00032b8e47b13ce5f353e0dc9d5b02\"","etag_repository":"W/\"a7c2352e3c4e6a54038a9bd728c8c897bb3e78425cbe4d0c065d649377eb9150\"","full_name":"fratsloos/fr24_card","last_commit":"f534bb7","last_updated":"2024-02-29T03:12:39Z","last_version":"v0.7.1","open_issues":4,"stargazers_count":38,"topics":["ads-b","flightradar24","lovelace-card","mode-s"],"last_fetched":1712088824.637773},"444350375":{"manifest":{"name":"Mushroom"},"description":"Mushroom Cards - Build a beautiful dashboard easily \ud83c\udf44","downloads":10435,"etag_releases":"W/\"6497f576bdfeb90572093581ee156834a5f27129957d3e1f389ceb8d8bea3750\"","etag_repository":"W/\"04eb8d8fe0fb15313a9741ec1f92f44f9490d88451339bb6042295af5ed1941f\"","full_name":"piitaya/lovelace-mushroom","last_commit":"48db88d","last_updated":"2024-04-03T17:54:42Z","last_version":"v3.5.4","open_issues":317,"stargazers_count":3094,"topics":["card","mushroom"],"last_fetched":1712225716.0747},"188323494":{"manifest":{"name":"ha-floorplan \ud83d\udd8c\ud83c\udfa8 - Your imagination just become the new limit"},"description":"Bring new life to Home Assistant. By mapping entities to a SVG-object, you're able to control devices, show states, calling services - and much more. Add custom styling on top, to visualize whatever you can think of. Your imagination just became the new limit.","etag_releases":"W/\"bd53f359aac56876a9297a641aa948ff59a0162226e4be1aba7dbc071627fe93\"","etag_repository":"W/\"8d5b7cdc283465b8efba201ea8e2f2eed80c37b175a173a159a4a2d9c7cce7b8\"","full_name":"ExperienceLovelace/ha-floorplan","last_commit":"5536644","last_updated":"2024-03-28T17:09:54Z","last_version":"1.0.43","open_issues":6,"stargazers_count":985,"topics":["floorplan","lovelace-card","lovelace-floorplan","panel"],"last_fetched":1712175330.115284},"250552447":{"manifest":{"name":"Binary Control Button Row"},"description":"Provides a customizable button row for binary entities in Home Assistant","etag_releases":"W/\"466370b928df0880e4dedf05e4a471f4a00788e805c26ba2e5f25602c185d214\"","etag_repository":"W/\"6cb010af2614937d2f399144237913ff423a714de9fc6f15760f758ff5c1f818\"","full_name":"finity69x2/binary-control-button-row","last_commit":"2ad9d78","last_updated":"2023-05-11T00:30:49Z","last_version":"3.1","stargazers_count":20,"last_fetched":1688940796.06875},"214365813":{"manifest":{"name":"StarLine Card"},"description":"StarLine custom card for Home Assistant","etag_releases":"W/\"b49e733edfadb41db5703dd5651ce7ce5d7b889fbb5799e37f7391cd266dac06\"","etag_repository":"W/\"4e52ff530d20dd654fb0519969a3f2d6682494d70ec481e90fa845386b2cce77\"","full_name":"Anonym-tsk/lovelace-starline-card","last_commit":"97ebde2","last_updated":"2024-02-21T13:42:20Z","last_version":"v1.2.3","stargazers_count":24,"topics":["lovelace-custom-card","starline"],"last_fetched":1708532158.028281},"257005990":{"manifest":{"name":"LG WebOS Remote Control"},"description":"Remote Control for LG TV WebOS","downloads":15391,"etag_releases":"W/\"dbcdef9b1c862dd588f297c34ffb2435b6cf38c54a79d21b934c8d10584fbd71\"","etag_repository":"W/\"fededffeee2d3fc15edb2283bb3312dcf03c9fb73cddd1e7dfd87993140d8e02\"","full_name":"madmicio/LG-WebOS-Remote-Control","last_commit":"13e5f58","last_updated":"2024-01-07T14:18:07Z","last_version":"2.0.2","open_issues":74,"stargazers_count":370,"topics":["lg","remote","webos"],"last_fetched":1712211468.992671},"526408682":{"manifest":{"country":["US"],"name":"Team Tracker Card"},"description":"A Home Assistant frontend custom card that will display real-time updates for teams tracked with the ha-teamtracker integration. Has custom in-game layouts for football, baseball, basketball, hockey, soccer, golf, tennis, racing, and mma.","etag_releases":"W/\"f7bb6bae8598ebc636d5f30149ff69d4e6247165383d6d922447c68d2b88ec4b\"","etag_repository":"W/\"f79e514bf432e63f284d2c578da2c57b5b009a073201d8803fc0776f84c192f7\"","full_name":"vasqued2/ha-teamtracker-card","last_commit":"86ac4b8","last_updated":"2024-03-07T01:06:26Z","last_version":"v0.11.1","open_issues":1,"stargazers_count":57,"topics":["baseball","basketball","football","golf","hockey","mma","racing","scoreboard","soccer","sports","teamtracker","tennis","volleyball"],"last_fetched":1710944065.195714},"320381430":{"manifest":{"name":"Analog Clock"},"description":"An analog clock for Home Assistant Lovelace","etag_releases":"W/\"1937ef158d380b01e0529b11feafdcb544eede50e47c5229ff9991485b220053\"","etag_repository":"W/\"b671b7073ab447e244ba5e64179e367d7620bca78fdf1940a13176e7ab0bc5b8\"","full_name":"tomasrudh/analogclock","last_commit":"96b77b5","last_updated":"2024-03-29T00:05:55Z","last_version":"1.10","open_issues":3,"stargazers_count":16,"topics":["analog","analog-clock","assistant-lovelace","clock"],"last_fetched":1711880126.132982},"364769821":{"manifest":{"name":"Harmony Remote Card"},"description":"Harmony Hub Remote Control Card for Home Assistant","downloads":1890,"etag_releases":"W/\"2de40e7e83dc49aa02de60f46b4547428cdedf074ddd600f0cefa9ce8b161be6\"","etag_repository":"W/\"5d744f1a73a4c9333f884e4468e95a1b707b5bcf35cc9cd524f8331bd2711be3\"","full_name":"ljmerza/harmony-remote-card","last_commit":"de145a5","last_updated":"2024-01-04T03:05:31Z","last_version":"2.0.11","open_issues":7,"stargazers_count":14,"topics":["harmony","remote"],"last_fetched":1708736026.703231},"450898706":{"manifest":{"name":"Only Lock Lock Row"},"description":"Custom entity rows that prevent users from unlocking a lock, disarming a security system(alarm), opening a cover(garage door).","etag_releases":"W/\"a9f89fc34b9cdd11877d8f1837e69a92a2393def48d854ed156cee51d9ab6fac\"","etag_repository":"W/\"86e7688a5a8f3483e7c9e7c08f402064396e9d38c0791158bc051deb3972f221\"","full_name":"frozenwizard/onlylocklock","last_commit":"827e051","last_updated":"2023-05-21T19:31:15Z","last_version":"v0.6","stargazers_count":5,"topics":["alarm","cover","frontend","lock"],"last_fetched":1685847971.611873},"261291295":{"manifest":{"name":"Vacuum Card"},"description":"Vacuum cleaner card for Home Assistant Lovelace UI","downloads":20731,"etag_releases":"W/\"db3ca5387f33eea2eca99779e06c51e3c89e53e98c54c652df4fc715faf7e0bd\"","etag_repository":"W/\"4193d909fff61594124527c0ac3c2d01e026a79f7edb38b17d3f75948270352b\"","full_name":"denysdovhan/vacuum-card","last_commit":"8734b5d","last_updated":"2024-04-01T03:41:08Z","last_version":"v2.8.1","open_issues":24,"stargazers_count":831,"topics":["robot-vacuum","vacuum"],"last_fetched":1711952248.039786},"680112919":{"manifest":{"name":"Bubble Card"},"description":"Bubble Card is a minimalist card collection for Home Assistant with a nice pop-up touch.","etag_releases":"W/\"96ac776d1fe1b80aadbcabc1ec7a286e5d06b38a9dd1f1f74a0c13921e5f4746\"","etag_repository":"W/\"740892314abf25e0db9a26d945a4d1a0f181e2b17cf5d92a706cb5202ed731b4\"","full_name":"Clooos/Bubble-Card","last_commit":"d8abcf9","last_updated":"2024-04-04T06:15:01Z","last_version":"v1.7.3","open_issues":55,"stargazers_count":1155,"topics":["button","cards","cover","dashboard","design","frontend","lovelace-custom-card","minimalist","mobile-first","pop-up","popup","slider"],"last_fetched":1712225603.435094},"203294272":{"manifest":{},"description":"All your unused entities in a list","etag_releases":"W/\"79c082916bf8ac2574c8bb917b6625b8ddb67366a8cff7444a0ac79314feff31\"","etag_repository":"W/\"d1fe04cc3b1ce48aa12d9ade21edc429ece6511c93b00e91f046d55889899138\"","full_name":"custom-cards/unused-card","last_commit":"32a053e","last_updated":"2023-01-04T07:38:35Z","last_version":"1.1","open_issues":6,"stargazers_count":30,"last_fetched":1708755308.659149},"487680971":{"manifest":{"name":"Weather Radar Card"},"description":"A rain radar card using the tiled images from RainViewer","downloads":32452,"etag_releases":"W/\"779bf7a7d172c815ecd27aea48298a4ba49e4d4ce3275389582ef858f14c4835\"","etag_repository":"W/\"bc627b189b6272ea2ef07300e7b6438cccc0de3b5279e274ca27a7345a2b1785\"","full_name":"Makin-Things/weather-radar-card","last_commit":"1bfafae","last_updated":"2023-12-28T04:16:11Z","last_version":"v2.1.0","open_issues":26,"stargazers_count":180,"topics":["frontend","home-assistant-config","meteorology","radar","rainviewer","weather"],"last_fetched":1711880087.055904},"188572845":{"manifest":{"name":"Rotel Remote Card"},"description":"\ud83d\udd0a Rotel Remote Card","etag_releases":"W/\"d581208f96282d70ba30453b3980b6b258f74a7b292f7310f9b757399bdc042c\"","etag_repository":"W/\"288b6308ed9ee2537337311a41b04c1115d0bc84c51358fa5fe1593192aa5da7\"","full_name":"marrobHD/rotel-card","last_commit":"198daad","last_updated":"2022-05-25T19:39:13Z","last_version":"v.0.2.1","stargazers_count":5,"topics":["home-assistant-rotel-card","lovelace-card"],"last_fetched":1683217762.727194},"184658908":{"manifest":{"name":"GitHub Entity Row"},"description":"GitHub repository sensor data on entity rows in Home Assistant's Lovelace UI","downloads":2,"etag_releases":"W/\"5ea6c7a3e45b2ac238bd72a96e66b654ac9e0a4ce66ec46bcc54cf6434e06d13\"","etag_repository":"W/\"9280b8262bd7a7218de7913b3b28ecf102c55a76202b4d415fcd3f811f89d469\"","full_name":"benct/lovelace-github-entity-row","last_commit":"d8277af","last_updated":"2024-03-18T16:59:23Z","last_version":"v2.2.0","stargazers_count":23,"topics":["card","entity","entity-rows","github"],"last_fetched":1711167386.899006},"164887047":{"manifest":{},"description":"A Lovelace custom card for custom component Krisinformation is Home Assistant","etag_releases":"W/\"9d56eb6c66db11069bffcac5796ed229449056461da656081a17ac7a5119ba94\"","etag_repository":"W/\"fb5731ffc5c2dbf670dbcd275d0dfb5f552023d9cbbaccda1aee549b16b2273c\"","full_name":"isabellaalstrom/krisinfo-card","last_commit":"962f549","last_updated":"2020-09-18T17:45:35Z","last_version":"v1.3.0","open_issues":1,"stargazers_count":7,"last_fetched":1699539187.020665},"192732636":{"manifest":{},"description":"Weather Card with animated icons for Home Assistant Lovelace","etag_releases":"W/\"15290627d9de9786988f43990d75c8aaa6ecd2488720dd5014248b92a59986b0\"","etag_repository":"W/\"d017307f451387b6ac310e55487ffccd073216b210cddecc53b69449e11c17d7\"","full_name":"bramkragten/weather-card","last_commit":"b020ae5","last_updated":"2023-12-09T23:19:12Z","last_version":"v1.5.0","open_issues":92,"stargazers_count":459,"last_fetched":1712225603.437577},"216008446":{"manifest":{"name":"Logbook Card"},"description":"Logbook card for Home Assistant UI Lovelace","downloads":3185,"etag_releases":"W/\"b1df132ce14984087e4cb5d96999aeb8ce1bd43b2757648bfe93d2d2e9f8aedf\"","etag_repository":"W/\"2e95a81a0df524328201034928a1c201c1589d7fb7974d8e26e5de7bf2639af4\"","full_name":"royto/logbook-card","last_commit":"d8a20ac","last_updated":"2024-03-24T18:30:52Z","last_version":"2.5.5","open_issues":16,"stargazers_count":179,"last_fetched":1711988302.958668},"304967918":{"manifest":{"name":"Number Box"},"description":"Replace input_number sliders with plus and minus buttons","etag_releases":"W/\"8e43a541d0634e4de4754cfda02cd26bcf11cf7bf081873e38f64eb578028da1\"","etag_repository":"W/\"3faa25fa9c07bbf16a25b1a115ac3899f2b94531f8c7f9b2c7e72934b6214c38\"","full_name":"htmltiger/numberbox-card","last_commit":"43ef342","last_updated":"2024-03-07T13:45:50Z","last_version":"4.17","open_issues":4,"stargazers_count":99,"topics":["input","lovelace-card","lovelace-cards","lovelace-custom-card","number","numberbox-card","slider"],"last_fetched":1711901698.72734},"679827231":{"manifest":{"country":["SE"],"name":"HASSAM Card"},"description":"HASSAM Card for Home Assistant","etag_releases":"W/\"d12ea97ca37e76d55343effc433c8756bf6455e74f625ea6002a4fb1f269fd91\"","etag_repository":"W/\"4eef0c6dfa5e3f6f82ff0e2c9e8d08b1408798b9262d58d64caa4a22c417dda7\"","full_name":"kverqus/lovelace-hassam-card","last_commit":"d9a4471","last_updated":"2024-03-24T13:28:29Z","last_version":"v1.0.1","topics":["homeassistant-frontend","lovelace-card","lovelace-custom-card","ssam"],"last_fetched":1711296946.529236},"587494301":{"manifest":{"name":"TimBox Remote Control Card"},"description":"TimBox Remote Control card for Home Assistant","etag_repository":"W/\"c16a7f6fa42d2a51f2bd4e7770689cf2077dad9fe163d89942b7796ad7b3f206\"","full_name":"czz/timbox-remote-control-card","last_commit":"9ca129e","last_updated":"2023-02-20T21:12:25Z","open_issues":2,"topics":["remote-control","tim","timbox"],"last_fetched":1701295956.563514},"146335411":{"manifest":{"name":"RMV Card"},"description":"Custom card for the RMV component.","etag_repository":"W/\"d426c09cce892021aa3421d0b6957059f93471817325b7dc2272afc763939217\"","full_name":"custom-cards/rmv-card","last_commit":"b0b2af1","last_updated":"2023-10-09T10:55:52Z","open_issues":3,"stargazers_count":26,"last_fetched":1706739170.402471},"631525923":{"manifest":{"name":"lux-power-distribution-card"},"description":"Lovelace card for Home Assistant to replicate the power flow on the LuxpowerTek App and website.","downloads":879,"etag_releases":"W/\"777d52403a35396c59e0d27e6f4d70f1cda701fa17c2299f9fdb39f7e2c161f2\"","etag_repository":"W/\"169738e70d13a857299902f7f9ed603e585ccd986b5fed2d8686f9d816ad968d\"","full_name":"DanteWinters/lux-power-distribution-card","last_commit":"545817e","last_updated":"2024-02-08T07:52:26Z","last_version":"v1.4.0","open_issues":9,"stargazers_count":21,"topics":["power-distribution-module"],"last_fetched":1710152133.596289},"537793361":{"manifest":{"name":"MyJDownloader Card"},"description":"This Lovelace custom card displays downloads information provided by the MyJDownloader Integration","downloads":612,"etag_releases":"W/\"524f12825bdf31c77e5df0a3c5d8542cfe9d44ba51ba8f9af8acf7dcee3da3aa\"","etag_repository":"W/\"a38d46e864be04c05548d3260f314d838bc1a4287e62c6cc30ab2d215cc4a527\"","full_name":"Nyaran/myjdownloader-card","last_commit":"527d626","last_updated":"2024-04-02T04:01:25Z","last_version":"v1.3.1","open_issues":2,"stargazers_count":9,"topics":["hacs-custom","jdownloader","myjdownloader"],"last_fetched":1712031432.086197},"273405252":{"manifest":{"name":"Lightning Detector Card"},"description":"A Lightning Detection Display Card for Home Assistant Lovelace","downloads":4330,"etag_releases":"W/\"71b1975f35c827321b53f093dfee66419befb7929c37ab53160c8951ed4a2d3a\"","etag_repository":"W/\"f9fc7b2f18cf00dffd71af237a292e245a9d6d84dde1e2622aae9e00b66e9c65\"","full_name":"ironsheep/lovelace-lightning-detector-card","last_commit":"e017e81","last_updated":"2023-01-04T15:47:05Z","last_version":"v1.0.3","open_issues":14,"stargazers_count":21,"topics":["as3935","lovelace-card","lovelace-custom-card"],"last_fetched":1712045845.996909},"328957716":{"manifest":{"name":"Time Elapsed Card"},"description":"Home Assistant Lovelace Custom Card to calculate time elapsed/left","downloads":1715,"etag_releases":"W/\"71d1a3d7db57f899465d835b57416ae8dee7d9faf376e5f8257d01906de1f58e\"","etag_repository":"W/\"b57c671afad0ee14075a0b9024d73883c182d3f42c0287ec8b38460df60c1fac\"","full_name":"Kirbo/ha-lovelace-elapsed-time-card","last_commit":"84704a2","last_updated":"2021-06-03T08:58:27Z","last_version":"0.4.2","open_issues":3,"stargazers_count":27,"topics":["lovelace-custom-card"],"last_fetched":1708402679.35511},"497319128":{"manifest":{"name":"Kiosk Mode"},"description":"\ud83d\ude48 Hides the Home Assistant header and/or sidebar","downloads":11457,"etag_releases":"W/\"947a1910f27fa6636cf5a733155a328e9a10cee592439d70f8186af7dae9d23f\"","etag_repository":"W/\"645ce30232be982b9940a7c8a3d9fb466dfdbf1ac0429d9b7ca8e621220a0407\"","full_name":"NemesisRE/kiosk-mode","last_commit":"c2cfa81","last_updated":"2024-03-31T11:16:24Z","last_version":"v6.0.0","open_issues":1,"stargazers_count":249,"topics":["customization"],"last_fetched":1711980855.131459},"263112567":{"manifest":{"name":"AV Receiver control card"},"description":"panel card for av-receiver","downloads":1858,"etag_releases":"W/\"1e896b7749772b19c69df3a8c115e11970f1c08444d80a1375b519c7ee182e0e\"","etag_repository":"W/\"9cbf87212e527f692952f2aae39ca49dc890ab817430c1e60594a04b4f4e766c\"","full_name":"madmicio/ampli-panel-card","last_commit":"03d1aeb","last_updated":"2024-01-02T11:43:08Z","last_version":"2.1.1","open_issues":8,"stargazers_count":35,"topics":["av","card","receiver"],"last_fetched":1710195203.28996},"183499944":{"manifest":{"name":"Tracking Number Card"},"description":"Show Tracking Numbers from the Email Sensor for Home Assistant","downloads":2,"etag_releases":"W/\"6b51ee94c0099e9ed9b0c2741eb91a7d3b6fece61aefbc92b4477e1fb900b9e2\"","etag_repository":"W/\"9b1a549254ccaf7b7ffa39e8d4169edd0ba1fc47c96d1cc5004d1455b906580b\"","full_name":"ljmerza/tracking-number-card","last_commit":"3ee5756","last_updated":"2024-02-03T08:41:01Z","last_version":"3.0.4","open_issues":14,"stargazers_count":28,"topics":["email","tracking-mumbers"],"last_fetched":1711253846.899518},"187245511":{"manifest":{"name":"group-card"},"description":null,"etag_releases":"W/\"702b9815b0f85785467967b3ff1afed31c909d4a9c0d82875fdbc0c8ff5e7a5d\"","etag_repository":"W/\"ed9fb6e9e988bf4a45493ee21d6f85521f0473be09fc567dec95871a1e3036f6\"","full_name":"custom-cards/group-card","last_commit":"a5e69ab","last_updated":"2021-06-12T14:19:18Z","last_version":"0.0.6","open_issues":6,"stargazers_count":23,"last_fetched":1706099133.38697},"351472550":{"manifest":{"name":"Multiline Entity Card"},"description":"A custom entity card for Home Assistant that allows text to span multiple lines.","etag_releases":"W/\"5284500988dd26835bed49d6b8fcd8e1bad0547c6dd8a02b06c8865552d860d0\"","etag_repository":"W/\"3c08856b8e03bc02c1d78827ecf0e84ed2249b23840277a905534d643ee1ee04\"","full_name":"jampez77/Multiline-Entity-Card","last_commit":"4b38459","last_updated":"2023-01-31T09:32:25Z","last_version":"1.2.2","stargazers_count":14,"topics":["automation"],"last_fetched":1690265844.78395},"491465538":{"manifest":{"name":"custom-icons"},"description":"Several custom made and legacy icons, and icons collected all over the internet in 1 set, UI selectable.","downloads":8484,"etag_releases":"W/\"aed26be3e052f0877c8ab60bda9d186f54f148ec11135f7ebc8d6cdc6162f956\"","etag_repository":"W/\"66009c9fc1a8237cb2e4105c17366ec07c21ba90ab1f84c75b90a20ad4423b1e\"","full_name":"Mariusthvdb/custom-icons","last_commit":"6590f96","last_updated":"2023-09-06T15:56:26Z","last_version":"v0.3.7","open_issues":1,"stargazers_count":22,"topics":["custom","customization","icons","iphone","light","shutter","vacuum"],"last_fetched":1710407548.090224},"187247927":{"manifest":{},"description":null,"etag_releases":"W/\"1f9a1237565faed246914e4543f4b5ff22e6dab6d55bb0bf5fde9c1056c106bc\"","etag_repository":"W/\"5820c4f190126e1158862a2f56595c7e0f3200c877b7fb2714b8a542dfd8a9d1\"","full_name":"custom-cards/plan-coordinates","last_commit":"428ce44","last_updated":"2021-06-05T21:07:14Z","last_version":"0.1.1","open_issues":2,"stargazers_count":28,"last_fetched":1704903459.077356},"489295753":{"manifest":{"name":"Navbar Position"},"description":"Moves the Home Assistant dashboard navigation bar to the bottom of the screen","etag_repository":"W/\"e9476ac8e23ecfb3d5efbedf6655df08c817395d325c9dbab48133a63b44b967\"","full_name":"javawizard/ha-navbar-position","last_commit":"c5a38a1","last_updated":"2023-11-08T11:30:57Z","open_issues":5,"stargazers_count":21,"last_fetched":1709535827.398323},"169783299":{"manifest":{},"description":"Track your repo issues, starts, forks, and pull requests","downloads":843,"etag_releases":"W/\"e49ece263b2bf4edaed01f2809d0b9313aa91b1c9fe36c848ac4eb8162bb6a95\"","etag_repository":"W/\"de7bff699f75f64d76cfa8599377ac783240273b5c2d84de050ea7ea3f92d5e1\"","full_name":"ljmerza/github-card","last_commit":"7e4c628","last_updated":"2020-01-13T23:55:00Z","last_version":"1.4.1","stargazers_count":11,"last_fetched":1711167476.8227},"187245495":{"manifest":{"name":"gauge-card"},"description":null,"etag_releases":"W/\"d4dbbafaaf8de3899b7649a8753e29a883a34c697ccc5f67a6864e7fea6f6397\"","etag_repository":"W/\"ad53a559e366a3b3ca2317bc7a716b8cd080c5db02c2a567edc5b6964c47f1fd\"","full_name":"custom-cards/gauge-card","last_commit":"d390580","last_updated":"2022-05-01T20:12:53Z","last_version":"0.2.3","open_issues":10,"stargazers_count":44,"last_fetched":1711484035.543998},"567030726":{"manifest":{"name":"Default Dashboard"},"description":"Automatically set the default dashboard for all devices for Home Assistant","downloads":2921,"etag_releases":"W/\"602ff4f0e569eaa903e0263e960585d7cede88b884b4fd5f16bb55ccd556bb11\"","etag_repository":"W/\"7c5ae426e9ad52f329a8ce134c947234e92c0e8d7e42ebd842e4ea7db73169e2\"","full_name":"daredoes/default-dashboard","last_commit":"4f46d54","last_updated":"2023-05-03T07:44:41Z","last_version":"1.1.1","open_issues":6,"stargazers_count":30,"topics":["hacs-custom"],"last_fetched":1707401519.042636},"191663150":{"manifest":{},"description":"Provides a means to show a compact graphical control row for 2 or 3 speed fans in Home Assistant","etag_releases":"W/\"7e73c59310af6c6f6f34974d5a30fcd1061abae4051e394cdc9f23096719a8ec\"","etag_repository":"W/\"66739181f0300aacd316cb7f328d05474782af366b6f4e65397de520ca0b166a\"","full_name":"finity69x2/fan-control-entity-row","last_commit":"d09c3fc","last_updated":"2022-09-12T22:09:11Z","last_version":"2.3","stargazers_count":67,"last_fetched":1711995373.27614},"259126760":{"manifest":{"name":"Honeycomb Menu"},"description":"Honeycomb menu is a Home Assistant module (not a card) that can be applied to any lovelace card. When activated by the defined action on said card, the module will display a 'rounded' list of honeycomb buttons with an optional XY pad to make interfacing with lovelace more fluent","downloads":4102,"etag_releases":"W/\"a8ed054ac74ccbff270e02d4d3f072309ef2d88ee398882a95c5f039275efac0\"","etag_repository":"W/\"044e5d781599b496bb2104d548215061c42e6539c873b20c2b1d3fec7c3000f4\"","full_name":"Sian-Lee-SA/honeycomb-menu","last_commit":"3cd9c26","last_updated":"2024-01-03T02:05:18Z","last_version":"0.13.1","open_issues":3,"stargazers_count":173,"topics":["lovelace-module","menu","module"],"last_fetched":1712110956.977525},"139634406":{"manifest":{"name":"Dark Thermostat"},"description":"\ud83c\udf21 Thermostat card with a round and black feel to it","downloads":30697,"etag_releases":"W/\"83358982c8c6655df4507e476d6f772685698ae937922b5bf462ebb739b521f1\"","etag_repository":"W/\"8058b6c15027a40c88af005a06c91e18631ca5f06d7aa702e5e27516450e2b1b\"","full_name":"ciotlosm/lovelace-thermostat-dark-card","last_commit":"e3f0b5a","last_updated":"2023-11-07T08:23:27Z","last_version":"0.0.5","open_issues":29,"stargazers_count":714,"topics":["thermostat"],"last_fetched":1712031326.41111},"163446489":{"manifest":{"name":"Entur Card"},"description":"Home Assistant Lovelace card card for the Entur public transport component.","etag_releases":"W/\"bf7c0ef6ce5d22e1775bb4e5d5a26100a5adcf2d3ee38b9afb769593d161b30e\"","etag_repository":"W/\"bd3281d57000165b905991fdfe941648b0b5a8b3d67eb67e5f93c1173584443a\"","full_name":"jonkristian/entur-card","last_commit":"635c344","last_updated":"2023-10-18T23:37:42Z","last_version":"v2.0.0","open_issues":5,"stargazers_count":51,"topics":["entur","transportation"],"last_fetched":1712204297.791892},"373857882":{"manifest":{"name":"Entities Button Group"},"description":"A custom card for Home Assistant to group multiple buttons","downloads":234,"etag_releases":"W/\"9d6a02bb9800da17f9efe59c57a9b2c8f1db992fc5dba71a39c3816b4b2d8a75\"","etag_repository":"W/\"5c57a1bec7569e0cac8e8df2b5806ddcb46eb7bf1f05ffd2e1d63ccedd153fbe\"","full_name":"wassy92x/lovelace-entities-btn-group","last_commit":"7487ffb","last_updated":"2023-05-22T20:47:26Z","last_version":"v1.0.5","stargazers_count":8,"topics":["lovelace-card"],"last_fetched":1684858778.781824},"501725479":{"manifest":{"name":"Home Assistant Swipe Navigation"},"description":"\u2194\ufe0f Swipe through Home Assistant Dashboard views on mobile.","downloads":7545,"etag_releases":"W/\"f0152bf00c62da9df6bd34859beae9fc0c8131fa603773dda9f0562fe9b651e2\"","etag_repository":"W/\"e2fcf1b599c924f6795d66a22232bc27326b56ddc57881b28fdcf4d66b25530c\"","full_name":"zanna-37/hass-swipe-navigation","last_commit":"2b579c4","last_updated":"2024-03-24T16:58:21Z","last_version":"v1.13.3","open_issues":9,"stargazers_count":246,"topics":["navigation","swipe"],"last_fetched":1712168292.443239},"188686483":{"manifest":{"name":"Decluttering Card"},"description":"\ud83e\uddf9 Declutter your lovelace configuration with the help of this card","downloads":16899,"etag_releases":"W/\"1c3bf68f98ba248f67381c349acc29548ef327a96e3b7a4b862a5841102f11f1\"","etag_repository":"W/\"cbbfe0e92ca0bba50aecc719ae9b345cc6f1449defa3e9954eaf7cf2d41cb83d\"","full_name":"custom-cards/decluttering-card","last_commit":"5bb09ff","last_updated":"2024-03-16T23:01:28Z","last_version":"v1.0.0","open_issues":36,"stargazers_count":333,"last_fetched":1711772078.002109},"328132422":{"manifest":{"name":"Kodi Playlist Card"},"description":"This repository is used to contain the code of a kodi playlist card for Home Assistant and publish it via HACS","downloads":1,"etag_releases":"W/\"3bc92d708c32d02e02d199641ae3b74c0ef6a031599969ad6b1703f5da179051\"","etag_repository":"W/\"2ca5376461797c2912f7293dc91fdf7176868a3bfbb1da4fb753f90b1c7a8a21\"","full_name":"jtbgroup/kodi-playlist-card","last_commit":"1725cf9","last_updated":"2024-02-18T03:17:00Z","last_version":"4.5.1","stargazers_count":3,"topics":["kodi"],"last_fetched":1708229732.933969},"220679530":{"manifest":{"name":"HASL Traffic Status Card"},"description":"Lovelace Traffic Status Card for the HASL Platform","etag_releases":"W/\"83944d90005c06ab2240d015bf28b4963d871301fe28a63ad509781e9b0cf153\"","etag_repository":"W/\"14e9f2ae3a075020a3ccc7a3f70d2faf999449c608c4a7afb6cf8e4d023e277a\"","full_name":"hasl-sensor/lovelace-hasl-traffic-status-card","last_commit":"fdf9915","last_updated":"2020-03-04T12:20:16Z","last_version":"v2.3.1","open_issues":1,"stargazers_count":4,"topics":["hasl","sl","stockholms-lokaltrafik","traffic-status"],"last_fetched":1704903509.437334},"583449944":{"manifest":{"name":"Silent remotes card"},"description":"Remotes control card for home assistant","etag_repository":"W/\"8344bffca9503963b6aa66e630b9ee51d6c61487d7f9d0600a5d1c048b0b368d\"","full_name":"silentbil/silent-remotes-card","last_commit":"d3e4152","last_updated":"2023-10-15T07:56:51Z","open_issues":2,"stargazers_count":6,"topics":["broadlink","card","remote","remote-control","smartir"],"last_fetched":1709928846.692146},"708527086":{"manifest":{"name":"Card to display bar chart oriented to display power sensors"},"description":"A Home Assistant lovelace card to display bar chart oriented to display power sensors","downloads":3821,"etag_releases":"W/\"26aac624b284514702ae0ff254a7382d5f61b67ccc91af3318389a4dc4b89576\"","etag_repository":"W/\"6f77fdfbe445e61800fac524906dc6344b8b522aef58aa0f68eb7a0bbd5ad92a\"","full_name":"tdvtdv/ha-tdv-bar","last_commit":"5257fb0","last_updated":"2024-03-10T18:11:36Z","last_version":"v1.1.7","open_issues":10,"stargazers_count":40,"topics":["lovlace-card"],"last_fetched":1712182432.588643},"193262086":{"manifest":{},"description":"Home assistant remote control","etag_repository":"W/\"d6063afb518c148b35ebd619892ffe7a48bf2d107a6ad2983a7cb859b9d2a375\"","full_name":"dimagoltsman/content-card-remote-control","last_commit":"f4acaf4","last_updated":"2022-01-20T20:58:11Z","stargazers_count":4,"last_fetched":1678825633.075894},"366862031":{"manifest":{"name":"Custom brand icons"},"description":"Custom brand icons for Home Assistant","etag_releases":"W/\"fce627b58a81a0e2ed17d6ab5880b7192a2224c8b69e82808b9523e2c857a586\"","etag_repository":"W/\"8155fce9d4ce30ca450f15dbcbe7edba6c313df17b4281c5b007bc3becbe8b5a\"","full_name":"elax46/custom-brand-icons","last_commit":"e5a0efc","last_updated":"2024-04-02T22:10:30Z","last_version":"2024.4.1","open_issues":3,"stargazers_count":701,"topics":["custom-icons","icons","icons-pack","iconset","ikea","philips-hue","xiaomi"],"last_fetched":1712218648.012021},"587057164":{"manifest":{"name":"Magic Home Party Card"},"description":"A Home Assistant custom card for managing Magic Home lighting effects","downloads":207,"etag_releases":"W/\"1cfb098806e2a23485ca1a3820786acecad5737ca34e8b84272cb0950f6968b2\"","etag_repository":"W/\"9b150cbf4cc11699932d8156a3728645980b4de0d74c206e5b901efb12786e6e\"","full_name":"kizza/magic-home-party-card","last_commit":"bc11331","last_updated":"2024-03-03T22:23:08Z","last_version":"v0.1.4","open_issues":1,"stargazers_count":2,"topics":["magic-home"],"last_fetched":1709513776.025107},"341707887":{"manifest":{"name":"Pollen Information Card for Hungary "},"description":"Home Assistant custom Lovelace card for pollen information in Hungary","downloads":833,"etag_releases":"W/\"dde194be9eaca74ee56bd34e8ff7fa0974cf42043bb6a5ed86da4baaebf6abad\"","etag_repository":"W/\"235e6c63439027f917e889501508f1c81e3fecaa1307289349dab0dd8e63b530\"","full_name":"amaximus/pollen-hu-card","last_commit":"61de905","last_updated":"2023-04-20T09:35:25Z","last_version":"0.0.1","stargazers_count":11,"topics":["hungary","lovelace-custom-card"],"last_fetched":1694549592.41898},"640244449":{"manifest":{"name":"Pool Monitor Card"},"description":"The \"Pool Monitor Card\" is a home assistant plugin that display information of 1 to 12 pre-defined sensors of your swimming pool : temperature, pH, ORP levels and TDS but also if you need them : salinity, CYA, calcium, phosphate, alkalinity, filter pressure , free chlorine, total chlorine","etag_releases":"W/\"d84e170985c0b5701251318b14b21388f89a416718d9d2520190d413f822817e\"","etag_repository":"W/\"6cec9704916276fac683484732d321167e79a759f4f8075d7be2ae78ee70474d\"","full_name":"wilsto/pool-monitor-card","last_commit":"48cf94b","last_updated":"2023-10-09T19:54:00Z","last_version":"v1.5.1","open_issues":24,"stargazers_count":38,"topics":["lovelace-custom-card","monitor","pool"],"last_fetched":1712045911.054261},"384434522":{"manifest":{"name":"Hass Hue Icons"},"description":"Additional vector icons for home assistant to model Philips Hue bulbs and fixtures. ","downloads":11854,"etag_releases":"W/\"b08f74df56f058ba7c840a95e6174bff82a1ee6eee563b905ec3c9ce84d86504\"","etag_repository":"W/\"7f8f0ed04d67eea0a568891b8fc6eff238ae5c0561124abf763c9ff11d7e4323\"","full_name":"arallsopp/hass-hue-icons","last_commit":"4604f9a","last_updated":"2023-12-13T18:53:17Z","last_version":"v1.2.53","open_issues":24,"stargazers_count":273,"topics":["custom-icons","hue","hue-lights","icons","iconset","philips-hue","svg"],"last_fetched":1712074582.31432},"391372854":{"manifest":{"name":"Alarmo Card"},"description":"Home Assistant card for controlling the Alarmo component","downloads":22841,"etag_releases":"W/\"d3f4b30aac88fd8217cf1c2d636c62a60acabfefa405bc32f53aeb3714d1bfe5\"","etag_repository":"W/\"0972510edbcd8fd277a83cf3f0c82a5c3ea92ea0e667a9de527c4532d409c10f\"","full_name":"nielsfaber/alarmo-card","last_commit":"36c6edd","last_updated":"2024-02-02T04:48:56Z","last_version":"v1.5.1","open_issues":1,"stargazers_count":88,"topics":["alarm","alarmo","assistant","card","home","security"],"last_fetched":1711846904.353753},"524783308":{"manifest":{"name":"Shutter Row"},"description":"Home Assistant Lovelace Shutter Row Card","downloads":2786,"etag_releases":"W/\"e8baa50c6e9fb55fa2fd2f82c6ccc0c99592ff8e0338dfecdaca446319f19185\"","etag_repository":"W/\"cf01abd43eaf4aeb3a423d78a56afcb82981e46b3fbe0f0494ef6af0cc02d049\"","full_name":"berrywhite96/lovelace-shutter-row","last_commit":"fd9de52","last_updated":"2024-01-24T18:03:45Z","last_version":"v0.3.6","open_issues":6,"stargazers_count":18,"topics":["home-assistant-card","lovelace-card"],"last_fetched":1711759987.661476},"536329656":{"manifest":{"name":"Firemote Card"},"description":"Apple TV, Amazon Fire TV, Fire streaming stick, Chromecast, NVIDIA Shield, onn., Roku, Xiaomi Mi, and Android TV remote control card for Home Assistant","etag_releases":"W/\"43e971bd644a795be3e9330e76235cf90533b92cffc5414a1fb3bdb99022dc66\"","etag_repository":"W/\"3a417b6b1d537a188bdfc9c22a7fa36fabe11945bcd6831f127fba69cd9cdd29\"","full_name":"PRProd/HA-Firemote","last_commit":"b4118d1","last_updated":"2024-04-03T01:15:27Z","last_version":"v3.3.1","open_issues":7,"stargazers_count":258,"topics":["amazon-fire","amazon-fire-cube","amazon-fire-stick","android","android-debug-bridge","android-tv","apple-tv","chromecast","chromecast-4k","nvidia","nvidia-shield","onn","remote-control","roku","roku-tv","shield","xiaomi","xiaomi-mi"],"last_fetched":1712218732.208808},"352399227":{"manifest":{"name":"KNX User Forum Icon Set"},"description":"Icon set from KNX User Forum for Home Assistant. The icon set contains more than 900 icons for home automation.","etag_releases":"W/\"5b9fbded164802bfd81d8b2b5f4a19ace10a51a160c35a11042344db72b4d784\"","etag_repository":"W/\"81404c424f096dcbd6612a6f0d015d7fbdf55457c03cfb94650f1e52984b3363\"","full_name":"mampfes/ha-knx-uf-iconset","last_commit":"a7721ad","last_updated":"2021-12-15T18:26:29Z","last_version":"1.1.0","open_issues":3,"stargazers_count":8,"topics":["icons","iconset"],"last_fetched":1705313796.480165},"215633404":{"manifest":{"name":"Restriction Card"},"description":"\ud83d\udd12 Apply restrictions to Lovelace cards","downloads":9637,"etag_releases":"W/\"dd086a12e5b457a7c5fdfdbe4c7479d5b44092acf846336574281c072cc80bec\"","etag_repository":"W/\"d3b021e9a2b4a81db5556b635a67ce74793f3abc7f343cde920adcd22a9cf778\"","full_name":"iantrich/restriction-card","last_commit":"8011b56","last_updated":"2023-07-06T19:12:35Z","last_version":"1.2.9","open_issues":8,"stargazers_count":233,"topics":["security"],"last_fetched":1711296925.436102},"286270157":{"manifest":{"name":"Scheduler Card"},"description":"HA Lovelace card for control of scheduler entities","downloads":41600,"etag_releases":"W/\"0c456e974be72ab3d72984ea44faf6d18bb20b9e031ac85fabe898cdd88d3fad\"","etag_repository":"W/\"b09e50cbb21c2698c12e52edae03977a4167178f886b43137419eadb14aa3ee0\"","full_name":"nielsfaber/scheduler-card","last_commit":"b530f3d","last_updated":"2024-03-26T20:20:39Z","last_version":"v3.2.12","open_issues":17,"stargazers_count":805,"topics":["assistant","automation","card","home","schedule","scheduler","sunrise","sunset","week","weekly"],"last_fetched":1712153643.001876},"158654878":{"manifest":{"name":"Simple Thermostat"},"description":"A different take on the thermostat card for Home Assistant \u2668\ufe0f","downloads":69387,"etag_releases":"W/\"a33d73267fa5b3b6ae40a8b02e784561050978fabf02e71d37996a476d25933f\"","etag_repository":"W/\"3e477df2d6c402bc1f32296c1e7f40c71c7d8201191515d6abf805c9066875e4\"","full_name":"nervetattoo/simple-thermostat","last_commit":"eb0c0d5","last_updated":"2023-12-29T14:36:54Z","last_version":"v2.5.0","open_issues":147,"stargazers_count":704,"topics":["polymer-3"],"last_fetched":1712125072.007601},"693656182":{"manifest":{"name":"Media Source Image Card"},"description":"A Lovelace custom card for showing images stored in Media Source","etag_releases":"W/\"b39058defcd9c8e9b481997ae2abb4888def1a1f5d381f23338f0952804b696b\"","etag_repository":"W/\"7c1bee6b85d69f625ae8d83a0e6b3bbff9cab81f8e02720a2c4353d889d540f4\"","full_name":"luixal/lovelace-media-source-image-card","last_commit":"f050363","last_updated":"2024-03-08T12:17:44Z","last_version":"v0.2.4","stargazers_count":11,"topics":["lovelace-card","lovelace-cards","lovelace-custom-card"],"last_fetched":1710447306.479404},"180229356":{"manifest":{"name":"Simple Vacuum Card"},"description":"Simple card for various robot vacuums in Home Assistant's Lovelace UI","downloads":24013,"etag_releases":"W/\"d174d1b3b72065d3589a1151b1e703c4e472e58a0fda6380b2c1f060abacdd08\"","etag_repository":"W/\"765afece4470355aff1e07619cf1031701b063646f7d170cd30034e5a119608b\"","full_name":"benct/lovelace-xiaomi-vacuum-card","last_commit":"44d53f9","last_updated":"2023-01-18T07:18:33Z","last_version":"v4.5.0","open_issues":25,"stargazers_count":253,"topics":["card","roborock","robot-vacuums","vacuum","xiaomi","xiaomi-vacuum"],"last_fetched":1711872958.062606},"307058107":{"manifest":{"country":["CN"],"name":"Car card"},"description":"\u8f66\u8f86\u4eea\u8868\u76d8","etag_repository":"W/\"c6194627a8f2e6d981957bd774e5201ced2095977337ee9c575f5c6c3d0501f2\"","full_name":"fineemb/lovelace-car-card","last_commit":"a28bca5","last_updated":"2022-06-02T18:44:43Z","open_issues":2,"stargazers_count":6,"topics":["car","lovelace-custom-card","lynkco"],"last_fetched":1708236968.582562},"345753205":{"manifest":{"name":"Fan Percent Button Row"},"description":"Frontend plugin to control fans in Home Assistant using percent values for speeds","etag_releases":"W/\"4c621b16c12e480caf0fd0f18fac1630a3740e13c10760db8940e3c4329d84bf\"","etag_repository":"W/\"ca12c1da166456a36d3ea10a07d1b464f40c0a6867f7fa343c07dac24e88cb1a\"","full_name":"finity69x2/fan-percent-button-row","last_commit":"03744d8","last_updated":"2023-05-11T00:29:06Z","last_version":"3.1","open_issues":4,"stargazers_count":31,"topics":["assistant","fan","home","percent","speed"],"last_fetched":1711995373.38041},"639953950":{"manifest":{"name":"Energy Period Selector Plus"},"description":"An upgraded Energy Date Selection Card for Home Assistant, with added customizability, while maintaining the Energy Dashboard's original design.","downloads":6475,"etag_releases":"W/\"ca980950f0fc5f54fa6b0fa6a8b592a7131286df9735e1e9e43e00d309285b90\"","etag_repository":"W/\"e7b95cc0527cf7fa72bc58aeb3ebe7b6b71dcf604e32b9000b2a6901c2bef921\"","full_name":"flixlix/energy-period-selector-plus","last_commit":"ae5b194","last_updated":"2024-02-20T08:28:28Z","last_version":"v0.2.3","open_issues":18,"stargazers_count":44,"topics":["automation","dashboard","date","datepicker","picker","plus","time"],"last_fetched":1711419550.021817},"195671060":{"manifest":{"name":"Lovelace Grocy Chores Card"},"description":"A card to track chores and tasks in Grocy.","downloads":2249,"etag_releases":"W/\"cfe6263f6ba307cff475f0b01dd1b685cf85419e592d287642c06c2e5b27898b\"","etag_repository":"W/\"7183aefa2fc39c459ed444ae663a935b17fb5138dcf3f4c31e7e1eb69bd422c1\"","full_name":"isabellaalstrom/lovelace-grocy-chores-card","last_commit":"2d01512","last_updated":"2024-03-18T18:59:34Z","last_version":"v3.8.2","open_issues":15,"stargazers_count":123,"last_fetched":1712139331.367678},"172177543":{"manifest":{"name":"Config Template Card"},"description":"\ud83d\udcdd Templatable Lovelace Configurations","downloads":64522,"etag_releases":"W/\"3d420cb126887a5005908442716e60b1a8e45b113f6ad98422a4c5e021a6f47e\"","etag_repository":"W/\"c55b056560500c06bf5c060917028fc241d56e127e070b781682bb0974e19bf0\"","full_name":"iantrich/config-template-card","last_commit":"bcbc09b","last_updated":"2024-01-09T19:44:02Z","last_version":"1.3.6","open_issues":16,"stargazers_count":402,"last_fetched":1711908943.143212},"458491675":{"manifest":{"name":"Nicehash Excavator Monitor Card"},"description":"Home Assistant UI Card for Nicehash Excavator Monitor integration","etag_releases":"W/\"a7611ca98b8828d5f243815a96af0b3d367c6baf77aa561942e6fb6d95fc8fa5\"","etag_repository":"W/\"4fbd1a2c01cba1f33aa2e1fad6eff433f04dc4d717b300cefa3bf8dbdf2477d2\"","full_name":"MesserschmittX/lovelace-nicehash-excavator-monitor-card","last_commit":"f90799e","last_updated":"2022-05-15T07:59:36Z","last_version":"v0.1.4","topics":["excavator","mining","nicehash"],"last_fetched":1678386392.047012},"165156754":{"manifest":{},"description":"\ud83d\udcb5 Personal Capital Card","etag_releases":"W/\"05ae758edfc541b55ff1185db6500ffd936d0be69a8d8bad2ceb525f59a757df\"","etag_repository":"W/\"78cf1adb9f56d063f0fa684597a7f51ff9dab2f922f01ba9ec09ea52487b9bbb\"","full_name":"custom-cards/pc-card","last_commit":"033af45","last_updated":"2019-10-21T03:36:31Z","last_version":"v0.0.3","stargazers_count":7,"last_fetched":1706811321.810187},"313269367":{"manifest":{"name":"kibibit Better Graph Colors"},"description":"Replace the history graph colors with a material design color palette.","etag_releases":"W/\"eac46afbd874fb5881041c18106f441ac308b65f4c9340741e1f36f2a6a79aec\"","etag_repository":"W/\"65ec8860b543377bc25ffed5cd292a90ecf30f0b90f827ec9d298124a51b17d2\"","full_name":"Kibibit/kb-better-graph-colors","last_commit":"bf18c68","last_updated":"2022-06-19T17:37:46Z","last_version":"v1.1.0","open_issues":4,"stargazers_count":10,"topics":["color-scheme","graphs","palette"],"last_fetched":1704903531.223445},"596085141":{"manifest":{"name":"octopus-energy-rates-card"},"description":"This lovelace card for Home Assistant displays the Octopus Energy rate prices per each 30 minute slot","etag_releases":"W/\"c79aaf0520587bf9974cdf13272aab7465e770d5d04cf9d91c0317d7c62f580c\"","etag_repository":"W/\"39f8375b4ad39206c2b4901b3e529a82c66d76f4f6bf6f0ee472230a1fe549d0\"","full_name":"lozzd/octopus-energy-rates-card","last_commit":"e8c401a","last_updated":"2024-03-22T23:15:34Z","last_version":"v0.7.0","open_issues":12,"stargazers_count":51,"topics":["electricity","energy","octopus","octopus-energy","octopus-energy-agile","octopusenergy","rates"],"last_fetched":1711649835.729665},"173955605":{"manifest":{"name":"Spotify Lovelace Card"},"description":"Spotify playlist card for Home Assistant card","etag_releases":"W/\"d8471bd355851f302b686e30959703c767dc6a10e34e5859aac8e4a41ee0cb32\"","etag_repository":"W/\"13963d83c7caec0611592bbf23a449ed70d32d138a312e302211bb3addb6a58b\"","full_name":"custom-cards/spotify-card","last_commit":"4297715","last_updated":"2023-05-29T10:51:50Z","last_version":"v2.4.0","open_issues":58,"stargazers_count":354,"last_fetched":1710987675.140012},"326033921":{"manifest":{"name":"Toggle Control Button Row"},"description":"A one-button control row for any Home Assistant binary entity","etag_releases":"W/\"3ed67b1819c9e16ce7c8b718276112c0a0e05266c9a08892b5dac9fc81edb140\"","etag_repository":"W/\"b39ca52b4ab06932cf123978fd53377b5010a7e6ad8ea05a817727106ae74d7e\"","full_name":"finity69x2/toggle-control-button-row","last_commit":"d063bf3","last_updated":"2023-05-11T00:29:43Z","last_version":"3.1","stargazers_count":12,"topics":["button","toggle"],"last_fetched":1688940796.753104},"618081815":{"manifest":{"name":"Power Flow Card Plus"},"description":"A power distribution card inspired by the official Energy Distribution card for Home Assistant","downloads":57458,"etag_releases":"W/\"54c3a2d46a45c9bcc3ea9916ae6d300132f446ab6561ba0497e4d05b0b217e89\"","etag_repository":"W/\"71f5eb9fbca0e2f2f80e6b975f28d8d40faaa8d9fa665b542f58f04b229e8539\"","full_name":"flixlix/power-flow-card-plus","last_commit":"8f8e440","last_updated":"2024-03-16T16:32:40Z","last_version":"v0.1.8.1","open_issues":74,"stargazers_count":391,"topics":["animation","card","cards","custom","energy","flow","plus","power"],"last_fetched":1712218658.650276},"234961647":{"manifest":{"name":"Climate Mode Entity Row"},"description":"Climate mode entity for Lovelace","etag_releases":"W/\"74009cd88b8704c38691b7bf510efea06ef1ed3c6b074ce3161e1f693fe9d303\"","etag_repository":"W/\"7aa736a77b91badcfa293f9c23b459b4ca329a2c2ce92b92fa33409b9c0e9887\"","full_name":"piitaya/lovelace-climate-mode-entity-row","last_commit":"ee50b61","last_updated":"2022-06-27T07:31:07Z","last_version":"v1.4.0","open_issues":5,"stargazers_count":81,"topics":["card","thermostat"],"last_fetched":1709288122.111657},"489457357":{"manifest":{"name":"Minimalistic Area Card"},"description":"A minimalistic area card with sensors and buttons.","downloads":10826,"etag_releases":"W/\"3f7d5b1f2114f3b894fc79c880014a0764b22f6c60505891b0442a14586d0843\"","etag_repository":"W/\"90676b3e1c2abd2b697761eaa63ac5375336d8deac3faf47376e9979d6dbaab6\"","full_name":"junalmeida/homeassistant-minimalistic-area-card","last_commit":"88344c4","last_updated":"2024-04-01T10:30:52Z","last_version":"v1.1.16","open_issues":6,"stargazers_count":99,"topics":["area-card"],"last_fetched":1712045856.175839},"141952963":{"manifest":{"name":"Circle Sensor Card"},"description":"A custom component for displaying sensor values as cards or elements","etag_releases":"W/\"fc3056c70e263e0617d70f057fa5d5e137a662a69ad00eed7707981534b1041e\"","etag_repository":"W/\"0b24baeca1e5b7617322512fb126f6ca2ba2705e61d29ed45a95bc713a4f9bce\"","full_name":"custom-cards/circle-sensor-card","last_commit":"4964b06","last_updated":"2022-06-02T04:10:16Z","last_version":"1.2.2","open_issues":22,"stargazers_count":166,"last_fetched":1709288016.517622},"609593305":{"manifest":{"name":"Rain Gauge Card"},"description":"A Lovelace card that shows the rain gauge for Home Assistant","downloads":5440,"etag_releases":"W/\"1cbe080b291e2d3f0a7447ca1fc5fd099fca2766f9c091f97a072f9b73d4666c\"","etag_repository":"W/\"c317df98703efc4461ed323177342cf0673e475ef09863750240f481c4b6e194\"","full_name":"t1gr0u/rain-gauge-card","last_commit":"eb5aad9","last_updated":"2024-01-05T20:45:37Z","last_version":"v1.4.0","open_issues":6,"stargazers_count":33,"topics":["uv-index"],"last_fetched":1712045910.023339},"363428919":{"manifest":{"name":"Plex Meets Home Assistant"},"description":"Custom card which integrates plex into Home Assistant and makes it possible to launch movies or tv shows on TV with a simple click","etag_releases":"W/\"d25545ca0b3d1e3f16527587438ed24f29d16fa995fdf367e9faf93b60ec8705\"","etag_repository":"W/\"bcbbced352cac23e0b0b9359c876a8e06522fae200012f0ed5264c38a904f40a\"","full_name":"JurajNyiri/PlexMeetsHomeAssistant","last_commit":"e1e9fbf","last_updated":"2024-01-12T18:09:30Z","last_version":"3.6.11","open_issues":20,"stargazers_count":103,"topics":["adb","androidtv","hacktoberfest2021","homeassistant-custom-component","kodi","plex","plexmediaserver","tv"],"last_fetched":1711527492.579319},"195497310":{"manifest":{"country":["IT","FR","DE","NL","PL","HE","RU","DA","UA","EN"],"name":"Custom Animated Weather Card"},"description":"Custom Animated Weather Card for any weather provider","etag_releases":"W/\"d60f2e8ea4091f5061b78ff1a6a7d23a708e5642d3c4b2800d7bb932255ad30d\"","etag_repository":"W/\"97ca7bf484393e045ccf64fa98dfe47f014f7cc9e55f0f81959c422044ce55a2\"","full_name":"DavidFW1960/bom-weather-card","last_commit":"01a3ddb","last_updated":"2023-03-16T00:34:49Z","last_version":"1.1.4","open_issues":1,"stargazers_count":155,"topics":["bom","weather-forecast"],"last_fetched":1711534447.324964},"264796130":{"manifest":{"name":"Pandora CAS card"},"description":"Pandora lovelace card for Home Assistant","etag_releases":"W/\"fbd934a023a24846a4e083c51c05f5d38321f151b24d93b0dcd7a7fbbf3e1cc7\"","etag_repository":"W/\"7b4e1a4b12435bd7795da0d4e2f164ecf9794be9bb2258ad74600cd7b9f6cdb8\"","full_name":"turbulator/pandora-cas-card","last_commit":"32ad046","last_updated":"2020-10-03T15:41:00Z","last_version":"0.2","open_issues":1,"stargazers_count":4,"topics":["lovelace-custom-card","pandora"],"last_fetched":1708640040.825234},"168570875":{"manifest":{},"description":"fitbit-card for lovelace","downloads":2428,"etag_releases":"W/\"f39dd01b6149795b4bed0b57eb90e43652d36dd775f507bb24167e3287bb73d8\"","etag_repository":"W/\"4a3ee4cd70c35d1ebf4ab238265cf43d6abd46ad64cd4c8b3c98f31eb1cd44f2\"","full_name":"ljmerza/fitbit-card","last_commit":"9ead350","last_updated":"2020-07-10T20:55:32Z","last_version":"1.1.1","open_issues":3,"stargazers_count":25,"last_fetched":1711570533.371845},"303857065":{"manifest":{"name":"Battery Entity Row"},"description":"Show battery states or attributes with dynamic icon on entity rows in Home Assistant's Lovelace UI","downloads":14493,"etag_releases":"W/\"45468d75f6c725b59bd23d034d9cd5af3d5cf461dad490bfe5e29afd3b8c0ecf\"","etag_repository":"W/\"787c90c1ff3371e250e988deb7bfca362470f479517e507e18e532fbb8196619\"","full_name":"benct/lovelace-battery-entity-row","last_commit":"e7d1eab","last_updated":"2021-03-12T15:50:43Z","last_version":"v1.3.1","open_issues":3,"stargazers_count":69,"topics":["attribute","battery","card","entity","entity-rows","state"],"last_fetched":1711542197.241194},"577071460":{"manifest":{"name":"pH meter"},"description":"Ph meter, temperature, tds, ec cl & salinity for fish tank and swimming pool","etag_repository":"W/\"abcb815cd4b45f148024582a10a1e3e51928e64fc8bd68853cd2f032e1e9b065\"","full_name":"madmicio/ph-meter-temperature","last_commit":"6926ba8","last_updated":"2023-04-14T11:33:19Z","open_issues":8,"stargazers_count":12,"topics":["ph-meter"],"last_fetched":1704910680.458742},"196132939":{"manifest":{"name":"Nintendo Wishlist Card"},"description":"Displays a card showing Nintendo Switch games that are on sale from your wish list.","etag_releases":"W/\"6d7cc96a2ef64fcdee3c14bfb632b202e106c0b0e23534867b6b8767c420d1e5\"","etag_repository":"W/\"ca9cdad90c0043f6713bd87c05510f28fa2005fd1b98d8cb51d12801688ea981\"","full_name":"custom-cards/nintendo-wishlist-card","last_commit":"b15211a","last_updated":"2024-01-30T03:37:15Z","last_version":"v2.3.0","stargazers_count":15,"last_fetched":1711822601.783618},"613588535":{"manifest":{"name":"sunsynk-power-flow-card"},"description":"\u26a1A customizable Home Assistant card to emulate the Sunsynk System flow that's displayed on the Inverter screen. ","downloads":1171,"etag_releases":"W/\"55da541cb594e1f35bf17dd188e5e03bc82ca1c608feaf010c073c885996e846\"","etag_repository":"W/\"4988e50950797b994d84b120506df22462258217c4a365d63371e7ddacd39c57\"","full_name":"slipx06/sunsynk-power-flow-card","last_commit":"8fe88c4","last_updated":"2024-04-03T22:54:26Z","last_version":"v4.27.0","open_issues":10,"stargazers_count":135,"topics":["deye","inverter","powerflow","solar","sunsynk"],"last_fetched":1712225733.27355},"341931266":{"manifest":{"name":"Simple Clock Card"},"description":"Simple clock card for Home assistant lovelace","etag_releases":"W/\"1fcea616fd8a30b00616b423af63d7c36316cfe8756730176be7e8c4d5e6da57\"","etag_repository":"W/\"28bd08eb1c179344a0c0ff9eea8200e728e69ffc994a873ff6c9caf693e719bb\"","full_name":"fufar/simple-clock-card","last_commit":"e58a26c","last_updated":"2023-12-18T17:58:14Z","last_version":"1.8","open_issues":2,"stargazers_count":38,"topics":["clock","lovelace-custom-card"],"last_fetched":1711846846.524563},"253019926":{"manifest":{"name":"mini humidifier"},"description":"Minimalistic humidifier card for Home Assistant Lovelace UI","downloads":4195,"etag_releases":"W/\"0cd55735bd0afb8c47775d2a1fd1aade3bfad23f7431ef2c6ac2ac3446277eb4\"","etag_repository":"W/\"bd2a779b98394e8cd1df8a97cabea4165bb1b07569c4afe42a22ea86a09e9818\"","full_name":"artem-sedykh/mini-humidifier","last_commit":"6ba7849","last_updated":"2024-02-23T17:08:57Z","last_version":"v3.1.5","open_issues":17,"stargazers_count":153,"topics":["automation","custom","humidifier"],"last_fetched":1712139252.585028},"358962656":{"manifest":{"name":"Notify Card"},"description":"Send notifications directly from the dashboard","etag_repository":"W/\"253acfb48427b364fd9b3583317026af02b9bf6d6a136af384acfc59f9c36e76\"","full_name":"bernikr/lovelace-notify-card","last_commit":"c78963f","last_updated":"2024-01-07T03:08:31Z","open_issues":10,"stargazers_count":39,"topics":["card","notification","notifications","notify","service"],"last_fetched":1710591786.446214},"543068603":{"manifest":{"name":"Philips TV Remote"},"description":"philips tv remote card for for home assistant ","etag_releases":"W/\"8a3897735aa0d2c67bdc56b11bc9cdc2c8a57f2b966fda504c4151a705043829\"","etag_repository":"W/\"997badb894f0689f5cc98cff924da4202d4fdd9af7321cfb2c91182909726c97\"","full_name":"abualy/philips-tv-remote-card","last_commit":"71058ef","last_updated":"2023-02-27T22:46:21Z","last_version":"v0.1.1","open_issues":2,"stargazers_count":10,"topics":["hacs-custom","philips","remote","remote-control"],"last_fetched":1711414468.131363},"240906060":{"manifest":{"country":["CN"],"name":"PHICOMM DC1 card"},"description":"\u6590\u8bafDC1\u6392\u63d2\u7684Lovelace\u5361\u7247","etag_releases":"W/\"c145a5c9506c51d1ae7102b060efb4edc91d5c342b69ad1601f6d9fed74d127a\"","etag_repository":"W/\"b2c7da78a44452689d19a67d100d2fd66e5353f989d7e465e3490341c294170d\"","full_name":"fineemb/lovelace-dc1-card","last_commit":"4c2c109","last_updated":"2022-06-03T03:36:28Z","last_version":"v1.2.0","open_issues":1,"stargazers_count":21,"last_fetched":1701397899.352178},"334448958":{"manifest":{"name":"bootstrap-grid-card"},"description":"Bootstrap grid in Lovelace UI","downloads":36,"etag_releases":"W/\"1e96fdcb1da32a57fc94d6b9b4056fe676a8c86e8f2fe78fa41b3f06d43f1deb\"","etag_repository":"W/\"14c8e16de79a9fe15fb218ad8a4c04e4b1acf034d68bbf0530c25f3059000467\"","full_name":"ownbee/bootstrap-grid-card","last_commit":"fe456fe","last_updated":"2024-03-26T17:50:56Z","last_version":"v0.2.1","open_issues":4,"stargazers_count":42,"topics":["bootstrap","bootstrap-grid-card","card","grid","layout"],"last_fetched":1712168268.433568},"522634019":{"manifest":{"name":"Clock Weather Card"},"description":"A Home Assistant Card indicating today's date/time, along with an iOS inspired weather forecast for the next days with animated icons","downloads":20333,"etag_releases":"W/\"a2b4580a13dc9cec2845521c6aba0cf2a01476e1e7c887240dcd37c2b186e0f4\"","etag_repository":"W/\"afef7c90f884a78c82e83447f795ba440ee31609a5b5474b4b9bbbbff8ecff26\"","full_name":"pkissling/clock-weather-card","last_commit":"39b80f1","last_updated":"2024-04-04T05:13:05Z","last_version":"2.3.0","open_issues":29,"stargazers_count":251,"topics":["animated","animation","bar","clock","date","forecast","gradient","icons","ios","time","weather"],"last_fetched":1712211495.41326},"269011342":{"manifest":{"name":"Shutter Card"},"description":"Shutter card for Home Assistant Lovelace UI","downloads":20026,"etag_releases":"W/\"d5e514048d62d94b1de93cf19b66c1b845bfd842dc990fa7edc73c9875d866e9\"","etag_repository":"W/\"aa6a323036b7c18ac8f91682bc5bb2da55bd12889f9cba563028368ae70c1d7b\"","full_name":"Deejayfool/hass-shutter-card","last_commit":"84dd1b7","last_updated":"2024-01-25T13:11:50Z","last_version":"v1.4.0","open_issues":66,"stargazers_count":242,"last_fetched":1712081866.838458},"187339794":{"manifest":{"name":"TV Remote Card"},"description":"\ud83d\udcfa TV Remote Card","etag_releases":"W/\"223dc4726c233ca2a1ea64aaefcef98e6aa66ddd5c92255641268e759a5d7077\"","etag_repository":"W/\"595ba352bb05d7d55a360a5f5c62b31d3c7d260f9749a469092f0efa3bf256f2\"","full_name":"marrobHD/tv-card","last_commit":"d587fbf","last_updated":"2022-11-15T14:04:23Z","last_version":"v0.2.1","open_issues":2,"stargazers_count":169,"topics":["homeassistant-tv-card","lovelace-card","tv-card"],"last_fetched":1710843304.806729},"164367214":{"manifest":{"name":"Roku Card"},"description":"\ud83d\udcfa Roku Remote Card","downloads":9480,"etag_releases":"W/\"212a1b29b025d13c294a491cf00141aa092ca86845c76a76f00fbc5ea7522340\"","etag_repository":"W/\"ff3ae0382237df4f45709b6456169df84baeb7e7752b760aa5f2b27f98ff16d8\"","full_name":"iantrich/roku-card","last_commit":"aec7b4d","last_updated":"2023-04-30T04:51:39Z","last_version":"1.2.4","open_issues":20,"stargazers_count":113,"topics":["roku"],"last_fetched":1711491213.552938},"198066338":{"manifest":{"country":["DK"],"name":"Rejseplanen Card"},"description":"Lovelace card for listing departures from Rejseplanen sensors","etag_releases":"W/\"91742e85ff70ae8511ed2fd586faffd55fc45de48e1936fceaa766a7d0b43f4e\"","etag_repository":"W/\"02e4af9f63439af45a8a99be500185364f7a389df445e6eab4542a207d393293\"","full_name":"DarkFox/rejseplanen-card","last_commit":"5b6eed3","last_updated":"2023-01-04T06:49:56Z","last_version":"1.5.4","open_issues":8,"stargazers_count":6,"topics":["denmark","lovelace-card","rejseplanen","rejseplanen-card","rejseplanen-sensors"],"last_fetched":1706144411.430502},"202874270":{"manifest":{},"description":"Sets the background of your Home Assistant to match the entity picture of a media player. No longer maintained.","etag_repository":"W/\"815bd0f724fbd69183871fe6119b0091c23fd01634fe127cbc9aafd66c5f7405\"","full_name":"TheLastProject/lovelace-media-art-background","last_commit":"d5137b0","last_updated":"2023-04-08T19:23:34Z","open_issues":6,"stargazers_count":32,"last_fetched":1709928846.93389},"245159052":{"manifest":{"name":"Canary"},"description":"\ud83d\udc24 Adds many useful extensions to lovelace, such as templating secondary info, stacking within a card and more!","downloads":12167,"etag_releases":"W/\"153fd038fa019185ef94a2649f67dd876418dd37dfbaa8e800817b18faab6ef8\"","etag_repository":"W/\"14bfcd25cece8d08a703fa679e06787157f2551bb27a40ed6a255ac7ab99c000\"","full_name":"jcwillox/lovelace-canary","last_commit":"00bf511","last_updated":"2024-04-04T01:24:32Z","last_version":"0.4.0","open_issues":18,"stargazers_count":85,"topics":["canary-card","extensions"],"last_fetched":1712197421.418366},"281214271":{"manifest":{"name":"RPi Monitor Card"},"description":"A Raspberry Pi status display Card for Home Assistant Lovelace","downloads":12794,"etag_releases":"W/\"29532c1867d2b4deadf769c277816fbb0dab594331417ac2e22f598648e44f55\"","etag_repository":"W/\"a3a79cfa06eb17e1a1ca290d3a04d08905933ae3e015e39c331bc38b1863dc22\"","full_name":"ironsheep/lovelace-rpi-monitor-card","last_commit":"562180b","last_updated":"2024-01-28T18:29:07Z","last_version":"v1.4.2","open_issues":12,"stargazers_count":171,"topics":["lovelace-card","lovelace-custom-card","raspberry-pi"],"last_fetched":1712045846.122009},"180000010":{"manifest":{},"description":null,"downloads":3115,"etag_releases":"W/\"cdfa9620908e4fe089cf76922fb4cca2113963f0459220d56e3a00056df902c3\"","etag_repository":"W/\"59650f49a2588cb1efcb78346809a785709c5e0cdeb955d8dbc7a4ef977e13df\"","full_name":"custom-cards/cover-element","last_commit":"495f600","last_updated":"2019-06-03T04:34:16Z","last_version":"0.3.0","open_issues":4,"stargazers_count":17,"last_fetched":1704903453.126802},"143762825":{"manifest":{"name":"Dual gauge card"},"description":"Dual gauge custom card for Lovelace in Home Assistant","etag_releases":"W/\"2ce8b4ff8a76c6ff1942a512bcf77fb193fa40bc0406a1dc97d55a546beb16c1\"","etag_repository":"W/\"ca807d2bd8cd1b12a2ffd1e6e0b206313b68381a62d9fe5487ff06ab50a4ab15\"","full_name":"custom-cards/dual-gauge-card","last_commit":"c66c6e9","last_updated":"2024-03-20T12:37:55Z","last_version":"0.5.3","open_issues":27,"stargazers_count":162,"last_fetched":1711649761.866652},"300754203":{"manifest":{"country":["JP"],"name":"Kanji Clock Card"},"description":"A simple clock widget using Japanese Kanji for date and time","downloads":448,"etag_releases":"W/\"f3aab373d9ce84c6eb280bae7e60550869686359556fb92616c51b98b4e84a39\"","etag_repository":"W/\"832431a7abb04d8a3f25511995988fa21258333c4c9fd287d5da3786be78290e\"","full_name":"sopelj/lovelace-kanji-clock-card","last_commit":"3e93ccd","last_updated":"2023-11-21T13:14:22Z","last_version":"1.0.1","open_issues":1,"stargazers_count":2,"topics":["lovelace-card","lovelace-custom-card"],"last_fetched":1712045910.055553},"259784620":{"manifest":{"country":["CN"],"name":"Gaode Map card"},"description":"\u590d\u523b\u5b98\u65b9Lovelace\u5730\u56fe\u5361\u7247,\u57fa\u4e8e\u9ad8\u5fb7\u5730\u56fe","etag_releases":"W/\"2b4e3a0fb3643d6c93f1f6a62c17a08a0273bb64ec999a089f9cf19e10669659\"","etag_repository":"W/\"48b1173c78822c165d0f964fb70f2a3104c56ca2b5a4c77b6707a992b0b3e1ee\"","full_name":"fineemb/lovelace-cn-map-card","last_commit":"fce3dbf","last_updated":"2022-06-03T03:35:37Z","last_version":"v1.2.7","open_issues":11,"stargazers_count":47,"last_fetched":1710598354.815906},"148520838":{"manifest":{},"description":"Minimalistic media card for Home Assistant Lovelace UI","downloads":63816,"etag_releases":"W/\"ced421f98b6d4eed73f08608d0cf4597b5933c4a512d9e9afe298caed792cd32\"","etag_repository":"W/\"6268186a64c37b9e84bf3a88c9957e9c93d58bffd9827206ea719a869fe3623b\"","full_name":"kalkih/mini-media-player","last_commit":"c2ff27f","last_updated":"2024-02-12T14:46:31Z","last_version":"v1.16.9","open_issues":150,"stargazers_count":1433,"topics":["automation","custom","sonos"],"last_fetched":1712182379.78492},"157674859":{"manifest":{"name":"Air Visual Card"},"description":"A Lovelace card showing air quality data from airvisual.com. Requires the AirVisual component.","etag_releases":"W/\"14853d4f296b68e29e3e2d5342f9c8a16185917f0cbb0e40e8b050d9741bf433\"","etag_repository":"W/\"605cd45c914cd41e4828345b08fd70b7f895a5b34dbb627e3ea59dc0010f198d\"","full_name":"dnguyen800/air-visual-card","last_commit":"efb2db3","last_updated":"2023-04-06T20:25:49Z","last_version":"2.0.2","open_issues":8,"stargazers_count":95,"topics":["air-quality","air-visual"],"last_fetched":1711102484.295151},"694403206":{"manifest":{"name":"Comfortable Environment Card"},"description":"A card to display the Heat Index and Discomfort Index (aka Thom Index)","downloads":383,"etag_releases":"W/\"085cfd775ac3a7410a33cc720fab6af587455bb8fb75c72756671a5cb98abbaa\"","etag_repository":"W/\"dcc44345af78ff33a6a8700c0b7d53966d3d4afe16915dfd74e472ed653d17d9\"","full_name":"argaar/comfortable-environment-card","last_commit":"2a576c3","last_updated":"2024-03-19T21:00:00Z","last_version":"1.5.10","open_issues":3,"stargazers_count":21,"topics":["comfort","comfortable","discomfort","discomfort-index","envrironment","heat","heat-index","thom-index"],"last_fetched":1710965631.872321},"350509867":{"manifest":{"name":"Uptime Card"},"description":"Minimalistic uptime card for Home Assistant Lovelace UI","downloads":6680,"etag_releases":"W/\"d62f984f0dda3940b5cfff12ff910108b0fbce088d244a0bab68308ca5cd012a\"","etag_repository":"W/\"aecd9f26c01d1f928db9bc387bc3d51632d2858071f5fd36fa5129c1b05d2a4a\"","full_name":"dylandoamaral/uptime-card","last_commit":"4eca23f","last_updated":"2024-03-20T07:58:35Z","last_version":"v0.16.0","open_issues":4,"stargazers_count":249,"topics":["card","custom","uptime","uptime-card"],"last_fetched":1712182337.718089},"246549747":{"manifest":{"name":"Atomic Calendar Revive"},"description":"An advanced calendar card for Home Assistant Lovelace.","downloads":15086,"etag_releases":"W/\"963120b15c03119414b88edb54a8c0da6dd8ad3b8b216fd3d275da9a3663d785\"","etag_repository":"W/\"afd87b817f713b11d4858e2434538fd23d89b7a9339bb6dbc39a6d7a86e5ab5f\"","full_name":"totaldebug/atomic-calendar-revive","last_commit":"b327da4","last_updated":"2024-04-03T21:16:41Z","last_version":"v9.6.2","open_issues":14,"stargazers_count":365,"topics":["calendar","card","javascript","module"],"last_fetched":1712192306.192866},"207292725":{"manifest":{"name":"Flexible Horseshoe Card for Lovelace"},"description":"Flexible Horseshoe card for Home Assistant Lovelace UI. A card with a flexible layout, a horseshoe-like donut graph, multiple entities or attributes, graphics and animations!","etag_releases":"W/\"b54de68f0a74324913a1ab4643a23209fa2fb4cae45eabcd250b4a90ce03fb0c\"","etag_repository":"W/\"e19fe88c09a6e85348b0ac03f31abdbf3e74e48bef2d201e06e714f006bf2104\"","full_name":"AmoebeLabs/flex-horseshoe-card","last_commit":"fff7405","last_updated":"2023-10-09T17:43:18Z","last_version":"v1.2","open_issues":50,"stargazers_count":217,"topics":["lovelace-card","lovelace-custom-card"],"last_fetched":1711938431.419827},"200081161":{"manifest":{"country":["HU"],"name":"BKK Stop Information Card"},"description":"Custom Lovelace card for Budapest Public Transportation custom component","downloads":352,"etag_releases":"W/\"f602262398b40d2b719dc84f5ff1905f4fae1b0b43a2333dcb8925e0d9f6c98b\"","etag_repository":"W/\"4739d8ce776904dab59064477cbcefad5df4bffb1b58a18d7d21460944377bb0\"","full_name":"amaximus/bkk-stop-card","last_commit":"09ffdee","last_updated":"2022-12-28T19:13:42Z","last_version":"1.3.0","stargazers_count":12,"topics":["bkk","budapest","hungary","lovelace-custom-card","transportation"],"last_fetched":1711728932.99996},"446955395":{"manifest":{"name":"TV touchpad remote card"},"description":"A card that simplifies TV interaction from HomeAssistant","etag_releases":"W/\"b9e67604a08a053db4141bacf271b474f80584fdbaa6f4e4919c0fabbad5688b\"","etag_repository":"W/\"733b50ad89af4744675e6e6e4035b240e1347976dc7e06ac2f3c5ab6c1af2a5c\"","full_name":"iablon/HomeAssistant-Touchpad-Card","last_commit":"5588aaf","last_updated":"2023-09-14T13:59:21Z","last_version":"v1.1.0","stargazers_count":17,"topics":["remote","tizen","touchpad","touchpad-remote","trackpad","tv-remote"],"last_fetched":1701152302.144339},"509260172":{"manifest":{"name":"Curtain Card"},"description":"Curtain card for Home Assistant Lovelace UI, to control your motor of cover entities.","etag_releases":"W/\"64468b56dfa77fa7586353aedca0e5235040d005f1b3fd8c295c4e597fd525e8\"","etag_repository":"W/\"c2abeeffe36937747f532edbf0f0e6ac141a034ea8c3a6e66e86db94d04fde28\"","full_name":"georgezhao2010/lovelace-curtain-card","last_commit":"2f101c6","last_updated":"2023-08-17T10:44:47Z","last_version":"0.1.4","open_issues":3,"stargazers_count":12,"topics":["cover","curtain","frontend","lovelave"],"last_fetched":1709244738.580531},"220679143":{"manifest":{"name":"HASL Departure Card"},"description":"Lovelace Departure Card for the HASL Platform","etag_releases":"W/\"f731e7201601b07c9bc4b7d6d9e28436b34d2e8ff203b344e47d0c13d7d4b590\"","etag_repository":"W/\"054a6c2c31763a137fbd83b5513d0554e020312482bbf673e8755370ad13da10\"","full_name":"hasl-sensor/lovelace-hasl-departure-card","last_commit":"0eb9ca5","last_updated":"2024-03-25T20:18:53Z","last_version":"v2.6.2","open_issues":4,"stargazers_count":12,"topics":["departures","hasl","sl","stockholms-lokaltrafik"],"last_fetched":1711404807.116798},"197929015":{"manifest":{},"description":"Custom Lovelace card that displays ZHA network and device information","etag_repository":"W/\"5594802e8b0fedf85ce7164c68819d7d6ed4f654c42c4b0ea24cd252c7040104\"","full_name":"dmulcahey/zha-network-card","last_commit":"b6b05fa","last_updated":"2023-11-07T18:36:08Z","open_issues":14,"stargazers_count":91,"last_fetched":1709748996.310397},"654393646":{"manifest":{"name":"Android TV Remote Card (with touchpad, haptic feedback, keyboard, and more!)"},"description":"Universal Customizable TV Remote Card, with HA actions, super configurable touchpad, slider, haptics, and keyboard","etag_releases":"W/\"db6c4ac119a8f0474db489dfa6ce4cc29ba460798bb5818edaef6af4ef8cbecf\"","etag_repository":"W/\"2f5d9bddf8cff4ccd75f2c109faaae5bf231e14c1e83f69b847d3d3cb3496912\"","full_name":"Nerwyn/android-tv-card","last_commit":"4593700","last_updated":"2024-03-26T14:44:12Z","last_version":"3.5.2","open_issues":7,"stargazers_count":146,"topics":["android-tv","androidtv","remote"],"last_fetched":1712192279.174466},"624448609":{"manifest":{"name":"FoxESS - Modbus: Charge Period Card"},"description":"Custom Home Assistant Cards for the FoxESS Modbus Integration","downloads":520,"etag_releases":"W/\"ad1db3e95c529dc846d7f80b62b9aec1b58a326c1e7ffaa3120e0736c9cc3ce1\"","etag_repository":"W/\"413d916901836373bf3042a7c15c3fbeafab89006036c81938c01e69cf7fe665\"","full_name":"nathanmarlor/foxess_modbus_charge_period_card","last_commit":"d0eaa6a","last_updated":"2023-12-26T12:03:38Z","last_version":"v1.0.2","open_issues":4,"stargazers_count":10,"topics":["energy","foxess"],"last_fetched":1708726392.386693},"259904390":{"manifest":{"name":"Jumbo Card"},"description":"A custom lovelace card for the custom Jumbo component.","downloads":4566,"etag_releases":"W/\"99264403f85c2d3467e3d2ebd76ea1adfbfc727351e94faf6d540a30407a198f\"","etag_repository":"W/\"a2b38182a71dc038b42530228fa16ebffcd5ee7cd0adf553ab73067202ba71b2\"","full_name":"Voxxie/lovelace-jumbo-card","last_commit":"7d5b2e7","last_updated":"2020-05-04T10:11:59Z","last_version":"v0.2.1","stargazers_count":2,"topics":["jumbo","lovelace-card","lovelace-custom-card"],"last_fetched":1678387332.889052},"274738925":{"manifest":{"name":"Purifier Card"},"description":"Air Purifier card for Home Assistant Lovelace UI","downloads":4011,"etag_releases":"W/\"b56d67500575da46813cb0f2c3b2236b8fc30534996c5670a1fae30c0c97ebf1\"","etag_repository":"W/\"102cf55085a3a3c7edb886640fe03ea758d694ac25458d85712abf718fc4c11a\"","full_name":"denysdovhan/purifier-card","last_commit":"dca9389","last_updated":"2024-04-01T16:46:37Z","last_version":"v2.5.2","open_issues":13,"stargazers_count":241,"topics":["air-purifier","purifier"],"last_fetched":1711995362.557355},"361776538":{"manifest":{"name":"Your HA Digital Twin floor3d-card"},"description":"Your Home Digital Twin: aka floor3d-card. Visualize Home Assistant state and perform actions using objects in a 3D home model based on Three.js.","downloads":6162,"etag_releases":"W/\"1895476cf5727fd6fda9523e9fbcbe3e66668bcdf9a439b04ec9f1a75e04f744\"","etag_repository":"W/\"2cdf1e62f3fdb29802f992d340e8a7b0841742ff08add8c7bdd5df2ddd83694c\"","full_name":"adizanni/floor3d-card","last_commit":"00b911e","last_updated":"2024-03-06T12:15:53Z","last_version":"v.1.5.3","open_issues":18,"stargazers_count":402,"topics":["3d-models","card","entity-bindings"],"last_fetched":1712052865.035152},"402799177":{"manifest":{"name":"Blind Card"},"description":"Blind card for Home Assistant Lovelace UI","etag_releases":"W/\"dac229ef2bdcbe2333f04a89a834475ebf333213ce1ce9c50a5df9b579792d10\"","etag_repository":"W/\"a9fd183f5bbbfb08aab6c45d9912d78c8bf7dd3a29b45c5be241b64cbc943403\"","full_name":"tungmeister/hass-blind-card","last_commit":"7e34b7c","last_updated":"2023-09-08T05:23:14Z","last_version":"v1.0.4","open_issues":13,"stargazers_count":31,"last_fetched":1712081969.182288},"180528950":{"manifest":{"name":"more-info-card"},"description":"\ud83d\udd39 Display the more-info dialog of any entity as a lovelace card","etag_repository":"W/\"9266bf6b9efd30447afb6a5e53194f09e8f24085b32ea3de648e937bf31a2afc\"","full_name":"thomasloven/lovelace-more-info-card","last_commit":"c0a9c94","last_updated":"2023-10-17T05:20:38Z","open_issues":11,"stargazers_count":128,"last_fetched":1711491277.608186},"361205663":{"manifest":{"name":"Meteoalarm Card"},"description":"Meteoalarm, M\u00e9t\u00e9o-France and DWD severe weather warnings card for Home Assistant Lovelace UI \u26c8\ufe0f","downloads":5313,"etag_releases":"W/\"38159fcb9481eedc637f7e9309a59f50b0f4da59b28d7f080af15a23f1f032e2\"","etag_repository":"W/\"be4edc3cae944ae56814e5e5391fd73cfde8586de65212876aa4a977681b6871\"","full_name":"MrBartusek/MeteoalarmCard","last_commit":"156e7e8","last_updated":"2024-01-19T09:07:40Z","last_version":"v2.6.0","open_issues":19,"stargazers_count":116,"topics":["deutscher-wetterdienst","dwd","lovelace-card","meteo-france","meteoalarm","meteoalarmeu","nina","nws","weather"],"last_fetched":1711707330.252289},"302895020":{"manifest":{"name":"Github Flexi Card / Entity Row"},"description":"Github stats card for Home Assistant","downloads":992,"etag_releases":"W/\"08f666f847c6af1543c8d366b8c200dbd7e50e0313af77243b15c784f67d7436\"","etag_repository":"W/\"f574578eff2d51c134447192e539381f4a7236db820ac0e80a7e79e0480b008b\"","full_name":"maxwroc/github-flexi-card","last_commit":"4edbcc2","last_updated":"2022-02-08T20:54:42Z","last_version":"v2.0.0","open_issues":1,"stargazers_count":25,"topics":["card","flexi","github","github-flexi-card"],"last_fetched":1711242095.670648},"284283867":{"manifest":{"name":"Gallery Card"},"description":"A custom card for Home Assistant that will display images and/or videos from a folder in the style of a gallery. ","etag_releases":"W/\"02147e85516525f9ae5bc025a652654fb01ba5dc23e2aca8560a3eb5706aa54a\"","etag_repository":"W/\"d837349d1f317636e556c7fcab5cb772b67c53d399d9ab8d08404972d9e15808\"","full_name":"TarheelGrad1998/gallery-card","last_commit":"e0aebfa","last_updated":"2024-03-11T15:55:43Z","last_version":"v3.5.1","open_issues":34,"stargazers_count":94,"topics":["gallery","gallery-card","images","videos"],"last_fetched":1711923272.729502},"207018200":{"manifest":{"name":"Garbage Collection Card"},"description":"Custom Lovelace card for Garbage Collection custom component","downloads":8139,"etag_releases":"W/\"2af0434085623b41c9168473595e3c15d290abf73709ddf19ef3180a4667b3ee\"","etag_repository":"W/\"f54a613f1d8ac210a2935308ed97a2c2ffb1f6c0a9fd6194e0f58abf24a65d7a\"","full_name":"amaximus/garbage-collection-card","last_commit":"85b1d0f","last_updated":"2023-11-03T13:28:46Z","last_version":"1.24.1","open_issues":3,"stargazers_count":118,"topics":["garbage-collection","lovelace-custom-card","ui-lovelace"],"last_fetched":1712175281.296219},"192835334":{"manifest":{"name":"Lovelace Lock Card"},"description":"Home Assistant Lovelace card to lock entire cards behind passwords or prompts.","etag_repository":"W/\"82efb14612dae3c83a39c8ba651ff2620ce2588f42bef1103a0f2558ee0e5d1d\"","full_name":"CyrisXD/love-lock-card","last_commit":"0e3a06e","last_updated":"2023-02-20T00:55:00Z","open_issues":13,"stargazers_count":128,"last_fetched":1711203049.680577},"499270202":{"manifest":{"name":"Hourly Weather Card"},"description":"Hourly weather card for Home Assistant. Visualize upcoming weather conditions as a colored horizontal bar.","downloads":13681,"etag_releases":"W/\"85520c44a68a2b9727ec920229a4f8890e3a6a511349bc56b7a87804edc08919\"","etag_repository":"W/\"b753952ca35f281576a6b8ef1d3b566f4ee483f37cec38475f058e177ec2ab6b\"","full_name":"decompil3d/lovelace-hourly-weather","last_commit":"13b4958","last_updated":"2024-04-02T16:56:57Z","last_version":"5.4.0","open_issues":14,"stargazers_count":224,"topics":["card","hourly","weather"],"last_fetched":1712204255.363866},"237620254":{"manifest":{"name":"todoist-task-list"},"description":"This is a custom lovelace card for displaying a todoist calendar in Home Assistant.","etag_releases":"W/\"3725c1ae7c8fdd94f44378cee10932d0b95f0935b3d85d7ba0cb9cd1b6b4216d\"","etag_repository":"W/\"aad31a349f3fde3c5a49450a0b58744dc0104da9c44a87c99cd027fb9adcb6b7\"","full_name":"tholgir/TodoIst-Task-List","last_commit":"23c9f66","last_updated":"2021-04-25T07:36:09Z","last_version":"v1.1.1","stargazers_count":13,"topics":["lovelace-custom-card","todoist"],"last_fetched":1690193797.170002},"540873855":{"manifest":{"name":"VPD Chart card"},"description":"A VPD chart card for Home Assistant","etag_releases":"W/\"e62734c43fa62a9a1149c47f9ea2a5349efa04cd1e317600ec08942ef4322d9c\"","etag_repository":"W/\"78cdaeabd85cc3f9b223b6f22648d04d370dba08b64b616c7f8e356c1a64f92a\"","full_name":"vpdchart/vpdchart-card","last_commit":"64f81b9","last_updated":"2023-05-16T09:22:26Z","last_version":"v1.0.1","open_issues":5,"stargazers_count":24,"topics":["vpd","vpdchart"],"last_fetched":1711009065.718},"215037975":{"manifest":{"name":"HA (Lovelace) Card Waze Travel Time"},"description":"Home Assistant Lovelace card for Waze Travel Time Sensor","etag_repository":"W/\"3cd98a7219fe5a1d5b9ccea6714f782cafca288e603727ab83c1c78cd9baea2a\"","full_name":"r-renato/ha-card-waze-travel-time","last_commit":"038f2a8","last_updated":"2022-11-09T00:43:36Z","open_issues":8,"stargazers_count":39,"topics":["lovelace-card"],"last_fetched":1706977056.948617},"193372044":{"manifest":{"name":"Xiaomi Vacuum Map Card"},"description":"This card provides a user-friendly way to fully control map-based vacuums in Home Assistant. Supported brands include Xiaomi (Roborock/Viomi/Dreame/Roidmi/Valetudo/Valetudo RE), Neato, Wyze, Roomba, Ecovacs (and probably more).","downloads":66393,"etag_releases":"W/\"c013b781e53a5d3799d0b9dc0428fea1c1c2a18d9d93f4be457d1ff01cf5423a\"","etag_repository":"W/\"0dc5072499a5ed90dde0cd58e346a77a9b8e3de7298e14939c314179a9b9530c\"","full_name":"PiotrMachowski/lovelace-xiaomi-vacuum-map-card","last_commit":"14bc2aa","last_updated":"2024-03-08T21:24:36Z","last_version":"v2.2.2","open_issues":32,"stargazers_count":1305,"topics":["deebot","ecovacs","lovelace-card","myneato","neato","roborock","roomba","roomba980","vacuum","valetudo","valetudo-re","wyze","xiaomi","xiaomi-vacuum"],"last_fetched":1712225721.216828},"484538222":{"manifest":{"name":"Power Flow Card"},"description":"A power distribution card inspired by the official Energy Distribution card for Home Assistant","downloads":20477,"etag_releases":"W/\"39ace65c472d89a27d08f0f5e0c28f335c563ade6db99adde3823c451a90be5f\"","etag_repository":"W/\"81817bcaf7e14d71fa8309f8c5066369ff02f506c75dbe5c7db49c4d0d7e4a11\"","full_name":"ulic75/power-flow-card","last_commit":"aef8a58","last_updated":"2023-10-18T00:19:37Z","last_version":"v2.6.2","open_issues":27,"stargazers_count":150,"topics":["dashboard"],"last_fetched":1711548881.377196},"160042309":{"manifest":{"name":"Power wheel card"},"description":"An intuitive way to represent the power and energy that your home is consuming or producing. (A custom card for the Lovelace UI of Home Assistant.)","etag_releases":"W/\"fb0757a0fbef59957d143cfdffe481cbcf0067792fa816ab3067116b127160ac\"","etag_repository":"W/\"e30cd3b39c6c76fe87e1959053efa6c9289f7e6e2659870a17e4e555e8a162de\"","full_name":"gurbyz/power-wheel-card","last_commit":"d136d6d","last_updated":"2022-06-06T07:43:11Z","last_version":"v0.1.5","open_issues":30,"stargazers_count":155,"topics":["energy","solar-panels"],"last_fetched":1711253814.280042},"420365062":{"manifest":{"name":"Last Changed Element"},"description":"Display when entity was last changed in home assistant picture element","etag_repository":"W/\"8069e5c63404102e7227b45fdaa848730a23d3ff8ff7d04ad7e6f90e92839d30\"","full_name":"queimadus/last-changed-element","last_commit":"331cb0c","last_updated":"2023-08-07T18:16:25Z","open_issues":1,"stargazers_count":10,"last_fetched":1702354655.060794},"294609880":{"manifest":{"name":"BOM Radar Card"},"description":"A rain radar card using the new tiled images from the Australian BOM","downloads":2314,"etag_releases":"W/\"1945b879100859f044a467cb8122d0eaf48b120540870737b3ac4290580507d1\"","etag_repository":"W/\"cdf03044a962659153904b5f2d01ed399730b5eff5c177ce3cb07110fe8cb3fa\"","full_name":"Makin-Things/bom-radar-card","last_commit":"86432eb","last_updated":"2024-01-15T09:27:44Z","last_version":"v2.1.1","open_issues":1,"stargazers_count":93,"topics":["bom","frontend","meteorology","radar","weather"],"last_fetched":1711933307.595157},"193408399":{"manifest":{},"description":"This card displays provided data as an HTML content of a card.","etag_releases":"W/\"24d73e9052fc164907c15ac5545cd3bd657090d40471418825489167563224b3\"","etag_repository":"W/\"3e13ea52be109c4ecec0db5696982c7ea412a4b71e34717a2d2fd53a359cc1bc\"","full_name":"PiotrMachowski/lovelace-html-card","last_commit":"28847d1","last_updated":"2023-07-20T20:13:11Z","last_version":"v1.0.0","open_issues":4,"stargazers_count":46,"topics":["lovelace-card"],"last_fetched":1711030472.838997},"335019855":{"manifest":{"name":"LinakDesk Card"},"description":"Home Assistant Lovelace Card for controlling desks based on linak bluetooth controller.","downloads":670,"etag_releases":"W/\"1bbe03907da56881780695716ffdf0bcaf55f842ca23ee58912511d4b3146d1a\"","etag_repository":"W/\"9a4f7f91fe1deab388580d557e2f62630e1732304b10c5e4b66af0e83bd9cf45\"","full_name":"IhorSyerkov/linak-desk-card","last_commit":"5e4e7ba","last_updated":"2023-11-29T21:13:43Z","last_version":"v1.6.0","open_issues":10,"stargazers_count":60,"topics":["linak-desk-card"],"last_fetched":1712045845.572353},"449416816":{"manifest":{"name":"Sonos Card"},"description":"Home Assistant custom lovelace sonos card","downloads":1461,"etag_releases":"W/\"d8cf9dfea02e34702b2ae3397cc9a644430b5ccd1b64a47f26fb63352f87e917\"","etag_repository":"W/\"ac5d30759b4de11b92f007fc90a920f73a9b5b3914f79272ea0540b7de57f77c\"","full_name":"punxaphil/custom-sonos-card","last_commit":"6754ba5","last_updated":"2024-04-03T18:12:24Z","last_version":"v7.7.1","open_issues":5,"stargazers_count":144,"topics":["lovelace-custom-card","sonos"],"last_fetched":1712218732.326589},"640516976":{"manifest":{"name":"Energy Gauge Bundle Card"},"description":"A collection of Gauge Cards for Home Assistant Energy Management","downloads":3846,"etag_releases":"W/\"b370a5fb21a6c3896c58e1d40513d7eb1e2f6b851b33147f09fa0a9d060aeb58\"","etag_repository":"W/\"657cfaee20bcee362be51f6f5a62e2768c2382bf54470dd3e9eee0fd5f980001\"","full_name":"flixlix/energy-gauge-bundle-card","last_commit":"b402b82","last_updated":"2023-08-11T09:09:03Z","last_version":"v0.0.3","open_issues":3,"stargazers_count":9,"topics":["bundle","card","cards","collection","custom","dashboard","energy","gauge","panel"],"last_fetched":1712182348.412489},"433577603":{"manifest":{"name":"Config Editor Card"},"description":"Home Assistant Configuration Files Editor for Lovelace","etag_releases":"W/\"e78c84dd4aad2cdfa709335683fec358efc13319c1d9c73be747af19156d726a\"","etag_repository":"W/\"8ee7202fbff66c24bfe85c26ea45719106b9919fa1d29ca733cf182895217f3e\"","full_name":"htmltiger/config-editor-card","last_commit":"92dae34","last_updated":"2024-03-08T22:09:38Z","last_version":"4.7","open_issues":1,"stargazers_count":60,"topics":["homeassistant-addons","homeassistant-config","homeassistant-configuration","yaml"],"last_fetched":1712175356.68084},"204049047":{"manifest":{"name":"OpenMensa Lovelace Card"},"description":"A Home-Assistant Lovelace card which displays information from the openmensa-sensor.","etag_releases":"W/\"8cc43de32c237d9c310e3e813f02072e72a20b63d857bfb47d10f3a21848ab13\"","etag_repository":"W/\"1f42ca259d00b06cdf31af80f99d5d1e5c172aeb38e12776cbc178f8fb52bb3b\"","full_name":"Mofeywalker/openmensa-lovelace-card","last_commit":"e234fbd","last_updated":"2023-06-14T10:31:04Z","last_version":"v1.1.0","stargazers_count":3,"last_fetched":1700583550.009649},"231015759":{"manifest":{"name":"Xiaomi Smartmi Fan Card"},"description":"Xiaomi Smartmi Fan Lovelace card with CSS fan animation","downloads":3276,"etag_releases":"W/\"fb279f3eb1d6cc553c6edd614667a4e519965ae43ce90724ed090e1ab0de78a2\"","etag_repository":"W/\"3f4aeb4d0946c045199795ff25ff75873de5e7f3f659b2b2c822a36ae23567c1\"","full_name":"ikaruswill/lovelace-fan-xiaomi","last_commit":"bc406e6","last_updated":"2023-07-10T08:28:43Z","last_version":"2.2.4","open_issues":20,"stargazers_count":65,"topics":["xiaomi","xiaomi-fan"],"last_fetched":1709612185.858057},"287409957":{"manifest":{"name":"Cover Control Button Row"},"description":"button row for controlling open/close covers in Home Assistant","etag_releases":"W/\"e4deb94177297c0674263cc158c64125787e8a4a372f847a95581c65a5e08423\"","etag_repository":"W/\"37eab3b7e236e1d5a85fce8a481376af08d2dd41cb83055b4c024f7eacb7bb9f\"","full_name":"finity69x2/cover-control-button-row","last_commit":"b447d10","last_updated":"2023-05-11T00:31:16Z","last_version":"3.1","open_issues":1,"stargazers_count":11,"topics":["cover"],"last_fetched":1704716715.48637},"586363416":{"manifest":{"name":"Mushroom - Better Sliders"},"description":"Fork of Mushroom Cards - For better touch control of light sliders \ud83c\udf44","downloads":27503,"etag_releases":"W/\"ad5790e8dbd273ed596e530353a78f1ff1b630e084fb3356185123d082836648\"","etag_repository":"W/\"494d3da1925db5c0b998800d7d9ae2b00547a106f89ff99fcd42bd1dcc58db92\"","full_name":"phischdev/lovelace-mushroom-better-sliders","last_commit":"f617e79","last_updated":"2023-07-11T13:23:20Z","last_version":"v3.0.2","open_issues":3,"stargazers_count":25,"topics":["card","mushroom","sliders","touch"],"last_fetched":1712225716.429247},"269474857":{"manifest":{"name":"Tab Redirect Card"},"description":"Custom lovelace card to use in\u00a0Home assistant allowing you to redirect a user to certain view based on entity states.","etag_repository":"W/\"11958a316ce5a68b88fce94be304c93821070a97ff613ffa3d2a634e3fe596f7\"","full_name":"ben8p/lovelace-tab-redirect-card","last_commit":"dd8f32a","last_updated":"2023-04-29T05:41:43Z","open_issues":5,"stargazers_count":17,"topics":["lovelace-custom-card"],"last_fetched":1708518138.359173},"172998062":{"manifest":{},"description":"Minimalistic weather card for Home Assistant","downloads":33634,"etag_releases":"W/\"024ca1d14208bf0390961b6d596334a4749ed049174195c839bae2522ab05daf\"","etag_repository":"W/\"8d3ef0dfc31120b8d58b95ec5afaa434c42e94886e09af4028e8b143432ac355\"","full_name":"kalkih/simple-weather-card","last_commit":"120721b","last_updated":"2023-05-12T19:41:22Z","last_version":"v0.8.5","open_issues":22,"stargazers_count":267,"topics":["weather"],"last_fetched":1711477037.447726},"331701152":{"manifest":{"name":"apexcharts-card"},"description":"\ud83d\udcc8 A Lovelace card to display advanced graphs and charts based on ApexChartsJS for Home Assistant","downloads":119401,"etag_releases":"W/\"2564abfa54f85d5a5aa0993594fc85f617eb5484396515730cac81f0ee6f7aaa\"","etag_repository":"W/\"b75d163e43c34b3759fffafca95f069c9afdfeddcf804c9bcf91717c00b63ad8\"","full_name":"RomRider/apexcharts-card","last_commit":"1b63c0f","last_updated":"2024-03-15T12:16:51Z","last_version":"v2.0.4","open_issues":66,"stargazers_count":999,"topics":["apexcharts","iot"],"last_fetched":1712218737.801905},"142545838":{"manifest":{"name":"Canvas Gauge Card"},"description":"The card makes it possible to use gauges from https://canvas-gauges.com/","downloads":6283,"etag_releases":"W/\"48e03c1d3cbc729f29a221bf0a399df6e3ff7e5d60f1c964e52d371abc928411\"","etag_repository":"W/\"3e244cc5d351c6114d400a3a7d83815127dc08e2262a4dc06f592da780ba7cd1\"","full_name":"custom-cards/canvas-gauge-card","last_commit":"e354a74","last_updated":"2023-10-07T05:46:59Z","last_version":"0.91","open_issues":6,"stargazers_count":158,"last_fetched":1711592565.974226},"161403328":{"manifest":{"name":"card-tools"},"description":"\ud83d\udd39A collection of tools for other lovelace plugins to use","etag_releases":"W/\"0cad444633bef83b37482f5ccc1ff8fb5435ec61c1a20e9827aaa4ac208ab8cd\"","etag_repository":"W/\"b31ca98aec628c7ef24b8a0a5ed6fe94107c4f3e99cd3f2d8715e43a0155ab1d\"","full_name":"thomasloven/lovelace-card-tools","last_commit":"477f3d4","last_updated":"2023-04-10T09:48:29Z","last_version":"11","open_issues":26,"stargazers_count":237,"last_fetched":1711599401.536636},"192732887":{"manifest":{},"description":"Card that allows you to swipe throught multiple cards for Home Assistant Lovelace","etag_releases":"W/\"acf6d1077af61fd08911f65c690b8cbac6732c2ed04c4fc7b4ceab04ec3ae92c\"","etag_repository":"W/\"5a573fd9550c09d38180c66a5f30bb7743c1df7589b6300bda6cfcfd8a531b3f\"","full_name":"bramkragten/swipe-card","last_commit":"fcd46ed","last_updated":"2023-09-07T21:30:39Z","last_version":"v5.0.0","open_issues":51,"stargazers_count":215,"last_fetched":1711333298.15484},"302122266":{"manifest":{"name":"Cover Icon Element"},"description":"Improved cover icon for home assistant picture element","etag_releases":"W/\"0e5cff76b9ce587f9d786c7eebcec2fe1123bcc02b09eda96ea63d4fecc5d1a5\"","etag_repository":"W/\"853ddbe9ea0ba7e8dbcb21940ee3ca83cff4c970265f03b3703a859a5dd883a8\"","full_name":"queimadus/cover-icon-element","last_commit":"b5af2f3","last_updated":"2023-08-07T18:15:04Z","last_version":"v1.3.0","open_issues":2,"stargazers_count":5,"topics":["cover"],"last_fetched":1692303286.251837},"199546187":{"manifest":{},"description":"This is a companion card for Google Keep sensor. It displays notes downloaded by integration in a friendly way, similar to Google Keep app.","etag_releases":"W/\"6fa3262f5fb8ad50817a43f70732886ce643a1f665530772de73cf8b0f921114\"","etag_repository":"W/\"389b874eef52bec4daecee4f64222fbdf7c9c606e0608b523deb5b509cd69e16\"","full_name":"PiotrMachowski/lovelace-google-keep-card","last_commit":"2db31f5","last_updated":"2023-07-07T02:53:42Z","last_version":"v1.2.0","open_issues":7,"stargazers_count":52,"topics":["lovelace-card"],"last_fetched":1710332665.322347},"315044466":{"manifest":{"name":"Transmission Card"},"description":"Custom Transmission card for Home Assistant/Lovelace","downloads":1220,"etag_releases":"W/\"4b222ea02faa24d6f7fa161938be571961506d7cd38d0e17c058164216784a41\"","etag_repository":"W/\"8be72f5b1d96f6f4ecb5a5b95bf71c4b73800e1529c8c690653b2fa1c74a74ac\"","full_name":"amaximus/transmission-card","last_commit":"7d08c49","last_updated":"2023-12-23T12:08:54Z","last_version":"0.19.0","open_issues":4,"stargazers_count":34,"topics":["lovelace-card","lovelace-custom-card","transmission"],"last_fetched":1707487883.749865},"309506416":{"manifest":{"name":"WallPanel"},"description":"\ud83d\uddbc\ufe0f Wall panel mode and photo screensaver for your Home Assistant Dashboards","downloads":4477,"etag_releases":"W/\"540a2cacea37e0e8369ccc0c6317ee027b30d1478887439774ec1ad86aea1c0c\"","etag_repository":"W/\"840c6c497e1b228fd30cfbbaf6364a8c4105671d19ea34a4e544243c302da8b7\"","full_name":"j-a-n/lovelace-wallpanel","last_commit":"b3a9578","last_updated":"2024-03-29T11:47:57Z","last_version":"v4.25.0","open_issues":17,"stargazers_count":361,"topics":["dashboard","fullscreen","home-assistant-addons","photo-gallery","screensaver","wallpanel"],"last_fetched":1712105745.021544},"290281267":{"manifest":{"name":"Fullscreen Card"},"description":"Make your Home Assistant browser fullscreen with one tap.","downloads":2241,"etag_releases":"W/\"4d3044e42baf3ed415d9abbba9acdecc9e913d97d22287f1e29db5fa770b014f\"","etag_repository":"W/\"70ad00a7f456582401a76f126a9ccc013e01e9733c43258fa487c840c13edf4f\"","full_name":"KTibow/fullscreen-card","last_commit":"c8d2459","last_updated":"2023-05-18T14:00:38Z","last_version":"v0.8","open_issues":1,"stargazers_count":36,"topics":["card","fullscreen"],"last_fetched":1710051380.93024},"151280062":{"manifest":{"name":"mini-graph-card"},"description":"Minimalistic graph card for Home Assistant Lovelace UI","downloads":54832,"etag_releases":"W/\"f276b4ea7f8311cb49653f86e0410e5c8630d846f43b41af50a11610d8fd1227\"","etag_repository":"W/\"feb70fa661a33375702d10abfa18be80de498b30776a5ecf0e3b155873cd2795\"","full_name":"kalkih/mini-graph-card","last_commit":"49ca1cd","last_updated":"2024-03-20T19:37:14Z","last_version":"v0.12.1","open_issues":122,"stargazers_count":2744,"topics":["automation","custom","graph"],"last_fetched":1712081914.765174},"203036108":{"manifest":{"name":"Valetudo Map Card"},"description":"Display the map from a valetudo-enabled robot in a home assistant dashboard card.","etag_releases":"W/\"d8c38eb3637352f25e0afa885881c91256e65a35b1bff2c57dd3ccae1cf7b011\"","etag_repository":"W/\"b1996d46d610cb5102f0d50b95973343c78c58dd9d5fcb689610370122875844\"","full_name":"Hypfer/lovelace-valetudo-map-card","last_commit":"9ce1140","last_updated":"2024-03-31T07:46:40Z","last_version":"v2023.04.0","open_issues":15,"stargazers_count":228,"topics":["valetudo"],"last_fetched":1712117863.562906},"263901624":{"manifest":{"name":"Generic Remote Control Card"},"description":"Generic Remote control card for HACS","etag_releases":"W/\"d01f0684e775c6242d4a8aabb2b23109e77ba1a683cf5ccad7cd56e6d74d8f6c\"","etag_repository":"W/\"262def29ba311f38bc1e94b4cdc5f06472d7f8f24a87344201fae01db7657eb9\"","full_name":"dimagoltsman/generic-remote-control-card","last_commit":"be884e0","last_updated":"2024-03-13T22:19:04Z","last_version":"0.2.11","open_issues":12,"stargazers_count":90,"last_fetched":1711261008.380546},"413812496":{"manifest":{"name":"Plotly Graph Card"},"description":"Highly customisable Lovelace card to plot interactive graphs. Brings scrolling, zooming, and much more!","downloads":15993,"etag_releases":"W/\"b6137f2cb79cf9e8b71095d2d85f2bc479ea80cfef690dae4ff5e57e4c92aa7e\"","etag_repository":"W/\"78f6be5dce3a1977a3dad6b30a75ad2cc65cf140c60da1dc75b545e9e1a6af94\"","full_name":"dbuezas/lovelace-plotly-graph-card","last_commit":"bbd43d8","last_updated":"2024-03-29T20:29:25Z","last_version":"v3.3.4","open_issues":23,"stargazers_count":288,"topics":["graphs","history","lovelace-custom-card","navigate","plotly","plotlyjs","plots","scroll","zoom"],"last_fetched":1712146982.649225},"257123327":{"manifest":{"name":"LG WebOS channel pad"},"description":"channel pad for LG TV Remote control","etag_repository":"W/\"9ef0ed9c2b4f02bda051f49441360506ec77f85e77db32f97c499fa559159393\"","full_name":"madmicio/channel-pad","last_commit":"abdbcc9","last_updated":"2020-05-28T19:17:53Z","open_issues":8,"stargazers_count":24,"topics":["channel-pad","lg","tv-remote"],"last_fetched":1711729038.927052},"215327195":{"manifest":{"name":"RGB Light Card"},"description":"\ud83d\udca1 A Lovelace custom card for RGB lights","downloads":31861,"etag_releases":"W/\"92242a9c27b9923269943dd5881476d9894a8cec1e3daeaefb5799f03d028f5d\"","etag_repository":"W/\"7b4337b72cff3e3563f2296de6d6f7798903717b504f8e044002eaa83ce74c1c\"","full_name":"bokub/rgb-light-card","last_commit":"f4a255c","last_updated":"2024-01-16T17:01:47Z","last_version":"1.11.0","open_issues":7,"stargazers_count":397,"topics":["lovelace-custom-card","rgb-lights"],"last_fetched":1710231321.064448},"637041617":{"manifest":{"name":"PowerTodoist Card"},"description":"Improved Todoist card for Home Assistant Lovelace UI.","etag_releases":"W/\"eb9851d5be2db5396d81a86831d19f67eba1fe2d1686ca1541e32aea0839c7a4\"","etag_repository":"W/\"1b0497f684815f1a34fd3c4c49623c5507f180e8cb3637c4c42e8d556dec7455\"","full_name":"pgorod/power-todoist-card","last_commit":"fb9e623","last_updated":"2023-11-24T17:48:50Z","last_version":"v0.11-beta","open_issues":1,"stargazers_count":20,"topics":["lovelace-custom-card"],"last_fetched":1712139373.534027},"632590573":{"manifest":{"country":["SE"],"name":"pollenprognos-card"},"description":"A custom Lovelace card to display pollen information","etag_releases":"W/\"287f44ee62e1320e03f8205c445c69205c92544258e39ac458374f9020d35440\"","etag_repository":"W/\"158045fb447a2ec84572ef38e1a44040f05e19f84bd49ebc688c372e7f213c64\"","full_name":"krissen/pollenprognos-card","last_commit":"8b9dea2","last_updated":"2023-05-09T17:42:14Z","last_version":"v1.0.4","open_issues":1,"stargazers_count":6,"topics":["lovelace-card","lovelace-custom-card","pollen","pollenprognos"],"last_fetched":1711369420.227252},"267558148":{"manifest":{"name":"Custom-ui"},"description":"Add templates and icon_color to Home Assistant UI","downloads":4597,"etag_releases":"W/\"1a75915e7b05d7cfe67b05c08467829b3dba7f42ddb63783f2119ee6fdbea41c\"","etag_repository":"W/\"054659352e85ca1bf75a14116e1f8231579f02e505caf6f4b789126da2bb87ab\"","full_name":"Mariusthvdb/custom-ui","last_commit":"f1fe609","last_updated":"2024-02-15T07:22:04Z","last_version":"20240118","stargazers_count":148,"topics":["attributes","customization","icon-color","more-info"],"last_fetched":1710073297.849642},"247134044":{"manifest":{"name":"Multiline Text Input Card"},"description":"A simple lovelace multiline text input card","downloads":1925,"etag_releases":"W/\"313bc7bf52ad4736352511715b650551460b2d3e35e3aafb5dee48981025b5bd\"","etag_repository":"W/\"8cf4073608c4015a1fbd50583199b6cd8333704f5603d9c70fd4dc35890bb84c\"","full_name":"faeibson/lovelace-multiline-text-input-card","last_commit":"7b5040b","last_updated":"2020-10-15T00:16:17Z","last_version":"1.0.4","open_issues":3,"stargazers_count":11,"topics":["lovelace-card","multiline","text-input"],"last_fetched":1704416289.511306},"678764124":{"manifest":{"name":"TrashCard"},"description":"TrashCard - indicates what type of trash will be picked up next based on your calendar entries \ud83d\uddd1\ufe0f","downloads":775,"etag_releases":"W/\"29b7a87e0e395696c201e8f0d394e4a92cc0cc9983374ff84a86ee0524d49778\"","etag_repository":"W/\"44e506c8800785549aa6ca1efbb38b023af660fd4e5371bbed1563eb7b736c7c\"","full_name":"idaho/hassio-trash-card","last_commit":"aacc3bc","last_updated":"2024-04-02T08:38:11Z","last_version":"2.2.1","open_issues":16,"stargazers_count":65,"topics":["calendar","card","frontend","lovelace-custom-card","mushroom","paper","trash","waste"],"last_fetched":1712105739.729311},"238802974":{"manifest":{"name":"Roomba Vacuum Card"},"description":"HA Lovelace Card for iRobot Roomba Vacuum Cleaner leveraging the rest980 Docker Image","etag_releases":"W/\"0b290f1d47def0151c3ed640e61935687a2f961d45802d6cbc71e383fba492ec\"","etag_repository":"W/\"3ba3c56a4e1056ab87584241906185a67615daa30bb7a2e2787da9f8ebed9588\"","full_name":"jeremywillans/lovelace-roomba-vacuum-card","last_commit":"ac3915a","last_updated":"2023-04-06T18:55:12Z","last_version":"0.11","open_issues":1,"stargazers_count":46,"topics":["irobot","irobot-roomba","lovelace-custom-card","vacuum"],"last_fetched":1709288079.732458},"591270696":{"manifest":{"name":"windrose-card"},"description":"Home Assistant Lovelace Windrose Card","downloads":4800,"etag_releases":"W/\"abe8c32b399017aed39a53180d9ad9dc3a7c3aba413811b3486e84c9b568e40c\"","etag_repository":"W/\"3521e00e5bfe9a02018f10e434fabfb8124ac9a5e629389a69702f8b3d14d933\"","full_name":"aukedejong/lovelace-windrose-card","last_commit":"6ad8a15","last_updated":"2024-03-10T18:48:27Z","last_version":"v1.4.0","open_issues":13,"stargazers_count":52,"topics":["weather-dashboard","windrose"],"last_fetched":1711901635.322446},"179788256":{"manifest":{"name":"Text Divider Row"},"description":"\ud83d\uddc2 Text Divider Row","downloads":13743,"etag_releases":"W/\"4ca2ec0d32dc9322bb903ce5e90325ff01a776b325b62f99ab49bcda930ad0f2\"","etag_repository":"W/\"68d31ed3dbac0c87e4d4d98024d485b9119d7a53624440455664f04f05c23bcd\"","full_name":"iantrich/text-divider-row","last_commit":"ff85821","last_updated":"2023-04-30T20:13:33Z","last_version":"1.4.1","open_issues":15,"stargazers_count":101,"last_fetched":1712225667.719548},"343112953":{"manifest":{"name":"Kodi Search Card"},"description":"Custom card for home assistant allowing to search in the libraries of kodi","downloads":9,"etag_releases":"W/\"73400239dab9970570f054e30f5ba9195329be4ba879d75f148d861b4ed89f9e\"","etag_repository":"W/\"02d0ae401a1a6802c17e03fb21d9b818f940dda694d1204941198a9b41695a28\"","full_name":"jtbgroup/kodi-search-card","last_commit":"5ff1f63","last_updated":"2024-02-17T07:54:07Z","last_version":"3.7.1","stargazers_count":9,"topics":["kodi","kodi-media-sensors"],"last_fetched":1708164795.15771},"556306418":{"manifest":{"name":"Daily Schedule Card"},"description":"Home Assistant Custom Card for Daily Schedule Integration","etag_releases":"W/\"2350cbd6ac305e837af89a6dd9d9718f0d5ebcd5fae54bbd70bf9ce2b5eaa88d\"","etag_repository":"W/\"f26eca8b167414592bd1142cbb7cec3ce5f013d5e4c5ac19c4e94888caeaf60f\"","full_name":"amitfin/lovelace-daily-schedule-card","last_commit":"81edd0d","last_updated":"2024-04-01T17:54:51Z","last_version":"v1.5.2","open_issues":1,"stargazers_count":9,"topics":["lovelace-custom-card"],"last_fetched":1712002439.136359},"350886220":{"manifest":{"name":"Fan Mode Button Row"},"description":"Frontend plugin to control fans in Home Assistant using preset modes for speeds","etag_releases":"W/\"1b20bfeff9d0f82bea08fcba85640dbe92696503451e5cff4d32dc66c0f4a5de\"","etag_repository":"W/\"12d764f6585cdfbf0b54da4ba290745e2c8ed51e8fa15b1d680d9102c9fc10d7\"","full_name":"finity69x2/fan-mode-button-row","last_commit":"f79f647","last_updated":"2023-11-25T16:42:39Z","last_version":"3.1","open_issues":2,"stargazers_count":13,"topics":["fan","preset"],"last_fetched":1711995373.39558},"560614992":{"manifest":{"name":"System Flow Card"},"description":"A system flow card inspired by the official Energy Distribution card for Home Assistant","etag_releases":"W/\"a60d32215b045715facc7da89acc7cfd87f6190604b4cdc37f08332804a7a2ca\"","etag_repository":"W/\"3903cc6f18f71e1e289d81361941ae740a798b9eec12a74b8bbbf45dc3b55c7a\"","full_name":"flyrmyr/system-flow-card","last_commit":"d611eef","last_updated":"2024-03-29T15:33:30Z","last_version":"v0.1.2","open_issues":15,"stargazers_count":37,"topics":["dashboard","lovelace-custom-card"],"last_fetched":1711894294.29485},"144899700":{"manifest":{"name":"slider-entity-row"},"description":"\ud83d\udd39 Add sliders to entity cards","etag_releases":"W/\"e77747b88c362ee2dac816e3f4e18444cdb5d5e1ddec69cf973d7a8cde6c397d\"","etag_repository":"W/\"5c1aaed3e3347feb47aebb56ac6be87ad3938154ef061b26dde28b5dd4f41017\"","full_name":"thomasloven/lovelace-slider-entity-row","last_commit":"7082021","last_updated":"2023-12-25T23:36:54Z","last_version":"17.4.1","open_issues":20,"stargazers_count":783,"last_fetched":1712192305.943692},"378256174":{"manifest":{"name":"OpenSprinkler Card"},"description":"Home Assistant card for collecting OpenSprinkler status","downloads":2129,"etag_releases":"W/\"652e0dbfea3686b6526c4d8aa01e8b9c8048d6354aebaa2134c53878d9a10616\"","etag_repository":"W/\"84fd5a65497dc161055e58c2e582b6a7b89f66243be5e58d1ac54bb4682e4972\"","full_name":"rianadon/opensprinkler-card","last_commit":"fca6e51","last_updated":"2022-11-25T09:22:58Z","last_version":"v1.13","open_issues":6,"stargazers_count":62,"topics":["opensprinkler"],"last_fetched":1710397075.147177},"178921037":{"manifest":{"name":"Multiple Entity Row"},"description":"Show multiple entity states and attributes on entity rows in Home Assistant's Lovelace UI","downloads":31427,"etag_releases":"W/\"1d878ad1b1636b88c5460f4e692517e4715e2bd03252d54a43720369bcca2fee\"","etag_repository":"W/\"8d5371d82560f37bf3677b1979c7be1299cb378b8e2b8856361f7342c9b1fb41\"","full_name":"benct/lovelace-multiple-entity-row","last_commit":"a3302f2","last_updated":"2024-04-04T02:30:57Z","last_version":"v4.5.1","open_issues":79,"stargazers_count":747,"topics":["attribute","card","entity","entity-attribute","entity-rows","format","multiple","state"],"last_fetched":1712204223.888935},"455846088":{"manifest":{"name":"Sankey Chart Card"},"description":"A Home Assistant lovelace card to display a sankey chart. For example for power consumption","etag_releases":"W/\"02cb52c57c4cb926477e24fb0fbf13c6dc1892ddc32dfb7ae2a52727ddf91b29\"","etag_repository":"W/\"59c3b00646e34b204b375d86787317bd6d2ea10eeb10ab1c6cfe1c4f47f7a10d\"","full_name":"MindFreeze/ha-sankey-chart","last_commit":"bc927e9","last_updated":"2024-04-04T08:08:41Z","last_version":"v1.21.1","open_issues":14,"stargazers_count":301,"topics":["energy-consumption","lovelace-card"],"last_fetched":1712218716.381627},"226862969":{"manifest":{"name":"Light Brightness Preset Row"},"description":"Provides a means to program 3 preset brightness settings for dimmable lights in Home Assistant","etag_releases":"W/\"7285b4b9bcb7b7b0b477ff7eb31030802e77bde61a168d4ac0e64ee3238b727e\"","etag_repository":"W/\"eeccd9faa2a68d88f9f47c7276d8eba9c3abd80135b9ef49abf9b29a0dc4404c\"","full_name":"finity69x2/light-brightness-preset-row","last_commit":"c08112d","last_updated":"2023-05-11T00:30:14Z","last_version":"3.1","open_issues":1,"stargazers_count":29,"last_fetched":1707613154.125101},"276636213":{"manifest":{"name":"Vertical Slider Cover Card"},"description":"Cover card with homekit style vertical position slider (best with panel-mode but normal-mode works also)","downloads":8379,"etag_releases":"W/\"4d6698895b427d07bce399f912db3581bec8d2dd922eed4939b05484d8a831b6\"","etag_repository":"W/\"a15d2a04d6a1c66b5698217c06440c3d75b1fce602f3a7a018ed653f364d6de3\"","full_name":"konnectedvn/lovelace-vertical-slider-cover-card","last_commit":"61b42f3","last_updated":"2022-07-09T10:24:45Z","last_version":"v0.1.5","open_issues":11,"stargazers_count":52,"topics":["card"],"last_fetched":1712045862.033981},"607398282":{"manifest":{"name":"UV Index Card"},"description":"A Lovelace card that shows a the UV index and risk level for Home Assistant","downloads":5565,"etag_releases":"W/\"4edbcca1d1ff5f596942b30b08a617bcf12f9ccfb629fb27964b540b0e362977\"","etag_repository":"W/\"32bb03164aa4d853354987e47755f67b39921be105704ab01cf869af277d4168\"","full_name":"t1gr0u/uv-index-card","last_commit":"467af7d","last_updated":"2024-03-30T06:47:34Z","last_version":"v1.2.1","open_issues":18,"stargazers_count":19,"topics":["uv-index"],"last_fetched":1712105803.719787},"452866308":{"manifest":{"name":"Tabbed Card"},"description":"a custom card for home assistant that utilizes tabs to segregate individual cards.","downloads":12219,"etag_releases":"W/\"9435498c7bb2b0fdc5979a59d696fdba7ef8cde1e5107869fcf62dd3d2f0d41f\"","etag_repository":"W/\"23ecc2ca0396dce893ac72c42e56e2363f9e0906585dd61ba3d56c04db05bab5\"","full_name":"kinghat/tabbed-card","last_commit":"e8c3d61","last_updated":"2023-10-31T17:30:45Z","last_version":"v0.3.2","open_issues":10,"stargazers_count":77,"topics":["card","hacs-custom","home-assistant-component","lovelace-custom-card"],"last_fetched":1711765061.214968},"599334003":{"manifest":{"name":"simple-weather-clock"},"description":"A card for Home Assistant designed to display a digital clock with six slots below for various numeric environmental sensor data.","etag_releases":"W/\"a2462655f67094b2b5cb97a47a2178d5a0a9606ea853a9dca39ad1da97716635\"","etag_repository":"W/\"de2ef2b0072f0b21d074f39a24a01f77889e35130db28a764f0f227646b933f9\"","full_name":"pkscout/simple-weather-clock","last_commit":"55bed15","last_updated":"2023-06-03T21:45:55Z","last_version":"1.00.05","stargazers_count":3,"topics":["clock","weather"],"last_fetched":1707243390.148978},"342944383":{"manifest":{"country":["NL","BE"],"name":"Neerslag Card"},"description":"Display Buienalarm and/or Buienradar data in a graph for Home Assistant.","etag_releases":"W/\"93bb56e9180f188e72ebbe10bf51400fdc916b97073ce19ebb1009e03cb09403\"","etag_repository":"W/\"839db0d401a79d39bfb3be31b7ba77cac1265d572585ef92e4d43f42d8eb4431\"","full_name":"aex351/home-assistant-neerslag-card","last_commit":"f15c9ef","last_updated":"2023-08-23T14:38:02Z","last_version":"2022.07.08.0","open_issues":11,"stargazers_count":26,"last_fetched":1701305828.388395},"142051833":{"manifest":{"name":"Vertical Stack In Card"},"description":"\ud83d\udcd0 Home Assistant Card: Group multiple cards into a single sleek card.","etag_releases":"W/\"cc7491753d7b6e62acae27cf878f7e8205f97aad39ec95f5cb4f93190346ec0d\"","etag_repository":"W/\"230708837c19a531b284720493fa45aacd5998b44c8b443ca4a1d481b1af8e2d\"","full_name":"ofekashery/vertical-stack-in-card","last_commit":"0a6dfbd","last_updated":"2024-03-02T21:52:44Z","last_version":"v0.4.4","open_issues":23,"stargazers_count":825,"last_fetched":1711846904.508889}} ================================================ FILE: tests/fixtures/v2-python_script-data.json ================================================ {"312649007":{"manifest":{"name":"Reminder"},"description":"A python script for Home Assistant that counts down the days to reminder","etag_releases":"W/\"bf7c66f5956e23e786360abc5ad8563b2564ed89ccedbb9bea4460e9f1cd0b35\"","etag_repository":"W/\"9f1594cb9a9a7a42fedae8dce86596702460795c71d4fa3215802ee2f33db78a\"","full_name":"eyalcha/ha-reminder","last_commit":"ed737c2","last_updated":"2020-12-20T21:07:41Z","last_version":"1.0.7","open_issues":2,"stargazers_count":12,"topics":["python-scripts"],"last_fetched":1709748957.448288},"448031517":{"manifest":{"name":"Shellies Discovery Gen2"},"description":"Script that adds MQTT discovery support for Shellies Gen2 devices","downloads":237,"etag_releases":"W/\"3d688f143a81d08f37d1a46e414e47a3e92238a340a05bd65c3aadf57550b818\"","etag_repository":"W/\"e89de3ba825d2f6322a4d878ddc8fdd041bc63aac21beb2a6d6cce777973b45b\"","full_name":"bieniu/ha-shellies-discovery-gen2","last_commit":"60a8daa","last_updated":"2024-03-29T00:34:31Z","last_version":"2.28.0","open_issues":1,"stargazers_count":86,"topics":["discovery","mqtt","shelly"],"last_fetched":1712175291.740307},"233093604":{"manifest":{"country":["NO"],"name":"kodi1/tracker_merge"},"description":"merge master/slave device trackers","etag_repository":"W/\"3f6c93e03bae6ea5539d3fa417cfe7c56ebd3cbf108047425101daae68ce1e9e\"","full_name":"kodi1/tracker_merge","last_commit":"3c517e9","last_updated":"2021-04-21T19:05:19Z","stargazers_count":4,"topics":["tracking"],"last_fetched":1683253693.417649},"198460710":{"manifest":{"name":"Date Countdown"},"description":"A python script for Homeassistant that counts down the days to birthdays, anniversaries etc","etag_releases":"W/\"2ead44d2eb5f8fdca43994ce75839377e7b1d5b266d2a545a6980e240c31c5a3\"","etag_repository":"W/\"d881809325af07d76c8adebf3792ca2b7379c925321826079ac977e689590a1f\"","full_name":"point-4ward/ps-date-countdown","last_commit":"bd6ceaa","last_updated":"2021-05-15T02:00:07Z","last_version":"v6.0","stargazers_count":22,"last_fetched":1706811301.177451},"258712314":{"manifest":{"name":"Fan Speed Control"},"description":"A python script for Home Assistant that control fan speed with Fan Template and Broadlink.","etag_releases":"W/\"c99b074d69e412fc7fb519c58138ac112085e9994180808756f48a3b423fedf5\"","etag_repository":"W/\"9bda6c9e5dc8db71ac1e5c91eb8dd8fdfc8034670959f61970d7d52354c4ed00\"","full_name":"iml885203/HA-FanSpeedControl","last_commit":"5620b54","last_updated":"2022-10-19T06:24:44Z","last_version":"v1.5.4","stargazers_count":16,"last_fetched":1696947120.469701},"194381263":{"manifest":{"name":"Thermostat Update"},"description":"This script updates Z-Wave thermostat entity state and current temperature from external sensor","etag_releases":"W/\"540f712849e36b739f90f70953718ca67e56ca68e54e4f5fe5f60f58a3793992\"","etag_repository":"W/\"5d477e2a6e6708ba99cbaae6df0c7dca80935ce56614cf48457ee4d99a3c15eb\"","full_name":"bieniu/ha-thermostat-update","last_commit":"08d0fc6","last_updated":"2020-04-28T06:54:52Z","last_version":"0.3.5","stargazers_count":12,"topics":["thermostat","z-wave"],"last_fetched":1705961508.89597},"246406566":{"manifest":{"name":"UpdateClimate"},"description":"Python script to update climate devices","etag_releases":"W/\"da159c88427a30160ad078437068f324aced589861c89a67dfafc7da1bb82424\"","etag_repository":"W/\"324511dede9d58f3f9e40a008ee058d86412f3493b1b70e9bb41d5038744c85d\"","full_name":"Santobert/HA-UpdateClimate","last_commit":"73e488b","last_updated":"2021-03-30T17:22:29Z","last_version":"2.0.3","stargazers_count":8,"topics":["climate","hvac","preset","scheduler"],"last_fetched":1709288001.318924},"240900380":{"manifest":{"name":"Entities Script"},"description":"Python script to handle state and attributes of existing sensors and entities","etag_releases":"W/\"a5535fc114065547715ad82acb37df1697c972c64f80ddd406400cc0e0376ae8\"","etag_repository":"W/\"ab9a7f1c74a99d1a89f4e3cd7615df087e6d46a523328f13062bbb2e208b8889\"","full_name":"pmazz/ps_hassio_entities","last_commit":"5a14ea2","last_updated":"2021-03-07T22:15:32Z","last_version":"v1.1.0","open_issues":1,"stargazers_count":52,"last_fetched":1709093709.049491},"194319685":{"manifest":{"name":"Shellies Discovery"},"description":"Script that adds MQTT discovery support for Shellies devices","downloads":689,"etag_releases":"W/\"b9fdbe9b8f9954d5265bccf45b874936ff5a4696614637e6b83ecd6674eb3593\"","etag_repository":"W/\"82b6a0357b0ee062879cf9b52234728ba0e87ee337f340bbce0c271232ff1c3d\"","full_name":"bieniu/ha-shellies-discovery","last_commit":"e561669","last_updated":"2024-03-29T01:04:31Z","last_version":"5.0.0","stargazers_count":280,"topics":["discovery","mqtt","shelly"],"last_fetched":1712175291.639687}} ================================================ FILE: tests/fixtures/v2-removed-data.json ================================================ [{"link":"https://github.com/hacs/default/pull/2","reason":"Security issues, known to steal auth tokens.","removal_type":"critical","repository":"test/test"},{"removal_type":"blacklist","repository":"amaximus/bkk_stop_card"},{"removal_type":"blacklist","repository":"au190/au190_bkk_stop_card"},{"removal_type":"blacklist","repository":"au190/au190_lock_entity"},{"removal_type":"blacklist","repository":"au190/au190_thermostat_card"},{"removal_type":"blacklist","repository":"basnijholt/media_player.kef"},{"removal_type":"blacklist","repository":"benleb/ad-batterycheck"},{"removal_type":"blacklist","repository":"benleb/ad-ench-ad3"},{"removal_type":"blacklist","repository":"bieniu/ha-ad-airly"},{"removal_type":"blacklist","repository":"Boosik/discord_game"},{"removal_type":"blacklist","repository":"boralyl/hass-smartthinq"},{"removal_type":"blacklist","repository":"custom-cards/boilerplate-card"},{"removal_type":"blacklist","repository":"custom-cards/camera-card"},{"removal_type":"blacklist","repository":"custom-cards/custom-card-helpers"},{"removal_type":"blacklist","repository":"custom-cards/information"},{"removal_type":"blacklist","repository":"custom-cards/marquee-state-element"},{"removal_type":"blacklist","repository":"custom-cards/monster-card"},{"removal_type":"blacklist","repository":"custom-cards/muuri-grid"},{"removal_type":"blacklist","repository":"custom-cards/timer-card"},{"removal_type":"blacklist","repository":"custom-cards/tracker-card"},{"removal_type":"blacklist","repository":"custom-components/binary_sensor.hadockermon"},{"removal_type":"blacklist","repository":"custom-components/blueprint"},{"removal_type":"blacklist","repository":"custom-components/camera.multisource"},{"removal_type":"blacklist","repository":"custom-components/cloudflare"},{"removal_type":"blacklist","repository":"custom-components/complimentr"},{"removal_type":"blacklist","repository":"custom-components/custom_cards"},{"removal_type":"blacklist","repository":"custom-components/custom_components"},{"removal_type":"blacklist","repository":"custom-components/custom_updater"},{"removal_type":"blacklist","repository":"custom-components/google_keep"},{"removal_type":"blacklist","repository":"custom-components/hassbian_config"},{"removal_type":"blacklist","repository":"custom-components/information"},{"removal_type":"blacklist","repository":"custom-components/lists"},{"removal_type":"blacklist","repository":"custom-components/sensor.ctabustracker"},{"removal_type":"blacklist","repository":"custom-components/sensor.custom_aftership"},{"removal_type":"blacklist","repository":"custom-components/sensor.custom_cards"},{"removal_type":"blacklist","repository":"custom-components/sensor.custom_components"},{"removal_type":"blacklist","repository":"custom-components/sensor.geoip"},{"removal_type":"blacklist","repository":"custom-components/sensor.launchlibrary"},{"removal_type":"blacklist","repository":"custom-components/sensor.ruter"},{"removal_type":"blacklist","repository":"custom-components/sensor.syncthing"},{"removal_type":"blacklist","repository":"custom-components/sensor.tautulli"},{"removal_type":"blacklist","repository":"custom-components/sensor.versions"},{"removal_type":"blacklist","repository":"custom-components/sickchill"},{"removal_type":"blacklist","repository":"custom-components/switch.hadockermon"},{"removal_type":"blacklist","repository":"custom-components/usps_mail"},{"removal_type":"blacklist","repository":"eifinger/here_travel_time"},{"removal_type":"blacklist","repository":"home-assistant-community-themes/template"},{"removal_type":"blacklist","repository":"home-assistant-community-themes/theme-request"},{"removal_type":"blacklist","repository":"keatontaylor/alexa_media_player"},{"removal_type":"blacklist","repository":"kethoth/green_slate_theme"},{"removal_type":"blacklist","repository":"ljmerza/waze-card"},{"removal_type":"blacklist","repository":"maykar/compact-custom-header"},{"removal_type":"blacklist","repository":"Michsior14/ha-kaiterra"},{"removal_type":"blacklist","repository":"Michsior14/ha-laser-egg"},{"removal_type":"blacklist","repository":"PTST/O365Calendar-HomeAssistant"},{"removal_type":"blacklist","repository":"Rocka84/dual-gauge-card"},{"removal_type":"blacklist","repository":"shaonianzhentan/ha-cloud-music"},{"removal_type":"blacklist","repository":"tenly2000/HomeAssistant-Places"},{"removal_type":"blacklist","repository":"xaviml/z2m_ikea_controller"},{"repository":"r-renato/hass-xiaomi-mi-flora-and-flower-care","reason":"Request from author","removal_type":"blacklist","link":"https://github.com/hacs/integration/pull/1045"},{"repository":"robmarkcole/HASS-Sighthound","reason":"Repository is archived","removal_type":"blacklist","link":"https://github.com/hacs/default/issues/344"},{"repository":"custom-cards/home-setter","reason":"Repository is archived","removal_type":"blacklist","link":"https://github.com/hacs/default/issues/344"},{"repository":"pippyn/Home-Assistant-Sensor-Ophaalkalender","reason":"Repository is archived","removal_type":"blacklist","link":"https://github.com/hacs/default/issues/347"},{"repository":"robmarkcole/Hue-remotes-HASS","reason":"archived","removal_type":"blacklist","link":"https://github.com/hacs/default/issues/392"},{"repository":"sinclairpaul/ha_purple_theme","reason":"No longer maintained","removal_type":"blacklist","link":"https://github.com/hacs/default/pull/427"},{"repository":"briis/mbweather","reason":"Repository is archived","removal_type":"blacklist"},{"repository":"nitobuendia/oura-custom-component","reason":"Request from author","removal_type":"blacklist","link":"https://github.com/hacs/default/pull/509"},{"repository":"custom-cards/button-entity-row","reason":"Not maintained anymore","removal_type":"blacklist","link":"https://github.com/hacs/integration/issues/1315"},{"repository":"heinoldenhuis/home_assistant_area_waste","reason":"Request from author","removal_type":"remove","link":"https://github.com/hacs/default/pull/531"},{"repository":"cgarwood/homeassistant-zwave_mqtt","reason":"deprecated","removal_type":"deprecated","link":"https://github.com/hacs/default/pull/547"},{"repository":"custom-components/sensor.wifi-scanner","reason":"Repository not complete","removal_type":"removed"},{"repository":"lociii/homeassistant-digitalstrom","reason":"archived","removal_type":"blacklist","link":"https://github.com/hacs/integration/issues/1457"},{"repository":"ReneNulschDE/mbapipy","reason":"archived","removal_type":"blacklist","link":"https://github.com/hacs/integration/issues/1457"},{"repository":"amelchio/logbook_cache","reason":"Request from author","removal_type":"removed","link":"https://github.com/hacs/default/pull/578"},{"repository":"Limych/media_player.linkplay","reason":"Requested by author","removal_type":"removed","link":"https://github.com/hacs/default/pull/577"},{"repository":"cbulock/lovelace-battery-entity","reason":"Abandoned, not working properly","removal_type":"remove","link":"https://github.com/hacs/integration/issues/1464"},{"repository":"peternijssen/lovelace-postnl-card","reason":"Can no longer be used","removal_type":"removed","link":"https://github.com/hacs/integration/issues/1533"},{"repository":"ljmerza/calendar-card","reason":"The repository is archived","removal_type":"archived"},{"repository":"OpenXbox/xboxone-home-assistant","reason":"The repository is archived","removal_type":"archived"},{"repository":"Armaell/home-assistant-custom-icons-loader","reason":"Not working after Home Assistant 0.110","removal_type":"removed","link":"https://github.com/hacs/integration/issues/1548"},{"repository":"custom-components/sensor.kodi_recently_added","reason":"Repository is archived","removal_type":"removed"},{"repository":"alryaz/hass-component-yandex-smart-home","reason":"Does not work after 0.115","removal_type":"removed","link":"https://github.com/hacs/integration/issues/1557"},{"repository":"joogps/MQTT-Climate-Sync","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/integration/issues/1562"},{"repository":"maykar/custom-header","reason":"Repository is archived","removal_type":"remove","link":"https://community.home-assistant.io/t/custom-header/155399/1100"},{"repository":"enriqg9/dual-thermostat","reason":"Repository is no longer maintained","removal_type":"remove","link":"https://github.com/hacs/integration/issues/1587"},{"repository":"fineemb/lynk-co","reason":"Repository does not exsist","removal_type":"removal","link":""},{"repository":"xMrVizzy/button-toolbar","reason":"Repository does not exsist","removal_type":"removal","link":"https://github.com/hacs/integration/issues/1696"},{"repository":"MatthewFlamm/nwsradar","reason":"NWS radar server no longer operational","removal_type":"removal","link":"https://github.com/MatthewFlamm/nwsradar/issues/16"},{"repository":"futuretense/lock-manager","reason":"replacing integration","removal_type":"removal","link":"https://github.com/FutureTense/keymaster"},{"repository":"custom-components/uilogs","reason":"Deprecated","removal_type":"remove","link":"https://github.com/custom-components/uilogs/issues/17"},{"repository":"custom-components/sensor.rpi_power","reason":"Repo archived","removal_type":"removal","link":"https://github.com/custom-components/sensor.rpi_power"},{"repository":"badguy99/octocost","reason":"Archived","removal_type":"remove","link":"https://github.com/hacs/integration/issues/1809"},{"repository":"edenhaus/ha-prosenic","reason":"Archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/807"},{"repository":"bratanon/lovelace-conditional-entity-row","reason":"Repository is archived","removal_type":"removed","link":"https://github.com/bratanon/lovelace-conditional-entity-row/issues/2"},{"repository":"Bre77/myair","reason":"Added to Home Assistant core","removal_type":"replaced","link":"https://www.home-assistant.io/integrations/advantage_air/"},{"repository":"bramkragten/lyric","reason":"Added to Home Assistant Core","removal_type":"removal","link":"https://github.com/hacs/default/pull/841"},{"repository":"zha-ng/zha-map","reason":"Deprecated. Available natively now.","removal_type":"removal","link":"https://github.com/zha-ng/zha-map#zha-map-is-deprecated"},{"repository":"ntilley905/faastatus","reason":"Added to Home Assistant Core","removal_type":"removal","link":"https://www.home-assistant.io/integrations/faadelays/"},{"repository":"Petro31/ad_multizone_media_control","reason":"Repository is archived","removal_type":"removal","link":"https://github.com/hacs/integration/issues/2080"},{"repository":"burnnat/ha-polar","reason":"Abandoned","removal_type":"removal","link":"https://github.com/hacs/integration/issues/1960"},{"repository":"nickneos/Appdaemon-ZHA-Xiaomi-Aqara-Switch","reason":"Repository does not exist","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2080"},{"repository":"nickneos/Appdaemon-Xiaomi-Doorbell","reason":"Repository does not exist","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2080"},{"repository":"nickneos/Appdaemon-Xiaomi-Smart-Button","reason":"Repository does not exist","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2080"},{"repository":"jomwells/ambihue","reason":"It's abandoned","removal_type":"replaced","link":"https://github.com/hacs/default/pull/955"},{"repository":"alryaz/hass-mosenergosbyt","reason":"Superseded by 'alryaz/hass-lkcomu-interrao'","removal_type":"blacklist","link":"https://github.com/alryaz/hass-mosenergosbyt/README.md"},{"repository":"azogue/fasthue","reason":"Not needed anymore. Native Hue integration now has local push access.","removal_type":"deprecated","link":"https://github.com/azogue/fasthue/issues/22"},{"repository":"SebuZet/samsungrac","reason":"Repository has been abandoned and it's not working with current HA versions.","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2103"},{"repository":"troykelly/hacs-amberelectric","reason":"Replaced with a superior version maintained by an Amber Electric employee","removal_type":"removal","link":"https://github.com/troykelly/hacs-amberelectric"},{"repository":"bieniu/ha-airly","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2115"},{"repository":"thomasloven/lovelace-dummy-entity-row","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2115"},{"repository":"thomasloven/lovelace-gap-card","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2115"},{"repository":"thomasloven/lovelace-gui-sandbox","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2115"},{"repository":"robmarkcole/Hue-sensors-HASS","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2115"},{"repository":"xlcnd/meteoalarmeu","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2115"},{"repository":"mammuth/ha-fritzbox-tools","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2121"},{"repository":"brefra/home-assistant-plugwise-stick","reason":"Replaced by alternative custom integration","removal_type":"remove","link":"https://github.com/plugwise/plugwise-beta"},{"repository":"avdeevsv91/ha_generic_hygrostat","reason":"Archived repository","removal_type":"remove","link":"https://github.com/hacs/default/pull/1047"},{"repository":"bieniu/ha-gios","reason":"Archived repository","removal_type":"remove","link":"https://github.com/hacs/default/pull/1047"},{"repository":"DavidFW1960/bom_forecast","reason":"Archived repository","removal_type":"remove","link":"https://github.com/hacs/default/pull/1047"},{"repository":"tellerbop/havistapool","reason":"The repository has been archived by the author","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2152"},{"repository":"reharmsen/hass-youless-component","link":"https://github.com/hacs/integration/issues/2192","reason":"Author removed","removal_type":"removal"},{"repository":"Sholofly/ZiggoNext","reason":"Request from author","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2209"},{"repository":"mampfes/hacs_wiffi","reason":"Archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1103"},{"repository":"pilotak/homeassistant-mikrotik","reason":"Archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1103"},{"repository":"PTST/O365-HomeAssistant","reason":"Archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1103"},{"repository":"atomic7777/atomic_calendar","reason":"Archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1103"},{"repository":"doudz/homeassistant-zigate","reason":"Deprecated and not working anymore","removal_type":"remove","link":"https://github.com/hacs/default/pull/1125"},{"repository":"ppanagiotis/pymusiccast","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1149"},{"repository":"estevez-dev/extended-banner-card","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1149"},{"repository":"Kraineff/philips-airpurifier","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1149"},{"repository":"jensweimann/awb","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1149"},{"repository":"briis/smartweather","reason":"Repository is beeing replaced with another repository","removal_type":"remove","link":"https://github.com/briis/smartweather"},{"repository":"sdebruyn/homeassistant-bpost-integration","reason":"Blocked by provider","removal_type":"remove","link":"https://github.com/hacs/default/pull/1205"},{"repository":"heinoldenhuis/home_assistant_omnik_solar","reason":"Repository has been archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1221"},{"repository":"abacao/hass_wibeee","reason":"Superseded by 'luuuis/hass_wibeee'","removal_type":"remove","link":"https://github.com/hacs/default/pull/1242"},{"repository":"rgruebel/ha_zigbee2mqtt_networkmap","reason":"Repository looks abandoned and the content is no longer working","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2517"},{"repository":"And3rsL/Deebot-for-Home-Assistant","reason":"Repository does not follow HACS requirements (Missing issues)","removal_type":"remove","link":"https://github.com/hacs/default/pull/1258"},{"repository":"briis/unifiprotect","reason":"Repository does not follow HACS requirements (Missing issues)","removal_type":"remove","link":"https://github.com/hacs/default/pull/1258"},{"repository":"ericpignet/home-assistant-tplink_router","reason":"No longer maintained","removal_type":"Remove","link":"https://github.com/hacs/integration/issues/2552"},{"repository":"SNoof85/lovelace-tempometer-gauge-card","reason":"No longer maintained","removal_type":"Remove","link":"https://github.com/hacs/default/pull/1356"},{"repository":"maykar/kiosk-mode","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1373"},{"repository":"maykar/lovelace-swipe-navigation","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1373"},{"repository":"custom-cards/upcoming-media-card","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1373"},{"repository":"maykar/plex_assistant","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1373"},{"repository":"custom-components/sensor.sonarr_upcoming_media","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1373"},{"repository":"custom-components/sensor.radarr_upcoming_media","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1373"},{"repository":"custom-components/sensor.plex_recently_added","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1373"},{"repository":"nagyrobi/home-assistant-custom-components-pfsense-gateways","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1373"},{"repository":"pippyn/Home-Assistant-Sensor-Groningen-Afvalwijzer","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1373"},{"repository":"iantrich/aftership-card","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1373"},{"repository":"DSorlov/hasl-platform","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1373"},{"repository":"dr1rrb/ha-twinkly","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1373"},{"repository":"custom-components/combined","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1375"},{"repository":"custom-components/breaking_changes","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1375"},{"repository":"custom-components/unsplash","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1375"},{"repository":"custom-components/templatesensor","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1375"},{"repository":"custom-components/sensor.yandex_maps","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1375"},{"repository":"custom-components/config_check","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1375"},{"repository":"custom-cards/favicon-counter","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1375"},{"repository":"custom-cards/text-element","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1375"},{"repository":"custom-cards/state-attribute-element","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1375"},{"repository":"custom-cards/state-element","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1375"},{"repository":"custom-cards/username-element","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1375"},{"repository":"custom-cards/ext-weblink","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1375"},{"repository":"fred-oranje/rituals-genie","reason":"Repository not available","removal_type":"remove","link":"https://github.com/hacs/default/pull/1402"},{"repository":"DCSBL/ha-homewizard-energy","reason":"Added to Home Assistant core","removal_type":"replaced","link":"https://www.home-assistant.io/integrations/homewizard/"},{"repository":"mattieha/slider-button-card","reason":"Abandoned, community fork maintained at custom-cards/slider-button-card","removal_type":"replaced","link":"https://github.com/custom-cards/slider-button-card"},{"repository":"eavanvalkenburg/sia","reason":"Added to Home Assistant core","removal_type":"replaced","link":"https://www.home-assistant.io/integrations/sia/"},{"repository":"custom-components/authenticated","reason":"No longer maintained","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2769"},{"repository":"opravdin/weback-hass","reason":"No longer maintained","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2806"},{"repository":"georgezhao2010/climate_ewelink","reason":"Archived repository","removal_type":"remove","link":"https://github.com/hacs/default/pull/1482"},{"repository":"Cyr-ius/hass-cozytouch","reason":"Archived repository","removal_type":"remove","link":"https://github.com/hacs/default/pull/1482"},{"repository":"Cyr-ius/hass-hue-service-advanced","reason":"Archived repository","removal_type":"remove","link":"https://github.com/hacs/default/pull/1482"},{"repository":"KTibow/lovelace-light-soft-ui-theme","reason":"Archived repository","removal_type":"remove","link":"https://github.com/hacs/default/pull/1482"},{"repository":"KTibow/lovelace-dark-soft-ui-theme","reason":"Archived repository","removal_type":"remove","link":"https://github.com/hacs/default/pull/1482"},{"repository":"GeorgeSG/lovelace-folder-card","reason":"Archived repository","removal_type":"remove","link":"https://github.com/hacs/default/pull/1482"},{"repository":"custom-components/wienerlinien","reason":"Archived repository","removal_type":"remove","link":"https://github.com/hacs/default/pull/1482"},{"repository":"thomasprior/EthermineInfo","reason":"Request from author","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2851"},{"repository":"Sholofly/arrisdcx960","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1552"},{"repository":"WolfRevo/climate.spzb0001_thermostat","reason":"Requested by author","removal_type":"remove","link":"https://github.com/hacs/default/pull/1613"},{"repository":"Ceerbeerus/beerbolaget","reason":"The integration can no longer be used","removal_type":"remove","link":"https://github.com/hacs/integration/issues/2863"},{"repository":"frenck/home-assistant-theme-outline","reason":"Obsolete and now archived","removal_type":"remove","link":"https://github.com/frenck/home-assistant-theme-outline/pull/41"},{"repository":"natekspencer/hacs-litterrobot","reason":"Repository archived","removal_type":"remove","link":"https://github.com/natekspencer/hacs-litterrobot/issues/17#issuecomment-1370045529"},{"repository":"DavidMStraub/homeassistant-homeconnect","reason":"Repository archived","removal_type":"remove","link":"https://github.com/DavidMStraub/homeassistant-homeconnect/commit/e7231c522b35e8d571a7317c69b5003bf144f48a"},{"repository":"hacf-fr/hassRenaultZE","reason":"Repository archived","removal_type":"remove","link":"https://github.com/hacf-fr/hassRenaultZE/pull/155"},{"repository":"Kraineff/minecraft-version","link":"https://github.com/hacs/integration/issues/2986","reason":"Author removed","removal_type":"removal"},{"repository":"ljmerza/reddit-card","reason":"Repository can not be used with HACS anymore","removal_type":"remove","link":"https://github.com/hacs/default/pull/1672"},{"repository":"dummylabs/watchman","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1674"},{"repository":"clayauld/lovelace-darksky-card","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1674"},{"repository":"marcomow/ble-bulb-card","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1674"},{"repository":"marrobHD/firetv-card","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1674"},{"repository":"NemesisRE/lovelace-swipe-navigation","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1674"},{"repository":"lukich48/hass_mqtt_template_switch","reason":"Repository has been archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1674"},{"repository":"spycle/microbot_push","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/hacs/default/pull/1674"},{"repository":"gjohansson-ST/stl","reason":"Requested by author","removal_type":"remove","link":"https://github.com/hacs/default/pull/1694"},{"repository":"custom-components/sensor.untappd","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/custom-components/sensor.untappd"},{"repository":"jessevl/homeassistant-greenchoice","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/jessevl/homeassistant-greenchoice"},{"repository":"echoromeo/hanobo","reason":"Replaced by official integration","removal_type":"remove","link":"https://www.home-assistant.io/integrations/nobo_hub/"},{"repository":"xannor/ha_reolink_rest","reason":"No longer actively developed due to built in integration","removal_type":"remove","link":"https://github.com/xannor/ha_reolink_rest"},{"repository":"AitorDB/home-assistant-sun-card","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/AitorDB/home-assistant-sun-card"},{"repository":"nagyrobi/home-assistant-custom-components-cover-rf-time-based","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/nagyrobi/home-assistant-custom-components-cover-rf-time-based"},{"repository":"djtimca/HASpaceX","reason":"Source data no longer maintained.","removal_type":"remove","link":"https://github.com/djtimca/HASpaceX"},{"repository":"JuanMTech/orange_dark","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/JuanMTech/orange_dark"},{"repository":"JuanMTech/orange_light","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/JuanMTech/orange_light"},{"repository":"JuanMTech/amoled_blue","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/JuanMTech/amoled_blue"},{"repository":"JuanMTech/green_dark_mode","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/JuanMTech/green_dark_mode"},{"repository":"JuanMTech/green_light_mode","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/JuanMTech/green_light_mode"},{"repository":"robmarkcole/HASS-Deepstack-face","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/robmarkcole/HASS-Deepstack-face"},{"repository":"robmarkcole/HASS-Deepstack-object","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/robmarkcole/HASS-Deepstack-object"},{"repository":"Raukze/home-assistant-fitx","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/Raukze/home-assistant-fitx"},{"repository":"bruxy70/Garbage-Collection","reason":"Most of the functionality included in core (local calendar)","removal_type":"remove","link":"https://github.com/bruxy70/Garbage-Collection#end-of-support"},{"repository":"bieniu/ha-zadnego-ale","reason":"zadnego ale API is down","removal_type":"remove","link":"https://github.com/bieniu/ha-zadnego-ale/issues/150"},{"repository":"Villhellm/custom-sidebar","reason":"No longer working and can not be maintained","removal_type":"remove","link":"https://github.com/hacs/integration/issues/3115"},{"repository":"remco770/garbage-bar-homeassistant","reason":"No longer working and not maintained","removal_type":"remove","link":"https://github.com/hacs/integration/issues/3141"},{"repository":"MTrab/clever","reason":"Requested removed by author","removal_type":"remove","link":"https://github.com/hacs/integration/issues/3142"},{"repository":"Villhellm/lovelace-animated-background","reason":"No longer working and can not be maintained","removal_type":"remove","link":"https://github.com/hacs/integration/issues/3149"},{"repository":"ha0y/xiaomi_miot_raw","reason":"No longer working and not maintained","removal_type":"remove","link":"https://github.com/hacs/integration/issues/3159"},{"repository":"ryannazaretian/hacs-nexia-climate-integration","reason":"No longer working and not maintained","removal_type":"remove","link":"https://github.com/hacs/integration/issues/3165"},{"repository":"walthowd/ha-automower","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/walthowd/ha-automower"},{"repository":"Petro31/ad_people_tracker","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/Petro31/ad_people_tracker"},{"repository":"cgarwood/homeassistant-fullykiosk","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/cgarwood/homeassistant-fullykiosk"},{"repository":"Kibibit/hass-kibibit-theme","reason":"Not maintained anymore","removal_type":"remove","link":"https://github.com/hacs/integration/issues/3171"},{"repository":"mlowijs/HomeAssistant-TeslaCustomComponent","reason":"remove","removal_type":"Integration is missing a version, and is abandoned.","link":"https://github.com/hacs/default/pull/1957"},{"repository":"custom-components/qbo","reason":"remove","removal_type":"Integration is missing a version, and is abandoned.","link":"https://github.com/hacs/default/pull/1957"},{"repository":"jihao/colorfulclouds-hass","reason":"remove","removal_type":"Integration is missing a version, and is abandoned.","link":"https://github.com/hacs/default/pull/1957"},{"repository":"custom-components/linksys_ap","reason":"remove","removal_type":"Integration is missing a version, and is abandoned.","link":"https://github.com/hacs/default/pull/1957"},{"repository":"burnnat/media_player.screenly","reason":"remove","removal_type":"Integration is missing a version, and is abandoned.","link":"https://github.com/hacs/default/pull/1957"},{"repository":"WillowMist/sensor.mylar","reason":"remove","removal_type":"Integration is missing a version, and is abandoned.","link":"https://github.com/hacs/default/pull/1957"},{"repository":"custom-components/fedex","reason":"remove","removal_type":"Integration is missing a version, and is abandoned.","link":"https://github.com/hacs/default/pull/1957"},{"repository":"burnnat/ha-fitness-push","reason":"remove","removal_type":"Integration is missing a version, and is abandoned.","link":"https://github.com/hacs/default/pull/1957"},{"repository":"cyberjunky/home-assistant-plugwise","reason":"remove","removal_type":"Integration is missing a version, and is abandoned.","link":"https://github.com/hacs/default/pull/1957"},{"repository":"jihao/traccar-cn-hass","reason":"remove","removal_type":"Integration is missing a version, and is abandoned.","link":"https://github.com/hacs/default/pull/1957"},{"repository":"elad-bar/ha-dahuavto","reason":"remove","removal_type":"Integration is missing a version, and is abandoned.","link":"https://github.com/hacs/default/pull/1957"},{"repository":"9rpp/securifi","reason":"remove","removal_type":"Integration is missing a version, and is abandoned.","link":"https://github.com/hacs/default/pull/1957"},{"repository":"tmechen/ber_status","reason":"remove","removal_type":"Integration is missing a version, and is abandoned.","link":"https://github.com/hacs/default/pull/1957"},{"repository":"custom-components/srp_energy","reason":"remove","removal_type":"Integration is missing a version, and is abandoned.","link":"https://github.com/hacs/default/pull/1957"},{"repository":"peternijssen/home-assistant-jumbo","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/peternijssen/home-assistant-jumbo"},{"repository":"ericpignet/home-assistant-lg_hombot","reason":"Integration is missing a version, and is abandoned.","removal_type":"remove","link":"https://github.com/hacs/default/pull/1978"},{"repository":"jomwells/ambilight-yeelight","reason":"Integration is missing a version, and is abandoned.","removal_type":"remove","link":"https://github.com/hacs/default/pull/1978"},{"repository":"jomwells/ambilights","reason":"Integration is missing a version, and is abandoned.","removal_type":"remove","link":"https://github.com/hacs/default/pull/1978"},{"repository":"shutupflanders/sensor.moneydashboard","reason":"Integration is missing a version, and is abandoned.","removal_type":"remove","link":"https://github.com/hacs/default/pull/1978"},{"repository":"burnnat/ha-hdhomerun","reason":"Integration is missing a version, and is abandoned.","removal_type":"remove","link":"https://github.com/hacs/default/pull/1978"},{"repository":"timvancann/homeassistant-growatt","reason":"Integration is missing a version, and is abandoned.","removal_type":"remove","link":"https://github.com/hacs/default/pull/1978"},{"repository":"rkoebrugge/hacs-youless-component","reason":"Integration is missing a version, and is abandoned.","removal_type":"remove","link":"https://github.com/hacs/default/pull/1978"},{"repository":"roberodin/ha-samsungtv-custom","reason":"Integration is missing a version, and is abandoned.","removal_type":"remove","link":"https://github.com/hacs/default/pull/1978"},{"repository":"safepay/cover.hd_powerview","reason":"Integration is missing a version, and is abandoned.","removal_type":"remove","link":"https://github.com/hacs/default/pull/1978"},{"repository":"bruxy70/CZ-Public-Transport","reason":"Integration is missing a version, and is abandoned.","removal_type":"remove","link":"https://github.com/hacs/default/pull/1978"},{"repository":"rsnodgrass/hass-flo-water","reason":"Integration is missing a version, and is abandoned.","removal_type":"remove","link":"https://github.com/hacs/default/pull/1978"},{"repository":"rsnodgrass/hass-integrations","reason":"Integration is missing a version, and is abandoned.","removal_type":"remove","link":"https://github.com/hacs/default/pull/1978"},{"repository":"fineemb/Yeelink-ven-fan","reason":"Integration is missing a version, and is abandoned.","removal_type":"remove","link":"https://github.com/hacs/default/pull/1978"},{"repository":"eyalcha/thermal","reason":"Integration is missing a version, and is abandoned.","removal_type":"remove","link":"https://github.com/hacs/default/pull/1978"},{"repository":"custom-components/sytadin","reason":"Integration is missing a version, and is abandoned.","removal_type":"remove","link":"https://github.com/hacs/default/pull/1978"},{"repository":"AdamNaj/linksys_velop","reason":"Integration is missing a version, and is abandoned.","removal_type":"remove","link":"https://github.com/hacs/default/pull/1978"},{"repository":"geertmeersman/telenet","reason":"Repository has been deleted.","removal_type":"remove","link":"https://github.com/hacs/default/pull/1994"},{"repository":"gerardag/person-entity-card","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/gerardag/person-entity-card"},{"repository":"mac-zhou/midea-ac-py","reason":"Repository looks abandoned and the content is no longer working","removal_type":"remove","link":"https://github.com/hacs/integration/issues/3225"},{"repository":"thebino/rki_covid","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/thebino/rki_covid"},{"repository":"dmamontov/hass-ledfx","reason":"No longer maintained","removal_type":"remove","link":"https://github.com/hacs/integration/issues/3257"},{"repository":"custom-cards/light-entity-row","reason":"No longer working and not maintained","removal_type":"remove","link":"https://github.com/hacs/integration/issues/3268"},{"repository":"hasscc/petkit","reason":"Repository has been abandoned.","removal_type":"remove","link":"https://github.com/hacs/integration/issues/3336"},{"repository":"battlemoose/waternsw-waterinsights-ha","reason":"Repository is no longer working","removal_type":"remove","link":"https://github.com/hacs/integration/issues/3335"},{"repository":"tikismoke/home-assistant-nespressoble","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/tikismoke/home-assistant-nespressoble"},{"repository":"ljmerza/ha-our-groceries","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/ljmerza/ha-our-groceries"},{"repository":"ThomasPrior/FlexpoolInfo","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/ThomasPrior/FlexpoolInfo"},{"repository":"ryanbateman/bvg-sensor","reason":"No longer maintained","removal_type":"remove","link":"https://github.com/hacs/integration/issues/3375"},{"repository":"PiotrMachowski/Home-Assistant-custom-components-Google-Keep","reason":"No longer working","removal_type":"remove","link":"https://github.com/hacs/integration/issues/3376"},{"repository":"Tiemooowh/homeassistant-teletask","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/Tiemooowh/homeassistant-teletask"},{"repository":"aijayadams/hass-blueair","reason":"No longer maintained","removal_type":"remove","link":"https://github.com/hacs/integration/issues/3382"},{"repository":"briis/hass-weatherflow","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/briis/hass-weatherflow"},{"repository":"rccoleman/lamarzocco","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/rccoleman/lamarzocco"},{"repository":"toringer/home-assistant-sbanken","reason":"Sbanken API shutdown","removal_type":"remove","link":"https://github.com/toringer/home-assistant-sbanken"},{"repository":"perara/systemair-save-connect","reason":"Repository is archived","removal_type":"remove","link":"https://github.com/perara/systemair-save-connect"},{"repository":"djtimca/hagooglewifi","reason":"Repository is no longer maintained","removal_type":"remove","link":"https://github.com/hacs/integration/issues/3440"},{"repository":"mauro-midolo/homeassistant_electrolux_status","reason":"Repository has been deleted.","removal_type":"remove","link":"https://github.com/hacs/integration/issues/3500"},{"repository":"Shreyas-R/lovelace-wallpanel-screensaver","reason":"Repository is no longer maintained","removal_type":"remove","link":"https://github.com/Shreyas-R/lovelace-wallpanel-screensaver"},{"repository":"hultenvp/home_assistant_omnik_solar","reason":"Requested by author","removal_type":"remove","link":"https://github.com/hultenvp/home_assistant_omnik_solar"}] ================================================ FILE: tests/fixtures/v2-template-data.json ================================================ {"680978332":{"manifest":{"name":"Availability Template"},"description":"Custom Template for checking the availiability of an entity.","etag_releases":"W/\"783b75ac16ec219af5a6ed7bcf404eb5a6431f395548370e2e06507ee2b91679\"","etag_repository":"W/\"6bb57b61bd4c9f8c42b272aec9922d5b172d7dddb1194db2f338a7ab1140409a\"","full_name":"SirGoodenough/Availability-Template","last_commit":"019c303","last_updated":"2024-01-10T05:51:36Z","last_version":"2024.01.01","stargazers_count":3,"topics":["availability","custom-template","jinja2-templates"],"last_fetched":1704874604.838378},"629510143":{"manifest":{"name":"Cheapest Energy Hours"},"description":"Jinja macro to find the cheapest energy prices","etag_releases":"W/\"4757f53596afe93fe92297c14fd83e3238c9b0151a6fd8c303059de1e75bfe79\"","etag_repository":"W/\"df3bd0f0f6d9d12df8b716b836d4583320846ad05b94c1c6f2598ef01c73f692\"","full_name":"TheFes/cheapest-energy-hours","last_commit":"e689dea","last_updated":"2024-04-02T09:24:03Z","last_version":"v5.5.0","open_issues":1,"stargazers_count":32,"topics":["energy-data","energy-prices","jinja","macro"],"last_fetched":1712182291.259169},"624674515":{"manifest":{"name":"Easy Time"},"description":"Easy Time calculations for Home Assistant templates","etag_releases":"W/\"cb5270c4f648e2958b5a46e2b201c340bd69c41076aced8dd815ca8c760930e9\"","etag_repository":"W/\"f62c55fc627398ee323e8494062f79b3e77a0af75fbdec8de4b69461a675b5c5\"","full_name":"Petro31/easy-time-jinja","last_commit":"e2f8844","last_updated":"2024-03-12T12:42:58Z","last_version":"v2.0.0.3","open_issues":3,"stargazers_count":52,"topics":["datetime","daylight-saving-time","jinja","jinja2","relative-time","time-calculate"],"last_fetched":1711542197.486854},"656746023":{"manifest":{"name":"Auto Sun Blind"},"description":"Automatically control your sun blinds via home assistant based on the position of the sun.","etag_releases":"W/\"7a02c7c6dc65c3833dd84119f8400cc6477859a7726ad34c28e5a79b3ea5433a\"","etag_repository":"W/\"bc9d6c11b6b40b4ed8a8b06565d3002e8e4f3c63df570f95d25410bf8f9b0c7b\"","full_name":"langestefan/auto-sun-blind","last_commit":"67983ae","last_updated":"2024-03-04T16:39:22Z","last_version":"v1.0.0","open_issues":2,"stargazers_count":19,"topics":["automation","blueprint","cover","energy-management","solar","sun","sunrise-sunset"],"last_fetched":1710778574.678547},"694582318":{"manifest":{"name":"Logic Chekr"},"description":"Check a list of entities to see their Boolean state. Jinja Custom Template.","etag_releases":"W/\"cbb3d2f202523869f70037b73f178801178a8ad7b261bf245102eae8a56fc283\"","etag_repository":"W/\"e3626cd350c05ea246eae8ef01dc70a3d16c6781f53e4688960b00541aea2a33\"","full_name":"SirGoodenough/Logic-Chekr","last_commit":"c7c86c2","last_updated":"2024-01-10T05:48:44Z","last_version":"2024.01.01","stargazers_count":3,"topics":["bool","boolean","custom-template","jinja2-templates"],"last_fetched":1707984919.296444},"624337782":{"manifest":{"name":"Relative Time Plus"},"description":"Relative Time Macro with additional options","etag_releases":"W/\"89d01f16fcce828a5183adc9eb5662c96ef43c7c5bacca6af553bc64edeb79c0\"","etag_repository":"W/\"5f869860659c70191399d1012a1d5d4d007cc5f7026fa8c5f4a3bd5772eb7999\"","full_name":"TheFes/relative-time-plus","last_commit":"db784b4","last_updated":"2024-04-04T08:13:53Z","last_version":"v2.1.0","stargazers_count":19,"topics":["jinja2","relative-time"],"last_fetched":1712225592.955387},"724754572":{"manifest":{"name":"Color Multi Tool"},"description":"Toolbox to work with and convert colors rgb, hs, xy, and Color Name. It will also provide random colors in any format, attempt to match your RGB value to an official color, and test if the color is valid (numbers or name).","etag_releases":"W/\"a33f016bb68fb8f334f7fab3fab4db237db1b0cf7460e3aea566a38b26cf3fec\"","etag_repository":"W/\"fbe02513690e1f8532742d864919f153cd884a740fe364478cdf60d03e613fb1\"","full_name":"SirGoodenough/Color-Multi-Tool","last_commit":"f6968cd","last_updated":"2024-01-13T00:33:11Z","last_version":"2024.10.11.01","stargazers_count":5,"topics":["color","color-name","converter","custom-template","hs","jinja2-templates","rgb","xy"],"last_fetched":1710612893.777206}} ================================================ FILE: tests/fixtures/v2-theme-data.json ================================================ {"457458731":{"manifest":{"name":"Material 3 Dark & Light Theme 07: DarkOliveGreen"},"description":"Material Design 3 based theme (dark olive green) for Home Assistant","etag_releases":"W/\"9261138b57be60ecdc9d2ae5d4e82221ea84024bb9e8e29fc3d35e9c1de6f1e7\"","etag_repository":"W/\"68d57388914a633667d9617692be2ebb4141bb19eef5d107aaa4d9bde7b9ecb4\"","full_name":"AmoebeLabs/HA-Theme_M3-07-DarkOliveGreen","last_commit":"79afa56","last_updated":"2022-06-15T07:56:39Z","last_version":"v1.1.2","stargazers_count":1,"topics":["dark-mode","dark-theme","home-assistant-theme","light-mode","light-theme","material-3"],"last_fetched":1678386249.195671},"214664317":{"manifest":{"name":"Midnight Theme"},"description":"Midnight theme for Home Assistant","etag_repository":"W/\"9a10c09a16c14099bc980f9efcbccaae00f965373b07d1024d4effea15f26fca\"","full_name":"home-assistant-community-themes/midnight","last_commit":"8f7c619","last_updated":"2024-02-19T15:00:37Z","open_issues":2,"stargazers_count":53,"last_fetched":1708359415.957452},"214979604":{"manifest":{"name":"Dark Mint Theme"},"description":"Another Dark theme for Home Assistant","etag_repository":"W/\"93526d28d565c59cc1cc1e81f67d6636266912e7dabae3915b87fc62912305fa\"","full_name":"home-assistant-community-themes/dark-mint","last_commit":"40a3600","last_updated":"2023-03-27T21:57:12Z","open_issues":4,"stargazers_count":4,"last_fetched":1708078410.405248},"470262899":{"manifest":{"name":"Nordic Theme"},"description":"Nordic theme for home assistant.","etag_releases":"W/\"6f56fac43c38a40428a7e45ae75d4d76f9f492e435599ec1369903c4be472b0a\"","etag_repository":"W/\"d0a557aa12c4ddf0396c0e8c0d8f31b7396c3a32913edf649ab311b63112fd34\"","full_name":"coltondick/nordic-theme-main","last_commit":"3bd9583","last_updated":"2022-04-30T13:38:21Z","last_version":"v1.1","stargazers_count":7,"last_fetched":1678386249.741998},"202203063":{"manifest":{},"description":"Synthwave inspired theme for Home Assistant","etag_releases":"W/\"5fdfb046ba54821477d7648720c9f9b170cd47350ba10b6b89882bbdba411913\"","etag_repository":"W/\"a1487444211cf629633faa3847102fc758d5db14d1b38cf7ff1a3387cf258bed\"","full_name":"bbbenji/synthwave-hass","last_commit":"23c9bf2","last_updated":"2022-06-13T03:57:15Z","last_version":"0.3.5","stargazers_count":149,"topics":["css","home-assistant-theme","javascript","synthwave"],"last_fetched":1710735281.144568},"197006509":{"manifest":{"name":"Slate Theme"},"description":"A Dark Theme for Home Assistant","etag_repository":"W/\"342af8429165d85b5afcbc6c78be2d9e4e97cf82bab1df8bffb6db3e7ac0f1a4\"","full_name":"seangreen2/slate_theme","last_commit":"01db05b","last_updated":"2024-02-05T19:33:27Z","open_issues":4,"stargazers_count":108,"last_fetched":1710195098.818782},"221288367":{"manifest":{"name":"Clear Theme Dark"},"description":"Dark variant of Clear Theme for Home Assistant","etag_releases":"W/\"283dd2b1eed5ee967d1a9bc3a070ccaa0698a3d46d17cf5eca8ea1a2b6abf1f0\"","etag_repository":"W/\"5abe85679485f4828c0504f9d75f1b889d80c9dd90978857a4f48450f29767bd\"","full_name":"naofireblade/clear-theme-dark","last_commit":"75af86a","last_updated":"2020-10-08T10:10:57Z","last_version":"v1.3","stargazers_count":16,"last_fetched":1678386253.514684},"236318024":{"manifest":{"name":"iOS Themes - Dark Mode and Light Mode"},"description":"\u2764\ufe0f\ud83d\udcf1\ud83c\udfe0\ud83e\udd16 Themes inspired by iOS Dark \u2b1b\ufe0f and Light \u25fb\ufe0f Mode for Lovelace Home Assistant with different backgrounds by @basnijholt","etag_releases":"W/\"12cf7fb1ebc669caa7d8892a5c185db05d290626db8d553e2f455224cfc755cf\"","etag_repository":"W/\"f1d20053a06d08fea1ac69a3e8f57e195c482b06ac07adb363fabdff0465e864\"","full_name":"basnijholt/lovelace-ios-themes","last_commit":"30fdac5","last_updated":"2022-11-20T20:05:49Z","last_version":"v2.11.0","open_issues":38,"stargazers_count":547,"last_fetched":1712211364.329751},"222422187":{"manifest":{"name":"iOS Dark Mode Theme"},"description":"\ud83c\udfe0\ud83e\udd16 Theme by @basnijholt based on iOS Dark Mode for Lovelace Home Assistant ","etag_repository":"W/\"87a9135cf24ff294f5d79c907dba68fe249fac38c3f5abc6a80043632af0f3ae\"","full_name":"basnijholt/lovelace-ios-dark-mode-theme","last_commit":"2805f18","last_updated":"2022-11-03T15:53:32Z","open_issues":36,"stargazers_count":441,"topics":["dark-mode","darkmode","ios"],"last_fetched":1712175284.233302},"227988032":{"manifest":{"name":"sweet pink"},"description":"Theme for home assistant that makes use of pinks and purples and maybe some teal","etag_releases":"W/\"30500d8f430cc37182a64364bc85d13cade284d960aa24eb3e87f4cadc7d538a\"","etag_repository":"W/\"7994f6e44941f714c6eb3f5cc3cb777d570d8464ad9fcedfc1e52ed50d9fdd02\"","full_name":"estiens/sweet_pink_hass_theme","last_commit":"64c34f7","last_updated":"2022-05-14T18:31:48Z","last_version":"v1.0.1","stargazers_count":4,"topics":["cyberpunk","lovelace-theme"],"last_fetched":1687753057.432618},"387055527":{"manifest":{"name":"Waves"},"description":"This is a blend of 2 themes found within the Home Assistant community. Inspired mostly by Noctis, I've adjust colours slightly and have also opted to pull some features from Caule Theme packs to build my own 'ultimate' theme. I will continue to update overtime and do my best to credit those whom I have 'referenced' ","etag_releases":"W/\"8912c3d580a83294f4d7ed2312dc2fdef68bd04874db67e26a4e5aadaf95f8b0\"","etag_repository":"W/\"c6fbd3d136fe029cb2d74c8f0f06120816d21b26b1c3c371d4b47361c823a4af\"","full_name":"tgcowell/waves","last_commit":"d3d595a","last_updated":"2023-03-26T08:21:03Z","last_version":"v2.4.1","open_issues":6,"stargazers_count":75,"last_fetched":1710951399.782725},"215075805":{"manifest":{"name":"Blue Night Theme"},"description":"Blue Night theme for Home Assistant","etag_repository":"W/\"fe6baa96c6f0382894efc3f9b1158b6b6828d9fefefa026309826e8d1ac41dad\"","full_name":"home-assistant-community-themes/blue-night","last_commit":"d8631df","last_updated":"2024-02-19T05:52:25Z","open_issues":2,"stargazers_count":8,"last_fetched":1708323443.446039},"274111031":{"manifest":{"name":"Animated Weather Card"},"description":"Animated icons for default Home Assistant weather card","etag_releases":"W/\"36db107311e366a881b5836a11f6acd52a0e2f840d6a1ba080539f6e1cce56ab\"","etag_repository":"W/\"81bc5409f558978bb1f30185dee59285585be16e58c72c8bcd25ff991b0172d2\"","full_name":"wowgamr/animated-weather-card","last_commit":"75a6cb6","last_updated":"2022-06-05T21:09:01Z","last_version":"1.2","open_issues":3,"stargazers_count":22,"topics":["weather-card"],"last_fetched":1708337626.844931},"236277163":{"manifest":{"name":"Reeder Dark Theme"},"description":"Reeder Dark Theme for Home Assistant","etag_repository":"W/\"c6dc81711f6e7e835b0289dfae6b683934f34d92e2f700ed480e31280670d50d\"","full_name":"hekm77/reeder_dark_theme","last_commit":"dbd319f","last_updated":"2020-09-18T07:41:54Z","stargazers_count":9,"last_fetched":1706019167.374228},"292621909":{"manifest":{"name":"Windows 10 themes"},"description":"Home Assistant Windows 10 inspired themes","etag_releases":"W/\"d6123fbf57e9cabbc62771c45c376d4b62024313fe7920d5fc81430e7242c342\"","etag_repository":"W/\"75a989b4967e266fbd65e5dd6b7479befadcfa6d133d18a7392be7d3b08e1d58\"","full_name":"mikosoft83/hass-windows10-themes","last_commit":"7248ba9","last_updated":"2023-10-20T13:49:07Z","last_version":"2.1","open_issues":1,"stargazers_count":10,"topics":["accent-color","windows","windows-10"],"last_fetched":1709612102.726598},"458817847":{"manifest":{"name":"Material 3 Dark & Light Theme 04: Magenta"},"description":"Material Design 3 / Material YOU theme for Home Assistant","etag_releases":"W/\"988a1525f0efcecb6fcf0daea8871c89fee6e74321e6cc643ebe6fd86f4fa342\"","etag_repository":"W/\"9bbb5155925b5c265097b60c1cd1f4f6547bf6ea62f8a38e269b233bf1bcd7bc\"","full_name":"AmoebeLabs/HA-Theme_M3-04-Magenta","last_commit":"a451ffd","last_updated":"2022-06-15T07:59:38Z","last_version":"v1.1.2","topics":["dark-mode","home-assistant-theme","light-mode","material-3"],"last_fetched":1706040859.628011},"309056232":{"manifest":{"name":"GitHub Dark Theme"},"description":"A Home Assistant theme inspired on Github.","etag_releases":"W/\"6c8a8f0480661965f794833969931ac3965bd2879a14bfc1122e243f4e2807e3\"","etag_repository":"W/\"c44a4ca96c19a8efcaac8dca911e0ed638889a467e622ba4b0be07b9ecc6699c\"","full_name":"einschmidt/github_dark_theme","last_commit":"3694047","last_updated":"2023-08-23T06:12:41Z","last_version":"v2.3","open_issues":1,"stargazers_count":5,"topics":["assistant-theme"],"last_fetched":1707812162.802114},"223938651":{"manifest":{"name":"Midnight Blue Theme"},"description":"Midnight Blue theme for Home Assistant","etag_repository":"W/\"414e5a17bfd3001d7fc82f4f28793df898f4e20b8ec5ad55e6457b68c655b815\"","full_name":"home-assistant-community-themes/midnight-blue","last_commit":"80e087a","last_updated":"2023-03-27T22:57:02Z","open_issues":3,"stargazers_count":5,"last_fetched":1708078411.521851},"253311340":{"manifest":{"name":"3Ative Blue Theme"},"description":"\ud83d\ude0e My Theme 'Blue' - with semi-transparent Cards","etag_releases":"W/\"f36d39da9881c88a6bec377d5f84eff761230e0f91551d53531a1d95e8a3da8a\"","etag_repository":"W/\"b2c0d48b43fe9ece63ddfbfe73b04d9f916c2e05667b8221ead85d35ebd773f2\"","full_name":"3ative/3ative-blue-theme","last_commit":"822bbcb","last_updated":"2023-07-30T09:08:42Z","last_version":"v1.7.2","stargazers_count":4,"topics":["3ative","blue","theme-ui"],"last_fetched":1702973777.594144},"216165131":{"manifest":{"name":"Solarized Light Theme"},"description":"Solarized Light theme for Home Assistant","etag_repository":"W/\"dc8fb60a6d420b1fc6088f27a09a4f89acf933616b56fa80c1e6496b8191654b\"","full_name":"home-assistant-community-themes/solarized-light","last_commit":"00e0701","last_updated":"2023-03-27T02:57:14Z","open_issues":1,"stargazers_count":4,"last_fetched":1708078411.575705},"574163721":{"manifest":{"name":"Graphite Theme"},"description":"Calm and clean dark theme for Home Assistant","etag_releases":"W/\"1269c5c69abe08cce3353ac448226fc8c3e1e8f64380da9eaadb571082a292b9\"","etag_repository":"W/\"5581d436f92a67de2506ad15b550ab5c060fe90199211883c78210114420a7af\"","full_name":"TilmanGriesel/graphite","last_commit":"ba2e92d","last_updated":"2023-01-27T19:36:59Z","last_version":"2.1","open_issues":1,"stargazers_count":49,"topics":["calm","clean","dark","dark-theme","flat","minimalist","modern"],"last_fetched":1711383353.364928},"458636658":{"manifest":{"name":"iOS Theme - Based on the system-wide light and dark mode UI"},"description":"\ud83c\udfa8 By JuanMTech -- Theme based on the iOS system-wide light and dark mode interface","etag_releases":"W/\"7f21f4f699fb85f8657527e8ec4d853066790deac9b35efb1dd3a1b9b533498f\"","etag_repository":"W/\"f2f261f951284bec8addce1953e75fc67bc6eb7c4525572079471e9966dbfa74\"","full_name":"JuanMTech/ios-theme","last_commit":"f317a60","last_updated":"2023-01-13T19:19:48Z","last_version":"v.14","open_issues":2,"stargazers_count":27,"topics":["darkmode","darktheme","lightmode","lighttheme"],"last_fetched":1711988170.809883},"261924981":{"manifest":{"name":"Swart Ninja Dark Theme"},"description":"\ud83c\udfa8 Green, dark mode theme for Home Assistant, Enjoy.\ud83e\udd18\ud83c\udffb","etag_releases":"W/\"be9a2f233d598a3c5573773ff2f6d506cbedd36d34c1079ac0b5fd90f747ed93\"","etag_repository":"W/\"cb6e616bde3b90ee9d6155b539068a1c7e7271671cec32138b90d30eb803a877\"","full_name":"DickSwart/swart_ninja_dark_theme","last_commit":"e5b62fd","last_updated":"2022-03-04T09:56:36Z","last_version":"v1.0.2","open_issues":1,"stargazers_count":5,"topics":["dark-theme"],"last_fetched":1705680992.55886},"701591334":{"manifest":{"name":"Material Rounded Theme - Based on Material You by Google on Android"},"description":"A Material You and Google Home app influenced theme for Home Assistant","etag_releases":"W/\"772dec0ee7298ca32fffebec9aafa458f629d7c3b99b259569cfe18f026abea8\"","etag_repository":"W/\"db21c903beac4dc8fbb37bf22d86c4a7b40291b404095c7f71da6abc850d0923\"","full_name":"Nerwyn/material-rounded-theme","last_commit":"f21d0f1","last_updated":"2024-03-06T00:48:51Z","last_version":"1.5.3","open_issues":1,"stargazers_count":27,"topics":["hacs-theme","homeassistant-themes"],"last_fetched":1712146964.863354},"216173358":{"manifest":{"name":"Christmas Theme"},"description":"Christmas theme for Home Assistant","etag_repository":"W/\"a5776ad02f2d8e1a86707a898655c908df79335f7837834bb6cf5060a12cc3e7\"","full_name":"home-assistant-community-themes/christmas","last_commit":"57d3aee","last_updated":"2023-03-27T23:57:09Z","open_issues":1,"stargazers_count":1,"last_fetched":1708078410.381585},"403381222":{"manifest":{"name":"Noctis-Solarized"},"description":"Noctis theme made Solarized","etag_repository":"W/\"6115ca8d6e7bd745d02e1ada234a40cc5f68fd2afdf98ca72abee8198f750e70\"","full_name":"williamahartman/noctis-solarized","last_commit":"c2cb37d","last_updated":"2022-03-06T20:37:36Z","open_issues":1,"stargazers_count":5,"topics":["home-assistant-theme"],"last_fetched":1710821705.714726},"309053262":{"manifest":{"name":"GitHub Light Theme"},"description":"A Home Assistant theme inspired on Github.","etag_releases":"W/\"620f940050af4dd210d40323f88d0a468b42045568d7ac165a61d22e98e8d87c\"","etag_repository":"W/\"4a40abcd80cd0c58f2a4f8b5a8f31b9f80699188f45707aa4467369ff0e483fc\"","full_name":"einschmidt/github_light_theme","last_commit":"726ec1b","last_updated":"2023-12-01T17:56:43Z","last_version":"v1.3","open_issues":1,"stargazers_count":4,"topics":["assistant-theme"],"last_fetched":1706602511.418178},"458664750":{"manifest":{"name":"Google Theme - Based on the Android light and dark interface"},"description":"\ud83c\udfa8 By JuanMTech -- Theme based on the Google Android light and dark mode interface","etag_releases":"W/\"45d6526a957d03847fa20664e76c45d6ccf5f8fe97de170c446a4cd7c90bb459\"","etag_repository":"W/\"dad9ccce6ca7df5ca116cc3b3f0ca85c53abd3b0f59becae6d0b5bb6840d6921\"","full_name":"JuanMTech/google-theme","last_commit":"373d014","last_updated":"2024-01-23T15:01:38Z","last_version":"v1.4","open_issues":5,"stargazers_count":97,"topics":["darkmode","googletheme","lightmode"],"last_fetched":1711068853.213594},"306914292":{"manifest":{"name":"Transparent Blue"},"description":"A transparent blue theme for Home Assistant","etag_releases":"W/\"53bb2f75430ce009b8ba16fa57cdaca55e84a46014a6d84d59fad9ce05fda150\"","etag_repository":"W/\"11a3b821482b21016c4c87f0f591b8ba4b5421af42fa872c4d64068715040671\"","full_name":"JOHLC/transparentblue","last_commit":"85b1ca5","last_updated":"2023-12-12T15:17:11Z","last_version":"v2023.12.2","stargazers_count":27,"topics":["homeassistant-addons","transparent-blue-theme","transparentblue","yaml"],"last_fetched":1704803042.280086},"255366214":{"manifest":{"name":"Vintage"},"description":"\ud83c\udf99\ufe0f Vintage theme original colours & style designed by @surendrananup HACS adapted by @Banditen01","etag_releases":"W/\"a99f8bb4df20db792ffe6424c38a2b9344ab8a1d4c4eebfb9570d9e8c645d0cb\"","etag_repository":"W/\"194b7419123316e93806ed337dee01e1f613c914c873ed69946028a6d4f35d27\"","full_name":"Banditen01/vintage_theme","last_commit":"51fa000","last_updated":"2023-09-30T07:27:22Z","last_version":"1.3.7.5","open_issues":2,"stargazers_count":7,"topics":["unofficial"],"last_fetched":1712009559.851779},"456201687":{"manifest":{"name":"Mushroom Themes"},"description":"Additional themes for Lovelace Mushroom Cards \ud83c\udf44","etag_releases":"W/\"2083a1d5620b6124b5c6dd79bda0cceab3f016fb4cdba5c02f54f6f8f566f595\"","etag_repository":"W/\"69f942c0beb642104f3d3c5533efd107584f0b3727b90a8400465e8765820e6e\"","full_name":"piitaya/lovelace-mushroom-themes","last_commit":"266d570","last_updated":"2024-02-01T19:25:22Z","last_version":"v0.0.9","open_issues":9,"stargazers_count":202,"topics":["mushroom"],"last_fetched":1712175285.929277},"498774862":{"manifest":{"name":"Material 3 Dark & Light Theme C11: Purple"},"description":"Material Design 3 / Material YOU theme for Home Assistant","etag_releases":"W/\"4d230e88fa1dd8a3f75714c6f385dacc20e7baeb8aaff61d066b89a6e4b59eb6\"","etag_repository":"W/\"3bb0cb34bb322bd8bcb0644c39a3edcf269b34accb300a24459e3f02a94e9941\"","full_name":"AmoebeLabs/HA-Theme_M3-C11-Purple","last_commit":"626f64a","last_updated":"2022-06-15T07:58:53Z","last_version":"v1.1.2","open_issues":1,"stargazers_count":1,"topics":["dark-mode","dark-theme","home-assistant-theme","light-mode","light-theme","material-3"],"last_fetched":1706105582.218172},"230974064":{"manifest":{"name":"Oxford Blue"},"description":"Oxford blue theme for Home Assistant","etag_repository":"W/\"76bed705c2b41abc51aa8cdc91c409b7b54e5b21bb0c4aba3ed2f07ebe7596f1\"","full_name":"arsaboo/oxford_blue_theme","last_commit":"ce33c91","last_updated":"2020-02-27T00:08:56Z","open_issues":1,"stargazers_count":5,"last_fetched":1701779049.841538},"221287384":{"manifest":{"name":"Clear Theme"},"description":"Clear Theme for Home Assistant","etag_releases":"W/\"83af3eb6400315af69e528430b0eddc64e9e4c2e83292474f2a7889424e86b99\"","etag_repository":"W/\"f18916a28b50012422d8a5fb4512e728f6fa54ea247035e4509126b5d30a2388\"","full_name":"naofireblade/clear-theme","last_commit":"a9f68e1","last_updated":"2024-01-06T22:26:08Z","last_version":"v1.1","open_issues":3,"stargazers_count":21,"last_fetched":1705680993.820354},"230672465":{"manifest":{"name":"Ugly Christmas Theme"},"description":"Christmas theme for Home-Assistant","etag_repository":"W/\"c73d3150ce6e2e9424767c4a2528a1f534767d3715f42b3e6002836c602696f1\"","full_name":"houtknots/UglyChristmas-Theme","last_commit":"9f96f83","last_updated":"2023-11-21T11:11:20Z","last_fetched":1700569484.820869},"464998514":{"manifest":{"name":"Cyberpunk 2077 Theme"},"description":"Cyberpunk 2077 GUI inspied Home Assistant theme","etag_releases":"W/\"101eedd077b74c8afc67813aec6099d088a595706386df22ac1a2a86fbf6874c\"","etag_repository":"W/\"6f9c7bfa748e75943526de01404f92cd4f2e985171c6aa5ec04a1ce5bba94bc6\"","full_name":"flejz/hass-cyberpunk-2077-theme","last_commit":"78077ad","last_updated":"2023-03-27T22:58:46Z","last_version":"0.0.4","open_issues":6,"stargazers_count":36,"topics":["cyberpunk","cyberpunk-2077"],"last_fetched":1710195097.442138},"235057110":{"manifest":{"name":"Material Dark Red Theme"},"description":"Material Dark Red theme for Home Assistant","etag_repository":"W/\"f2e17a8b1d08db97ad99f598032d6b540882e08e84af0e35aefa42a20df42201\"","full_name":"home-assistant-community-themes/material-dark-red","last_commit":"88e9656","last_updated":"2023-03-22T23:57:27Z","open_issues":1,"stargazers_count":3,"last_fetched":1708078411.43906},"234581410":{"manifest":{"name":"UX Goodie Theme"},"description":"\ud83c\udfa8 Theme for Home Assistant inspired by iOS Dark Mode \ud83c\udf16","etag_releases":"W/\"7b7dd08a9eeab4462cf7a3d8dd806ce269b85fc5a51f375198243d2d4a004915\"","etag_repository":"W/\"0218899a41579b572b9a94eeeb5a84aa89b4086938fd026665ce8d9ff53f455a\"","full_name":"fi-sch/ux_goodie_theme","last_commit":"17c5b93","last_updated":"2022-05-27T21:05:56Z","last_version":"1.9.2","open_issues":1,"stargazers_count":11,"topics":["dark","ios","lovelace-theme","mode","ux"],"last_fetched":1701871932.365596},"216183299":{"manifest":{"name":"Material Dark Pink Theme"},"description":"Material Dark Pink theme for Home Assistant","etag_repository":"W/\"91cb1e496f85cec117a2673eca5c521154bc713d7e7401919c22412887ff48d6\"","full_name":"home-assistant-community-themes/material-dark-pink","last_commit":"386a3b2","last_updated":"2023-03-27T19:57:38Z","open_issues":2,"stargazers_count":3,"last_fetched":1708078410.845369},"443651710":{"manifest":{"name":"Midnight Teal"},"description":"A dark teal theme for HomeAssistant.","etag_releases":"W/\"5dc0c93380ba1421d5c4f6d5e77a7356e686a5d6269393582fe5af03a17a6d09\"","etag_repository":"W/\"178ccec8b981c7de5ba9bc753b5ff6705a4bc33a49f1ce37c1ffed07604d147b\"","full_name":"Neekster/MidnightTeal","last_commit":"e4efc2e","last_updated":"2022-03-11T20:50:36Z","last_version":"v2.1","stargazers_count":1,"topics":["dark-theme"],"last_fetched":1684879968.223331},"216181396":{"manifest":{"name":"Teal Theme"},"description":"Teal theme for Home Assistant","etag_repository":"W/\"0f70ee5f30a4ec71d595f89b708e60b69b4c1441189c4cbdad8684f4e43c0f28\"","full_name":"home-assistant-community-themes/teal","last_commit":"8b9a363","last_updated":"2023-04-03T14:07:08Z","open_issues":1,"stargazers_count":1,"last_fetched":1708078411.603753},"231083679":{"manifest":{"name":"Dark Teal"},"description":"\ud83d\udc35 Dark Theme based on clear-theme-dark by @naofireblade","etag_releases":"W/\"918b5deb5d0239c2e55b0cfef38066c897549c644496281196ede004c95120ad\"","etag_repository":"W/\"4454c28d6400bc59ee6afb2c46b1c0c2b7ba39f81c29420c70c03740083c9b25\"","full_name":"aFFekopp/dark_teal","last_commit":"9644980","last_updated":"2022-03-15T09:06:42Z","last_version":"1.4","stargazers_count":22,"topics":["dark-theme","home-assistant-theme"],"last_fetched":1709287999.54904},"216178553":{"manifest":{"name":"Material Dark Green Theme"},"description":"Material Dark Green theme for Home Assistant","etag_repository":"W/\"1fae6fb7e8d31a3092aa545c090332da710e5d81b17dd6b73ef2f5126ceb5ea1\"","full_name":"home-assistant-community-themes/material-dark-green","last_commit":"37fe700","last_updated":"2023-03-27T02:57:14Z","open_issues":2,"stargazers_count":2,"last_fetched":1708078410.669548},"441738040":{"manifest":{"country":["US"],"name":"Soft Theme"},"description":"\ud83c\udfa8 A new, simple soft theme for Home Assistant.","etag_repository":"W/\"984087174da8b1d73eef883b419152ce2f5a92a1d100e9635ea4f5be07b76881\"","full_name":"KTibow/lovelace-soft-theme","last_commit":"54bc8a1","last_updated":"2024-01-07T01:57:21Z","open_issues":1,"stargazers_count":34,"topics":["soft-ui"],"last_fetched":1709993591.094174},"223028160":{"manifest":{"name":"Green Slate Theme"},"description":"Green adaptation of this Home-Assistant theme: https://github.com/seangreen2/slate_theme","etag_repository":"W/\"f746067c1373231c1fcca4395334bc8f51e88d659fa04c6b1a44112ab1ae2b77\"","full_name":"pbeckcom/green_slate_theme","last_commit":"c67b3f1","last_updated":"2019-11-20T22:22:55Z","stargazers_count":1,"last_fetched":1678386253.842994},"270638476":{"manifest":{"name":"Nord Theme"},"description":"Nord theme for Home Assistant","etag_repository":"W/\"e1a8a73b71ffe6ec387bb148b8fd1f5e763156c8e54d6d5148078924146e85ab\"","full_name":"home-assistant-community-themes/nord","last_commit":"c391d2d","last_updated":"2023-04-03T13:58:06Z","open_issues":3,"stargazers_count":13,"last_fetched":1709244679.708601},"284293899":{"manifest":{"name":"iOS Dark Mode"},"description":"\ud83c\udfa8 By JuanMTech -- A Home Assistant theme inspired on the iOS dark mode interface.","etag_releases":"W/\"744350080ae6646f2ce858e297239dc6a11becaa55150b38bdfb46e2fd994f09\"","etag_repository":"W/\"b4d65ef327a94e78d1297b3cae752bbfe28d0d86360b5b6fbb29fe71becfa6a5\"","full_name":"JuanMTech/ios_dark_mode_theme","last_commit":"2770891","last_updated":"2023-01-12T22:58:52Z","last_version":"v1.4","open_issues":1,"stargazers_count":19,"topics":["dark-mode","dark-theme"],"last_fetched":1691791883.071946},"234022648":{"manifest":{"name":"Google Dark Theme"},"description":"\ud83c\udfa8 By JuanMTech -- A Home Assistant theme inspired on the Google app dark mode.","etag_releases":"W/\"d4542bb16ac49eaa6e0f26700de4838ce3229c2c4d65f695f0d5a99dd37c745b\"","etag_repository":"W/\"1337b4015d7d4a29172dce21da6cabd049bfe213e59a6a11fecd671f6db971f4\"","full_name":"JuanMTech/google_dark_theme","last_commit":"0dc836c","last_updated":"2023-01-12T22:47:14Z","last_version":"v1.13","stargazers_count":139,"last_fetched":1709741727.815235},"534353896":{"manifest":{"country":["US","GB"],"name":"HA LCARS"},"description":"LCARS theme for Home Assistant","etag_releases":"W/\"bf3b2c8037027d0d632dda1dc5017e62f92b2983626ee9910680c488b2a13e6b\"","etag_repository":"W/\"fcda0d3e9f8a75c8e9389eb99c531e5a4e8946371beeb66c16813bba463743ae\"","full_name":"th3jesta/ha-lcars","last_commit":"22df835","last_updated":"2024-02-24T19:36:35Z","last_version":"HA-LCARS-2.2.4","open_issues":16,"stargazers_count":235,"topics":["ha-theme","hacs-theme","homeassistant-themes","lcars","lcars-interface","lcars-style","startrek"],"last_fetched":1711570410.19757},"234375294":{"manifest":{"name":"Vaporwave Pink Theme"},"description":"Vaporwave Pink Theme for Home Assistant","etag_releases":"W/\"9a83cd37231e3bcf0fd74279a62a07c85bf29a56899c0c0e37ceaadb2eb51a30\"","etag_repository":"W/\"b7adaba770cd0991aade5d05bc7fec95daa10379c072590b7da7ed93103953fc\"","full_name":"home-assistant-community-themes/vaporwave-pink","last_commit":"bcdba33","last_updated":"2022-06-17T14:41:05Z","last_version":"v1.1","open_issues":3,"stargazers_count":3,"topics":["80s","pink","vaporwave"],"last_fetched":1708078411.594342},"255270395":{"manifest":{"name":"Stell Blue with Colors Theme"},"description":"Stell Blue with Colors theme for Home Assistant","etag_repository":"W/\"89f683d6a928a847a5659ef589346641df797547693faf34e63b94dbd8e2b150\"","full_name":"home-assistant-community-themes/stell-blue-with-colors","last_commit":"d5d209c","last_updated":"2024-02-19T08:32:24Z","open_issues":1,"stargazers_count":2,"last_fetched":1708337625.975564},"277068969":{"manifest":{"name":"Caule Themes Pack 1 - by caule.studio"},"description":"10 modern colors | 4 categories of styles (Black Glass, Black, Dark, Light) | 40 themes in total | Animated icons for the weather forecast card | And a bonus automatic theme selector for your interface.","etag_releases":"W/\"fdbb918b1c29fa608272d33517f6db3f2f749f368cece45be1f245900f9fba8c\"","etag_repository":"W/\"b1a29806cfe520890cbe4d88bb677eea2bd2abac09fab29f9c7429cc03115262\"","full_name":"orickcorreia/caule-themes-pack-1","last_commit":"0ec8a4b","last_updated":"2023-10-05T00:53:45Z","last_version":"v.1.3.3","open_issues":7,"stargazers_count":244,"topics":["caule","pack"],"last_fetched":1711155184.262098},"234032927":{"manifest":{"name":"Google Light Theme"},"description":"\ud83c\udfa8 By JuanMTech -- A Home Assistant theme inspired on the Google app light mode.","etag_releases":"W/\"f6c61c42cea5189e9cc763cc313326b2756667f5ded3cc09fb670934c54b9d59\"","etag_repository":"W/\"23b4d9ce2ac58e8c15a608e069bbcfe9b0907bb30137a90ef79881e7f04a2a45\"","full_name":"JuanMTech/google_light_theme","last_commit":"4959d09","last_updated":"2023-01-12T22:52:07Z","last_version":"v1.13","open_issues":1,"stargazers_count":56,"topics":["assistant-theme"],"last_fetched":1691542995.458331},"233445397":{"manifest":{"name":"Sundown Theme"},"description":"Custom theme for home assistant","etag_releases":"W/\"1836177ebd6b0b6a76505a0d513d6d74d1115acb3a5fbac435049f6f563c6692\"","etag_repository":"W/\"556f6156d3e39207ffd7e49ef18a1c572e2e418ac0dd6206c681af1d47635476\"","full_name":"am80l/sundown","last_commit":"bdfa827","last_updated":"2020-07-29T01:28:19Z","last_version":"1.0.6","stargazers_count":4,"last_fetched":1703465862.177112},"235984421":{"manifest":{"name":"Blackened Theme"},"description":"Blackened theme for Home Assistant","etag_repository":"W/\"4d28453e9024dc88ec982e9e8cff4ebb6fb4a10da845ec34abeb1f15c11f70f9\"","full_name":"home-assistant-community-themes/blackened","last_commit":"4393cc3","last_updated":"2024-02-16T11:09:26Z","open_issues":2,"stargazers_count":8,"last_fetched":1708086093.049482},"479056577":{"manifest":{"name":"Green and Dark Theme: Simple, clean, and green"},"description":"A dark theme with green accents for Home Assistant based off green_dark_mode by JuanMTech, with mods by dmyoung9","etag_releases":"W/\"86be8f0cff71698ef502268d696ec0eab6668eb57dd5c850d3bab796f2fbba01\"","etag_repository":"W/\"f93f1f0f14a65457c7b1d65297f9f443e93862f2d83e24fade6216fca0639804\"","full_name":"Matt-PMCT/Green-and-Dark-HA-Theme","last_commit":"1ee907a","last_updated":"2022-04-07T16:57:33Z","last_version":"Release","stargazers_count":2,"topics":["dark-theme","green"],"last_fetched":1694912181.447809},"320117484":{"manifest":{"name":"Vibrant (Dark) Clear Theme"},"description":"Vibrant (Dark) Version of Clear Theme","etag_releases":"W/\"a6e4383a17d6603aa8111c2d025fa424d0fb532b3bcc255c0fc24de939d2ed49\"","etag_repository":"W/\"529c4c0d84c66c4001350174606d9b4d97ef62f2392fb35855bd6ff6f269211d\"","full_name":"myleskeeffe/clear-theme-dark-vibrant","last_commit":"bec2afe","last_updated":"2021-02-10T10:21:44Z","last_version":"v2.0.7","stargazers_count":2,"topics":["clear","dark","vibrant"],"last_fetched":1678386253.504105},"448355900":{"manifest":{"name":"Vastayan Bond"},"description":"\ud83c\udfa8 Home Assistant Theme inspired by the color schemes of Xayah & Rakan!","etag_releases":"W/\"1472b18733eeaea8a66aa5a8853a2dd78871e50ce459b80a0b6785353d27cb97\"","etag_repository":"W/\"6e5c837e7ab405ded4c7bf6c0a9d0dc569cb0116b315da1a879a4e9b8ae007ab\"","full_name":"SnakeFist007/ha_vastayan_bond","last_commit":"9c4478c","last_updated":"2023-02-28T15:06:25Z","last_version":"v1.3","open_issues":1,"stargazers_count":2,"topics":["bond","rakan","vastayan","xayah"],"last_fetched":1690812723.401968},"249722008":{"manifest":{"name":"Your Name."},"description":"Home Assistant theme - A dark, electric blue theme that reminds the movie Your Name. ","etag_repository":"W/\"8148fe992d039c77426355f9e33083fb36aae262b2e4dc5edde778e2be6886a7\"","full_name":"Nihvel/your_name","last_commit":"ecd0eec","last_updated":"2023-11-13T13:25:42Z","open_issues":1,"stargazers_count":37,"last_fetched":1711361637.361363},"407627914":{"manifest":{"name":"Google Dark Theme"},"description":"A fork of popular Home Assistant Google dark theme with animated icons","etag_releases":"W/\"f6f529654cdc3ee7e6765590904f4a9a6b367c89e9b911e25cb510ee7f474026\"","etag_repository":"W/\"f740a4ad583600171f0b0403cecb5cfe249717984561c3c9b11bcf14ea9d4cd7\"","full_name":"pacjo/google_dark_animated","last_commit":"1f59fba","last_updated":"2021-11-22T17:05:56Z","last_version":"v1.9","open_issues":2,"stargazers_count":4,"topics":["ha"],"last_fetched":1709741728.38051},"284294048":{"manifest":{"name":"iOS Light Mode"},"description":"\ud83c\udfa8 By JuanMTech -- A Home Assistant theme inspired on the iOS light mode interface.","etag_releases":"W/\"3a88557feb17b3af4d512583559d3174ad4b42478f7d5026057dd4f442d8fdbc\"","etag_repository":"W/\"adb89058e5e20958040829e2797a95bd582dda1755a4120e5cda52b175da3869\"","full_name":"JuanMTech/ios_light_mode_theme","last_commit":"35834c2","last_updated":"2023-01-12T22:54:45Z","last_version":"v1.4","stargazers_count":16,"last_fetched":1681827332.177518},"220641275":{"manifest":{"name":"Dark Orange Theme"},"description":"Dark Orange theme for Home Assistant","etag_repository":"W/\"f35d1fbca3e67f3c09d2ccb44f102f693ba3dfd75ca8ce84b915ac122ab8c142\"","full_name":"home-assistant-community-themes/dark-orange","last_commit":"e74397d","last_updated":"2023-03-22T19:58:15Z","open_issues":2,"stargazers_count":11,"last_fetched":1708078410.433487},"162468030":{"manifest":{"name":"Dark Theme Pack for Home Assistant"},"description":"A collection of modern, clean but colorfull dark themes for the Home Assistant UI. Comes in six different colors (Blue / Green / Orange / Pink / Turqoise / Yellow).","etag_releases":"W/\"d60428cc8065260e182b6ec9c0920c655c54321b0626c6198ac5e91708b6b975\"","etag_repository":"W/\"5a6016eba8d4b1a324998ede7fce49c858608128a3fe6bee7d5671dcae36fe5b\"","full_name":"awolkers/home-assistant-themes","last_commit":"fed0c0f","last_updated":"2022-11-04T12:54:46Z","last_version":"v1.2.1","open_issues":1,"stargazers_count":12,"topics":["dark-mode","dark-theme","home-assistant-theme","lovelace-theme"],"last_fetched":1711397601.307605},"486045869":{"manifest":{"name":"Metrology - Metro + Fluent + Windows Themes - by mmak.es"},"description":"\ud83c\udfa8 Give your Home Assistant a modern and clean facelift. \ud83d\udfe5\ud83d\udfe7\ud83d\udfe9\ud83d\udfe6\ud83d\udfea 24 Variations with 2 Styles + 6 Colors (Magenta Red / Orange / Green / Blue / Purple) + \ud83c\udf1e Light and \ud83c\udf1a Dark modes included. Based on Metro and Fluent UI Design Systems from Microsoft Windows.","etag_releases":"W/\"6389973712d614170248133e06467bc8732e6f8c9672ef749b0f168c375612f0\"","etag_repository":"W/\"497426fa61d51c47011eb7a727ce0fdc6b0de6dc2585f9fbf8152b6df9e9535e\"","full_name":"Madelena/Metrology-for-Hass","last_commit":"3e85876","last_updated":"2023-04-04T23:04:20Z","last_version":"v.1.9.1","open_issues":10,"stargazers_count":501,"topics":["home-assistant-config","lovelace-theme"],"last_fetched":1712105661.05041},"233715171":{"manifest":{"name":"Darkish Theme"},"description":"Darkish-Theme for Home Assistant","etag_repository":"W/\"36a93b86f4bf7d59a97e48b31bd95880e170d332d36500d1ba85ef645efc1d59\"","full_name":"78wesley/Home-Assistant-Darkish-Theme","last_commit":"505d536","last_updated":"2021-12-14T20:45:38Z","stargazers_count":5,"last_fetched":1678386249.129702},"234750356":{"manifest":{"name":"iOS Light Mode Theme"},"description":"\ud83c\udfe0\ud83e\udd16 Theme based on iOS Light Mode for Lovelace Home Assistant ","etag_repository":"W/\"fabb7cb43d982b8a4aa67ac7a87cec948db76a5120da0a491bab49afc420c2a7\"","full_name":"basnijholt/lovelace-ios-light-mode-theme","last_commit":"d3d404b","last_updated":"2020-01-20T19:48:02Z","stargazers_count":9,"topics":["ios","light-mode","lightmode"],"last_fetched":1685304804.755544},"231829137":{"manifest":{"name":"Noctis"},"description":"\ud83d\udc35 Dark Blue Theme for Home Assistant","etag_releases":"W/\"097880929a409b48c3497ad56268bbb2028800cc5a821d976d64e8735f45f683\"","etag_repository":"W/\"b9e1c44a6a1da9b27258f91c5f53850c3ea3220de67de3de4da1e54ae33f7510\"","full_name":"aFFekopp/noctis","last_commit":"0b81d11","last_updated":"2023-12-17T11:40:12Z","last_version":"3.1","open_issues":7,"stargazers_count":192,"topics":["dark-theme","home-assistant-theme"],"last_fetched":1710821703.867657},"226567922":{"manifest":{"name":"Red slate theme"},"description":"My red\"isch\" home assistant theme.","etag_releases":"W/\"3703bc392f2adfacd0ad2ff58fb1e85824ea9678f6ef77986c613e0ab780d2a7\"","etag_repository":"W/\"d578c6147dda0dd30a90920aa3fe197aeef7f79fc1af63d404cbbe3572dcc793\"","full_name":"Poeschl/slate_red","last_commit":"4a2fbff","last_updated":"2024-02-18T14:01:29Z","last_version":"1.6.0","stargazers_count":1,"topics":["material-design","red"],"last_fetched":1708265436.032299},"461936688":{"manifest":{"name":"Whatsapp Theme"},"description":"Home Assistant theme based on Whatsapp's colors","etag_releases":"W/\"e83ce70b5624bc893008650f95a83bd025636fca4e77c45a0b3592ffdeb9a001\"","etag_repository":"W/\"839415820995b2dc5e6ed2aeeef8cd67fef185fd4ed98b7d9a818a5cf1833c30\"","full_name":"robinwittebol/whatsapp-theme","last_commit":"9f39a14","last_updated":"2022-07-17T12:43:07Z","last_version":"1.1.1","open_issues":1,"stargazers_count":12,"topics":["darkmode","green","lightmode","whatsapp","whatsapptheme"],"last_fetched":1711174775.136727},"209891408":{"manifest":{"name":"Amoled Theme"},"description":"Amoled theme for Home Assistant","etag_repository":"W/\"3b95d30f5f9bb32cca9e85d2bcd0a5ca7f981b5451838919bc6e3a345565bc41\"","full_name":"home-assistant-community-themes/amoled","last_commit":"42302e1","last_updated":"2023-03-23T02:57:45Z","open_issues":4,"stargazers_count":27,"last_fetched":1708078410.191534},"703332819":{"manifest":{"name":"Dracula-ish Theme for HA"},"description":"Dracula-Inspired Theme for Home Assistant with light and dark modes. ","etag_releases":"W/\"7c3034c322697012ce4d83038cefa3af7d9f21a5ecef2427ed38596499fdcfbc\"","etag_repository":"W/\"48bd07db71b4d954a0729f271a0e2b0ed4c7fec355923dcf3dab97362263e83a\"","full_name":"malcolmturnbull/draculaish-ha-theme","last_commit":"333e527","last_updated":"2023-10-13T02:30:40Z","last_version":"V1.0.0","open_issues":2,"stargazers_count":6,"topics":["hacs-theme","home-assistant-theme"],"last_fetched":1709108142.96031},"570909059":{"manifest":{"name":"Catppuccin Theme"},"description":"\ud83c\udfe0 Soothing pastel theme for Home Assistant","etag_releases":"W/\"3c9427418669db3e37a414f197cf3f484727380162cff6b948d891ead73f1571\"","etag_repository":"W/\"c05c3df2960fa0db9c8e94f16c949d75e63f1b5bfdb063c76e4184c949abea8c\"","full_name":"catppuccin/home-assistant","last_commit":"e877188","last_updated":"2024-03-23T19:47:11Z","last_version":"v1.0.2","open_issues":4,"stargazers_count":105,"topics":["catppuccin","catppuccin-theme"],"last_fetched":1712019456.665066},"480992848":{"manifest":{"name":"macOS Theme - Based on the system-wide light and dark mode UI"},"description":"\ud83c\udfa8 By JuanMTech -- Theme based on the macOS system-wide light and dark mode interface","etag_releases":"W/\"20eb6ca2e40d872f0f252b02f69036ec8b6d3259104d5cc5da53c6f2ed0ce85c\"","etag_repository":"W/\"5607a9eb6b664aed8d5f6c438953eafa869f445b341ea21a840d6f1a4652ca83\"","full_name":"JuanMTech/macOS-Theme","last_commit":"908836c","last_updated":"2023-01-13T19:20:50Z","last_version":"v1.4","open_issues":1,"stargazers_count":53,"topics":["darktheme","lighttheme"],"last_fetched":1711068853.351137},"225969186":{"manifest":{"name":"Aqua Fiesta Theme"},"description":"Aqua Fiesta theme for Home Assistant","etag_releases":"W/\"ae774046a554d38f09d4b2984cdf54b2b6fbb07479e9e4421116189f52842dba\"","etag_repository":"W/\"651cfaf4f10305f2a150077cb7261968364cf1c02302191d8acb88a99bdf7d4a\"","full_name":"home-assistant-community-themes/aqua-fiesta","last_commit":"618fb98","last_updated":"2024-02-19T09:54:24Z","last_version":"v1.0","open_issues":2,"stargazers_count":4,"last_fetched":1708337625.441429},"217374413":{"manifest":{"name":"Halloween Theme"},"description":"Halloween theme for Home Assistant","etag_repository":"W/\"aa028e761efdc1d457b08520e7e4a27db4431ef5e1789c09c55c64d081635995\"","full_name":"home-assistant-community-themes/halloween","last_commit":"9859e42","last_updated":"2023-03-27T19:57:15Z","open_issues":2,"stargazers_count":3,"last_fetched":1708078410.594304},"215075899":{"manifest":{"name":"Grey Night Theme"},"description":"Grey Night theme for Home Assistant","etag_repository":"W/\"30037cf975e43d277b039f0df2cf0833d0dfd8082dfd4904e72e4fe8f7af5955\"","full_name":"home-assistant-community-themes/grey-night","last_commit":"38ae52a","last_updated":"2024-02-19T10:56:21Z","open_issues":2,"stargazers_count":4,"last_fetched":1708345358.98973}} ================================================ FILE: tests/hacsbase/test_backup.py ================================================ """HACS Backup Test Suite.""" # pylint: disable=missing-docstring import os from custom_components.hacs.utils.backup import Backup def test_file(hacs, tmpdir): with open(f"{tmpdir.dirname}/dummy_file", "w") as dummy: dummy.write("") backup = Backup(hacs=hacs, local_path=f"{tmpdir.dirname}/dummy_file") backup.create() assert not os.path.exists(backup.local_path) assert os.path.exists(backup.backup_path_full) backup.restore() assert os.path.exists(backup.local_path) backup.cleanup() assert not os.path.exists(backup.backup_path_full) def test_directory(hacs, tmpdir): os.makedirs(f"{tmpdir.dirname}/dummy_directory", exist_ok=True) backup = Backup(hacs=hacs, local_path=f"{tmpdir.dirname}/dummy_directory") backup.create() assert not os.path.exists(backup.local_path) assert os.path.exists(backup.backup_path_full) backup.restore() assert os.path.exists(backup.local_path) backup.cleanup() assert not os.path.exists(backup.backup_path_full) def test_muilti(hacs, tmpdir): backup = Backup(hacs=hacs, local_path=f"{tmpdir.dirname}/dummy_directory") backup.create() backup.create() ================================================ FILE: tests/hacsbase/test_configuration.py ================================================ """HacsConfiguration Test Suite.""" # pylint: disable=missing-docstring import pytest from custom_components.hacs.base import HacsConfiguration from custom_components.hacs.exceptions import HacsException def test_configuration_and_option(): config = HacsConfiguration() config.update_from_dict({"token": "xxxxxxxxxx"}) assert isinstance(config.to_json(), dict) assert isinstance(config.token, str) assert config.token == "xxxxxxxxxx" assert isinstance(config.sidepanel_title, str) assert config.sidepanel_title == "HACS" assert isinstance(config.sidepanel_icon, str) assert config.sidepanel_icon == "hacs:hacs" assert isinstance(config.appdaemon, bool) assert not config.appdaemon assert isinstance(config.python_script, bool) assert not config.python_script assert isinstance(config.theme, bool) assert not config.theme assert isinstance(config.country, str) assert config.country == "ALL" assert isinstance(config.release_limit, int) assert config.release_limit == 5 def test_ignore_experimental(): """Test experimental setting is ignored.""" config = HacsConfiguration() assert not hasattr(config, "experimental") config.update_from_dict({"experimental": False}) assert not hasattr(config, "experimental") def test_ignore_netdaemon(): """Test netdaemon setting is ignored.""" config = HacsConfiguration() assert not hasattr(config, "netdaemon") config.update_from_dict({"netdaemon": True}) assert not hasattr(config, "netdaemon") def test_edge_update_with_none(): config = HacsConfiguration() with pytest.raises(HacsException): assert config.update_from_dict(None) ================================================ FILE: tests/hacsbase/test_hacs.py ================================================ # pylint: disable=missing-module-docstring, missing-function-docstring import pytest from custom_components.hacs.base import HacsRepositories from custom_components.hacs.enums import HacsCategory async def test_hacs(hacs, repository, tmpdir): hacs.hass.config.config_dir = tmpdir hacs.repositories = HacsRepositories() assert hacs.repositories.get_by_id(None) is None repository.data.id = "1337" repository.data.category = "integration" repository.data.installed = True hacs.repositories.register(repository) assert hacs.repositories.get_by_id("1337").data.full_name == "test/test" assert hacs.repositories.get_by_id("1337").data.full_name_lower == "test/test" hacs.repositories = HacsRepositories() assert hacs.repositories.get_by_full_name(None) is None hacs.repositories.register(repository) assert hacs.repositories.get_by_full_name("test/test").data.id == "1337" assert hacs.repositories.is_registered(repository_id="1337") assert hacs.repositories.category_downloaded(category=HacsCategory.INTEGRATION) for category in [x for x in list(HacsCategory) if x != HacsCategory.INTEGRATION]: assert not hacs.repositories.category_downloaded(category=category) await hacs.async_process_queue() async def test_add_remove_repository(hacs, repository, tmpdir): hacs.hass.config.config_dir = tmpdir repository.data.id = "0" hacs.repositories.register(repository) hacs.repositories.set_repository_id(repository, "42") # Once its set, it should never change with pytest.raises(ValueError): hacs.repositories.set_repository_id(repository, "30") # Safe to set it again hacs.repositories.set_repository_id(repository, "42") assert hacs.repositories.get_by_full_name("test/test") is repository assert hacs.repositories.get_by_id("42") is repository hacs.repositories.unregister(repository) assert hacs.repositories.get_by_full_name("test/test") is None assert hacs.repositories.get_by_id("42") is None # Verify second removal does not raise hacs.repositories.unregister(repository) ================================================ FILE: tests/hacsbase/test_hacsbase_data.py ================================================ """Data Test Suite.""" from unittest.mock import patch from custom_components.hacs.base import HacsRepositories from custom_components.hacs.enums import HacsGitHubRepo from custom_components.hacs.utils.data import HacsData async def test_hacs_data_async_write1(hacs, repository): data = HacsData(hacs) repository.data.installed = True repository.data.installed_version = "1" hacs.repositories.register(repository) await data.async_write() async def test_hacs_data_async_write2(hacs): data = HacsData(hacs) hacs.system.disabled_reason = None hacs.repositories = HacsRepositories() await data.async_write() async def test_hacs_data_restore_write_not_new(hacs, caplog): data = HacsData(hacs) async def _mocked_loads(hass, key): if key == "repositories": return { "1727333146": { "category": "integration", "full_name": "hacs/integration2", "installed": True, "show_beta": True, }, "202226247": { "category": "integration", "full_name": "shbatm/hacs-isy994", "installed": False, }, } elif key == "hacs": return {} elif key == "data": return {} elif key == "renamed_repositories": return {} else: raise ValueError(f"No mock for {key}") with patch("os.path.exists", return_value=True), patch( "custom_components.hacs.utils.data.async_load_from_store", side_effect=_mocked_loads, ): await data.restore() assert hacs.repositories.get_by_id("202226247") assert hacs.repositories.get_by_full_name("shbatm/hacs-isy994") assert hacs.repositories.get_by_id("1727333146") assert hacs.repositories.get_by_full_name(HacsGitHubRepo.INTEGRATION) assert hacs.repositories.get_by_id("1727333146").data.show_beta is True assert hacs.repositories.get_by_id("1727333146").data.installed is True with patch("custom_components.hacs.utils.data.async_save_to_store") as mock_async_save_to_store: await data.async_write() assert mock_async_save_to_store.called assert "Loading base repository information" not in caplog.text ================================================ FILE: tests/helpers/classes/test_repository_data.py ================================================ from custom_components.hacs.repositories.base import RepositoryData def test_guarded(): data = RepositoryData.create_from_dict({"full_name": "test"}) assert data.name == "test" data.update_data({"name": "new"}) assert data.name != "new" test = data.to_json() test["name"] = "new" assert data.name != "new" ================================================ FILE: tests/helpers/classes/test_validate_class.py ================================================ from custom_components.hacs.utils.validate import Validate def test_validate(): validate = Validate() assert validate.success validate.errors.append("test") assert not validate.success ================================================ FILE: tests/helpers/download/test_gather_files_to_download.py ================================================ """Helpers: Download: gather_files_to_reload.""" # pylint: disable=missing-docstring from aiogithubapi.models.release import GitHubReleaseModel from aiogithubapi.objects.repository.content import AIOGitHubAPIRepositoryTreeContent def test_gather_files_to_download(repository): repository.content.path.remote = "" repository.tree = [ AIOGitHubAPIRepositoryTreeContent( {"path": "test/path/file.file", "type": "blob"}, "test/test", "main", ), ] files = [x.path for x in repository.gather_files_to_download()] assert "test/path/file.file" in files def test_gather_plugin_files_from_root(repository_plugin): repository_plugin.content.path.remote = "" repository_plugin.tree = [ AIOGitHubAPIRepositoryTreeContent({"path": "test.js", "type": "blob"}, "test/test", "main"), AIOGitHubAPIRepositoryTreeContent({"path": "dir", "type": "tree"}, "test/test", "main"), AIOGitHubAPIRepositoryTreeContent({"path": "aaaa.js", "type": "blob"}, "test/test", "main"), AIOGitHubAPIRepositoryTreeContent( {"path": "dist/test.js", "type": "blob"}, "test/test", "main", ), ] repository_plugin.update_filenames() files = [x.path for x in repository_plugin.gather_files_to_download()] assert "test.js" in files assert "dir" not in files assert "aaaa.js" in files assert "dist/test.js" not in files def test_gather_plugin_files_from_dist(repository_plugin): repository = repository_plugin repository.content.path.remote = "dist" repository.data.file_name = "test.js" repository.tree = [ AIOGitHubAPIRepositoryTreeContent({"path": "test.js", "type": "blob"}, "test/test", "main"), AIOGitHubAPIRepositoryTreeContent( {"path": "dist/image.png", "type": "blob"}, "test/test", "main", ), AIOGitHubAPIRepositoryTreeContent( {"path": "dist/test.js", "type": "blob"}, "test/test", "main", ), AIOGitHubAPIRepositoryTreeContent( {"path": "dist/subdir", "type": "tree"}, "test/test", "main", ), AIOGitHubAPIRepositoryTreeContent( {"path": "dist/subdir/file.file", "type": "blob"}, "test/test", "main", ), ] files = [x.path for x in repository.gather_files_to_download()] assert "test.js" not in files assert "dist/image.png" in files assert "dist/subdir/file.file" in files assert "dist/subdir" not in files assert "dist/test.js" in files def test_gather_plugin_multiple_plugin_files_from_dist(repository_plugin): repository = repository_plugin repository.content.path.remote = "dist" repository.data.file_name = "test.js" repository.tree = [ AIOGitHubAPIRepositoryTreeContent({"path": "test.js", "type": "blob"}, "test/test", "main"), AIOGitHubAPIRepositoryTreeContent( {"path": "dist/test.js", "type": "blob"}, "test/test", "main", ), AIOGitHubAPIRepositoryTreeContent( {"path": "dist/something_other.js", "type": "blob"}, "test/test", "main", ), ] files = [x.path for x in repository.gather_files_to_download()] assert "test.js" not in files assert "dist/test.js" in files assert "dist/something_other.js" in files def test_gather_plugin_files_from_release(repository_plugin): repository = repository_plugin repository.data.file_name = "test.js" repository.data.releases = True release = GitHubReleaseModel({"tag_name": "3", "assets": [{"name": "test.js"}]}) repository.releases.objects = [release] files = [x.name for x in repository.gather_files_to_download()] assert "test.js" in files def test_gather_plugin_files_from_release_multiple(repository_plugin): repository = repository_plugin repository.data.file_name = "test.js" repository.data.releases = True repository.releases.objects = [ GitHubReleaseModel({"tag_name": "3", "assets": [{"name": "test.js"}, {"name": "test.png"}]}), ] files = [x.name for x in repository.gather_files_to_download()] assert "test.js" in files assert "test.png" in files def test_gather_zip_release(repository_plugin): repository = repository_plugin repository.data.file_name = "test.zip" repository.repository_manifest.zip_release = True repository.repository_manifest.filename = "test.zip" repository.releases.objects = [ GitHubReleaseModel({"tag_name": "3", "assets": [{"name": "test.zip"}]}), ] files = [x.name for x in repository.gather_files_to_download()] assert "test.zip" in files def test_single_file_repo(repository): repository.content.single = True repository.data.file_name = "test.file" repository.tree = [ AIOGitHubAPIRepositoryTreeContent( {"path": "test.file", "type": "blob"}, "test/test", "main", ), AIOGitHubAPIRepositoryTreeContent({"path": "dir", "type": "tree"}, "test/test", "main"), AIOGitHubAPIRepositoryTreeContent( {"path": "test.yaml", "type": "blob"}, "test/test", "main", ), AIOGitHubAPIRepositoryTreeContent( {"path": "readme.md", "type": "blob"}, "test/test", "main", ), ] files = [x.path for x in repository.gather_files_to_download()] assert "readme.md" not in files assert "test.yaml" not in files assert "test.file" in files def test_gather_content_in_root_theme(repository_theme): repository = repository_theme repository.repository_manifest.content_in_root = True repository.content.path.remote = "" repository.data.file_name = "test.yaml" repository.tree = [ AIOGitHubAPIRepositoryTreeContent( {"path": "test.yaml", "type": "blob"}, "test/test", "main", ), AIOGitHubAPIRepositoryTreeContent({"path": "dir", "type": "tree"}, "test/test", "main"), AIOGitHubAPIRepositoryTreeContent( {"path": "test2.yaml", "type": "blob"}, "test/test", "main", ), ] files = [x.path for x in repository.gather_files_to_download()] assert "test2.yaml" not in files assert "test.yaml" in files def test_gather_appdaemon_files_base(repository_appdaemon): repository = repository_appdaemon repository.tree = [ AIOGitHubAPIRepositoryTreeContent({"path": "test.py", "type": "blob"}, "test/test", "main"), AIOGitHubAPIRepositoryTreeContent( {"path": "apps/test/test.py", "type": "blob"}, "test/test", "main", ), AIOGitHubAPIRepositoryTreeContent( {"path": ".github/file.file", "type": "blob"}, "test/test", "main", ), ] files = [x.path for x in repository.gather_files_to_download()] assert ".github/file.file" not in files assert "test.py" not in files assert "apps/test/test.py" in files def test_gather_appdaemon_files_with_subdir(repository_appdaemon): repository = repository_appdaemon repository.data.file_name = "test.py" repository.tree = [ AIOGitHubAPIRepositoryTreeContent({"path": "test.py", "type": "blob"}, "test/test", "main"), AIOGitHubAPIRepositoryTreeContent( {"path": "apps/test/test.py", "type": "blob"}, "test/test", "main", ), AIOGitHubAPIRepositoryTreeContent( {"path": "apps/test/core/test.py", "type": "blob"}, "test/test", "main", ), AIOGitHubAPIRepositoryTreeContent( {"path": "apps/test/devices/test.py", "type": "blob"}, "test/test", "main", ), AIOGitHubAPIRepositoryTreeContent( {"path": "apps/test/test/test.py", "type": "blob"}, "test/test", "main", ), AIOGitHubAPIRepositoryTreeContent( {"path": ".github/file.file", "type": "blob"}, "test/test", "main", ), ] files = [x.path for x in repository.gather_files_to_download()] assert ".github/file.file" not in files assert "test.py" not in files assert "apps/test/test.py" in files assert "apps/test/devices/test.py" in files assert "apps/test/test/test.py" in files assert "apps/test/core/test.py" in files def test_gather_plugin_multiple_files_in_root(repository_plugin): repository = repository_plugin repository.content.path.remote = "" repository.data.file_name = "test.js" repository.tree = [ AIOGitHubAPIRepositoryTreeContent({"path": "test.js", "type": "blob"}, "test/test", "main"), AIOGitHubAPIRepositoryTreeContent({"path": "dep1.js", "type": "blob"}, "test/test", "main"), AIOGitHubAPIRepositoryTreeContent({"path": "dep2.js", "type": "blob"}, "test/test", "main"), AIOGitHubAPIRepositoryTreeContent({"path": "dep3.js", "type": "blob"}, "test/test", "main"), AIOGitHubAPIRepositoryTreeContent({"path": "info.md", "type": "blob"}, "test/test", "main"), ] files = [x.path for x in repository.gather_files_to_download()] assert "test.js" in files assert "dep1.js" in files assert "dep2.js" in files assert "dep3.js" in files assert "info.md" not in files def test_gather_plugin_different_card_name(repository_plugin): repository = repository_plugin repository.content.path.remote = "" repository.data.file_name = "card.js" repository.tree = [ AIOGitHubAPIRepositoryTreeContent({"path": "card.js", "type": "blob"}, "test/test", "main"), AIOGitHubAPIRepositoryTreeContent({"path": "info.md", "type": "blob"}, "test/test", "main"), ] repository_plugin.update_filenames() files = [x.path for x in repository.gather_files_to_download()] assert "card.js" in files assert "info.md" not in files ================================================ FILE: tests/helpers/download/test_should_try_releases.py ================================================ """Helpers: Download: should_try_releases.""" # pylint: disable=missing-docstring def test_base(repository): repository.ref = "dummy" repository.data.category = "plugin" repository.data.releases = True assert repository.should_try_releases def test_ref_is_default(repository): repository.ref = "main" repository.data.category = "plugin" repository.data.releases = True assert not repository.should_try_releases def test_category_is_wrong(repository): repository.ref = "dummy" repository.data.category = "integration" repository.data.releases = True assert not repository.should_try_releases def test_no_releases(repository): repository.ref = "dummy" repository.data.category = "plugin" repository.data.releases = False assert not repository.should_try_releases def test_zip_release(repository): repository.data.releases = False repository.repository_manifest.zip_release = True repository.repository_manifest.filename = "test.zip" assert repository.should_try_releases # Select a branch repository.ref = "main" assert not repository.should_try_releases ================================================ FILE: tests/helpers/filters/test_filter_content_return_one_of_type.py ================================================ """Helpers: Filters: filter_content_return_one_of_type.""" # pylint: disable=missing-docstring from aiogithubapi.objects.repository.content import AIOGitHubAPIRepositoryTreeContent from custom_components.hacs.utils import filters def test_valid_objects(): tree = [ AIOGitHubAPIRepositoryTreeContent( {"path": "test/file.file", "type": "blob"}, "test/test", "main", ), AIOGitHubAPIRepositoryTreeContent( {"path": "test/newfile.file", "type": "blob"}, "test/test", "main", ), AIOGitHubAPIRepositoryTreeContent( {"path": "test/file.png", "type": "blob"}, "test/test", "main", ), ] files = [ x.filename for x in filters.filter_content_return_one_of_type(tree, "test", "file", "full_path") ] assert "file.file" in files assert "newfile.file" not in files assert "file.png" in files def test_valid_list(): tree = ["test/file.file", "test/newfile.file", "test/file.png"] files = filters.filter_content_return_one_of_type(tree, "test", "file") assert "test/file.file" in files assert "test/newfile.file" not in files assert "test/file.png" in files ================================================ FILE: tests/helpers/filters/test_get_first_directory_in_directory.py ================================================ """Helpers: Filters: get_first_directory_in_directory.""" # pylint: disable=missing-docstring from aiogithubapi.objects.repository.content import AIOGitHubAPIRepositoryTreeContent from custom_components.hacs.utils import filters def test_valid(): tree = [ AIOGitHubAPIRepositoryTreeContent({"path": "test", "type": "tree"}, "test/test", "main"), AIOGitHubAPIRepositoryTreeContent( {"path": "test/path", "type": "tree"}, "test/test", "main", ), AIOGitHubAPIRepositoryTreeContent( {"path": "test/path/sub", "type": "tree"}, "test/test", "main", ), ] assert filters.get_first_directory_in_directory(tree, "test") == "path" def test_not_valid(): tree = [ AIOGitHubAPIRepositoryTreeContent( {"path": ".github/path/file.file", "type": "tree"}, "test/test", "main", ), ] assert filters.get_first_directory_in_directory(tree, "test") is None ================================================ FILE: tests/helpers/functions/test_extract_repository_from_url.py ================================================ """Tests for repository extraction.""" from custom_components.hacs.utils import regex def test_extract_repository_from_url(): """Tests for repository extraction.""" assert regex.extract_repository_from_url("https://github.com/user/repo") == "user/repo" assert regex.extract_repository_from_url("user/repo/") == "user/repo" assert regex.extract_repository_from_url("user/repo") == "user/repo" assert regex.extract_repository_from_url("USER/REPO") == "user/repo" assert regex.extract_repository_from_url("user/repo.git") == "user/repo" assert regex.extract_repository_from_url("user/repo.repo") == "user/repo.repo" assert regex.extract_repository_from_url("git@github.com:user/repo.git") == "user/repo" assert not regex.extract_repository_from_url("https://google.com/user/repo") ================================================ FILE: tests/homeassistantfixtures/__init__.py ================================================ ================================================ FILE: tests/homeassistantfixtures/common.py ================================================ from collections.abc import Mapping, Sequence from pathlib import Path from typing import Any, TypeVar from homeassistant import core as ha from homeassistant.helpers import storage INSTANCES = [] _T = TypeVar("_T", bound=Mapping[str, Any] | Sequence[Any]) def get_test_config_dir(*add_path): """Return a path to a test config dir.""" return Path(Path(__file__).resolve().parent, "testing_config", *add_path) @ha.callback def ensure_auth_manager_loaded(auth_mgr): """Ensure an auth manager is considered loaded.""" store = auth_mgr._store if store._users is None: store._set_defaults() class StoreWithoutWriteLoad(storage.Store[_T]): """Fake store that does not write or load. Used for testing.""" async def async_save(self, *args: Any, **kwargs: Any) -> None: """Save the data. This function is mocked out in tests. """ @ha.callback def async_save_delay(self, *args: Any, **kwargs: Any) -> None: """Save data with an optional delay. This function is mocked out in tests. """ ================================================ FILE: tests/homeassistantfixtures/dev.py ================================================ """Return a Home Assistant object pointing at test config dir. This should be copied from latest Home Assistant version, currently Home Assistant Core 2025.5.0dev0 (2025-04-22). https://github.com/home-assistant/core/blob/dev/tests/common.py """ from __future__ import annotations import asyncio from collections.abc import AsyncGenerator from contextlib import asynccontextmanager, suppress import functools as ft from unittest.mock import AsyncMock, Mock, patch from homeassistant import auth, bootstrap, config_entries, loader from homeassistant.auth import auth_store from homeassistant.const import EVENT_HOMEASSISTANT_CLOSE, EVENT_HOMEASSISTANT_STOP from homeassistant.core import CoreState, HomeAssistant, callback from homeassistant.helpers import ( area_registry as ar, category_registry as cr, device_registry as dr, entity, entity_registry as er, floor_registry as fr, issue_registry as ir, label_registry as lr, restore_state as rs, translation, ) from homeassistant.util.async_ import _SHUTDOWN_RUN_CALLBACK_THREADSAFE import homeassistant.util.dt as dt_util from homeassistant.util.unit_system import METRIC_SYSTEM from .common import ( INSTANCES, StoreWithoutWriteLoad, ensure_auth_manager_loaded, get_test_config_dir, ) @asynccontextmanager async def async_test_home_assistant( event_loop: asyncio.AbstractEventLoop | None = None, load_registries: bool = True, config_dir: str | None = None, initial_state: CoreState = CoreState.running, ) -> AsyncGenerator[HomeAssistant]: """Return a Home Assistant object pointing at test config dir.""" hass = HomeAssistant(config_dir or get_test_config_dir()) store = auth_store.AuthStore(hass) hass.auth = auth.AuthManager(hass, store, {}, {}) ensure_auth_manager_loaded(hass.auth) INSTANCES.append(hass) orig_async_add_job = hass.async_add_job orig_async_add_executor_job = hass.async_add_executor_job orig_async_create_task_internal = hass.async_create_task_internal orig_tz = dt_util.get_default_time_zone() def async_add_job(target, *args, eager_start: bool = False): """Add job.""" check_target = target while isinstance(check_target, ft.partial): check_target = check_target.func if isinstance(check_target, Mock) and not isinstance(target, AsyncMock): fut = asyncio.Future() fut.set_result(target(*args)) return fut return orig_async_add_job(target, *args, eager_start=eager_start) def async_add_executor_job(target, *args): """Add executor job.""" check_target = target while isinstance(check_target, ft.partial): check_target = check_target.func if isinstance(check_target, Mock): fut = asyncio.Future() fut.set_result(target(*args)) return fut return orig_async_add_executor_job(target, *args) def async_create_task_internal(coroutine, name=None, eager_start=True): """Create task.""" if isinstance(coroutine, Mock) and not isinstance(coroutine, AsyncMock): fut = asyncio.Future() fut.set_result(None) return fut return orig_async_create_task_internal(coroutine, name, eager_start) hass.async_add_job = async_add_job hass.async_add_executor_job = async_add_executor_job hass.async_create_task_internal = async_create_task_internal hass.data[loader.DATA_CUSTOM_COMPONENTS] = {} hass.config.location_name = "test home" hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 hass.config.elevation = 0 await hass.config.async_set_time_zone("US/Pacific") hass.config.units = METRIC_SYSTEM hass.config.media_dirs = {"local": get_test_config_dir("media")} hass.config.skip_pip = True hass.config.skip_pip_packages = [] hass.config_entries = config_entries.ConfigEntries( hass, { "_": ( "Not empty or else some bad checks for hass config in discovery.py" " breaks" ) }, ) hass.bus.async_listen_once( EVENT_HOMEASSISTANT_STOP, hass.config_entries._async_shutdown, ) # Load the registries entity.async_setup(hass) loader.async_setup(hass) # setup translation cache instead of calling translation.async_setup(hass) hass.data[translation.TRANSLATION_FLATTEN_CACHE] = translation._TranslationCache( hass ) if load_registries: with ( patch.object(StoreWithoutWriteLoad, "async_load", return_value=None), patch( "homeassistant.helpers.area_registry.AreaRegistryStore", StoreWithoutWriteLoad, ), patch( "homeassistant.helpers.device_registry.DeviceRegistryStore", StoreWithoutWriteLoad, ), patch( "homeassistant.helpers.entity_registry.EntityRegistryStore", StoreWithoutWriteLoad, ), patch( "homeassistant.helpers.storage.Store", # Floor & label registry are different StoreWithoutWriteLoad, ), patch( "homeassistant.helpers.issue_registry.IssueRegistryStore", StoreWithoutWriteLoad, ), patch( "homeassistant.helpers.restore_state.RestoreStateData.async_setup_dump", return_value=None, ), patch( "homeassistant.helpers.restore_state.start.async_at_start", ), ): await ar.async_load(hass) await cr.async_load(hass) await dr.async_load(hass) await er.async_load(hass) await fr.async_load(hass) await ir.async_load(hass) await lr.async_load(hass) await rs.async_load(hass) hass.data[bootstrap.DATA_REGISTRIES_LOADED] = None hass.set_state(initial_state) @callback def clear_instance(event): """Clear global instance.""" # Give aiohttp one loop iteration to close hass.loop.call_soon(INSTANCES.remove, hass) hass.bus.async_listen_once(EVENT_HOMEASSISTANT_CLOSE, clear_instance) try: yield hass finally: # Restore timezone, it is set when creating the hass object dt_util.set_default_time_zone(orig_tz) # Remove loop shutdown indicator to not interfere with additional hass objects with suppress(AttributeError): delattr(hass.loop, _SHUTDOWN_RUN_CALLBACK_THREADSAFE) ================================================ FILE: tests/homeassistantfixtures/min.py ================================================ """Return a Home Assistant object pointing at test config dir. This should be copied from the minimum supported version, currently Home Assistant Core 2025.3.0. https://github.com/home-assistant/core/blob/2025.3.0/tests/common.py """ from __future__ import annotations import asyncio from collections.abc import AsyncGenerator from contextlib import asynccontextmanager, suppress import functools as ft from unittest.mock import AsyncMock, Mock, patch from homeassistant import auth, bootstrap, config_entries, loader from homeassistant.auth import auth_store from homeassistant.const import EVENT_HOMEASSISTANT_CLOSE, EVENT_HOMEASSISTANT_STOP from homeassistant.core import CoreState, HomeAssistant, callback from homeassistant.helpers import ( area_registry as ar, category_registry as cr, device_registry as dr, entity, entity_registry as er, floor_registry as fr, issue_registry as ir, label_registry as lr, restore_state as rs, translation, ) from homeassistant.util.async_ import _SHUTDOWN_RUN_CALLBACK_THREADSAFE import homeassistant.util.dt as dt_util from homeassistant.util.unit_system import METRIC_SYSTEM from .common import ( INSTANCES, StoreWithoutWriteLoad, ensure_auth_manager_loaded, get_test_config_dir, ) # pylint: disable=protected-access @asynccontextmanager async def async_test_home_assistant( event_loop: asyncio.AbstractEventLoop | None = None, load_registries: bool = True, config_dir: str | None = None, initial_state: CoreState = CoreState.running, ) -> AsyncGenerator[HomeAssistant]: """Return a Home Assistant object pointing at test config dir.""" hass = HomeAssistant(config_dir or get_test_config_dir()) store = auth_store.AuthStore(hass) hass.auth = auth.AuthManager(hass, store, {}, {}) ensure_auth_manager_loaded(hass.auth) INSTANCES.append(hass) orig_async_add_job = hass.async_add_job orig_async_add_executor_job = hass.async_add_executor_job orig_async_create_task_internal = hass.async_create_task_internal orig_tz = dt_util.get_default_time_zone() def async_add_job(target, *args, eager_start: bool = False): """Add job.""" check_target = target while isinstance(check_target, ft.partial): check_target = check_target.func if isinstance(check_target, Mock) and not isinstance(target, AsyncMock): fut = asyncio.Future() fut.set_result(target(*args)) return fut return orig_async_add_job(target, *args, eager_start=eager_start) def async_add_executor_job(target, *args): """Add executor job.""" check_target = target while isinstance(check_target, ft.partial): check_target = check_target.func if isinstance(check_target, Mock): fut = asyncio.Future() fut.set_result(target(*args)) return fut return orig_async_add_executor_job(target, *args) def async_create_task_internal(coroutine, name=None, eager_start=True): """Create task.""" if isinstance(coroutine, Mock) and not isinstance(coroutine, AsyncMock): fut = asyncio.Future() fut.set_result(None) return fut return orig_async_create_task_internal(coroutine, name, eager_start) hass.async_add_job = async_add_job hass.async_add_executor_job = async_add_executor_job hass.async_create_task_internal = async_create_task_internal hass.data[loader.DATA_CUSTOM_COMPONENTS] = {} hass.config.location_name = "test home" hass.config.latitude = 32.87336 hass.config.longitude = -117.22743 hass.config.elevation = 0 await hass.config.async_set_time_zone("US/Pacific") hass.config.units = METRIC_SYSTEM hass.config.media_dirs = {"local": get_test_config_dir("media")} hass.config.skip_pip = True hass.config.skip_pip_packages = [] hass.config_entries = config_entries.ConfigEntries( hass, { "_": ( "Not empty or else some bad checks for hass config in discovery.py" " breaks" ) }, ) hass.bus.async_listen_once( EVENT_HOMEASSISTANT_STOP, hass.config_entries._async_shutdown, ) # Load the registries entity.async_setup(hass) loader.async_setup(hass) # setup translation cache instead of calling translation.async_setup(hass) hass.data[translation.TRANSLATION_FLATTEN_CACHE] = translation._TranslationCache( hass ) if load_registries: with ( patch.object(StoreWithoutWriteLoad, "async_load", return_value=None), patch( "homeassistant.helpers.area_registry.AreaRegistryStore", StoreWithoutWriteLoad, ), patch( "homeassistant.helpers.device_registry.DeviceRegistryStore", StoreWithoutWriteLoad, ), patch( "homeassistant.helpers.entity_registry.EntityRegistryStore", StoreWithoutWriteLoad, ), patch( "homeassistant.helpers.storage.Store", # Floor & label registry are different StoreWithoutWriteLoad, ), patch( "homeassistant.helpers.issue_registry.IssueRegistryStore", StoreWithoutWriteLoad, ), patch( "homeassistant.helpers.restore_state.RestoreStateData.async_setup_dump", return_value=None, ), patch( "homeassistant.helpers.restore_state.start.async_at_start", ), ): await ar.async_load(hass) await cr.async_load(hass) await dr.async_load(hass) await er.async_load(hass) await fr.async_load(hass) await ir.async_load(hass) await lr.async_load(hass) await rs.async_load(hass) hass.data[bootstrap.DATA_REGISTRIES_LOADED] = None hass.set_state(initial_state) @callback def clear_instance(event): """Clear global instance.""" # Give aiohttp one loop iteration to close hass.loop.call_soon(INSTANCES.remove, hass) hass.bus.async_listen_once(EVENT_HOMEASSISTANT_CLOSE, clear_instance) try: yield hass finally: # Restore timezone, it is set when creating the hass object dt_util.set_default_time_zone(orig_tz) # Remove loop shutdown indicator to not interfere with additional hass objects with suppress(AttributeError): delattr(hass.loop, _SHUTDOWN_RUN_CALLBACK_THREADSAFE) ================================================ FILE: tests/integration/test_integration_setup.py ================================================ import sys from unittest.mock import MagicMock, patch from homeassistant.components.websocket_api import DOMAIN as WEBSOCKET_DOMAIN from homeassistant.core import HomeAssistant import pytest from custom_components.hacs.base import HacsBase from tests.common import create_config_entry, get_hacs from tests.conftest import SnapshotFixture async def test_integration_setup( hass: HomeAssistant, snapshots: SnapshotFixture, ): config_entry = create_config_entry() hass.data.pop("custom_components", None) config_entry.add_to_hass(hass) assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() hacs: HacsBase = get_hacs(hass) assert not hacs.system.disabled assert hacs.stage == "running" await snapshots.assert_hacs_data( hacs, "test_integration_setup.json", { "websocket_commands": [ command for command in hass.data[WEBSOCKET_DOMAIN] if command.startswith("hacs/") ], }, ) async def test_integration_setup_with_custom_updater( hass: HomeAssistant, snapshots: SnapshotFixture, caplog: pytest.LogCaptureFixture, ): config_entry = create_config_entry() hass.data.pop("custom_components", None) config_entry.add_to_hass(hass) with patch.dict( sys.modules, { **sys.modules, # Pretend custom_updater is loaded "custom_components.custom_updater": MagicMock(), }, ): assert not await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() hacs: HacsBase = get_hacs(hass) assert hacs.system.disabled_reason == "constrains" assert ( "HACS cannot be used with custom_updater. To use HACS you need to remove custom_updater from `custom_components`" in caplog.text ) await snapshots.assert_hacs_data( hacs, "test_integration_setup_with_custom_updater.json", {}, ) ================================================ FILE: tests/patch_time.py ================================================ """Patch time related functions. Copied from Home Assistant Core. """ from __future__ import annotations import datetime import time from homeassistant import runner, util from homeassistant.util import dt as dt_util def _utcnow() -> datetime.datetime: """Make utcnow patchable by freezegun.""" return datetime.datetime.now(tz=datetime.UTC) def _monotonic() -> float: """Make monotonic patchable by freezegun.""" return time.monotonic() dt_util.utcnow = _utcnow # type: ignore[assignment] util.utcnow = _utcnow # type: ignore[assignment] runner.monotonic = _monotonic # type: ignore[assignment] ================================================ FILE: tests/repositories/helpers/__init__.py ================================================ ================================================ FILE: tests/repositories/helpers/test_properties.py ================================================ """HACS Repository Helper properties.""" # pylint: disable=missing-docstring from awesomeversion import AwesomeVersion from custom_components.hacs.repositories.base import HacsRepository def test_repository_helpers_properties_can_be_installed(hacs): repository = HacsRepository(hacs) assert repository.can_download def test_repository_helpers_properties_pending_update(hacs): repository = HacsRepository(hacs) repository.hacs.core.ha_version = AwesomeVersion("0.109.0") repository.repository_manifest.homeassistant = "0.110.0" repository.data.releases = True assert not repository.pending_update repository = HacsRepository(hacs) repository.data.installed = True repository.data.default_branch = "main" repository.data.selected_tag = "main" assert not repository.pending_update repository.data.installed_commit = "1" repository.data.last_commit = "2" assert repository.pending_update ================================================ FILE: tests/repositories/test_can_install.py ================================================ """Configuration Test Suite: can install.""" # pylint: disable=missing-docstring from awesomeversion import AwesomeVersion from custom_components.hacs.repositories.base import HacsManifest, HacsRepository def test_hacs_can_install(hacs): repository = HacsRepository(hacs) repository.repository_manifest = HacsManifest.from_dict({"test": "test"}) repository.data.releases = True hacs.core.ha_version = AwesomeVersion("1.0.0") repository.repository_manifest.homeassistant = "1.0.0b1" assert repository.can_download hacs.core.ha_version = AwesomeVersion("1.0.0b1") repository.repository_manifest.homeassistant = "1.0.0" assert not repository.can_download hacs.core.ha_version = AwesomeVersion("1.0.0b1") repository.repository_manifest.homeassistant = "1.0.0b2" assert not repository.can_download hacs.core.ha_version = AwesomeVersion("1.0.0") repository.repository_manifest.homeassistant = "1.0.0" assert repository.can_download ================================================ FILE: tests/repositories/test_display_status.py ================================================ """Configuration Test Suite: can install.""" # pylint: disable=missing-docstring from awesomeversion import AwesomeVersion from custom_components.hacs.base import HacsBase def test_display_status(hacs: HacsBase): repository = hacs.repositories.get_by_full_name( "hacs-test-org/integration-basic") assert repository.display_status == "default" repository.data.new = True assert repository.display_status == "new" repository.data.new = False repository.pending_restart = True assert repository.display_status == "pending-restart" repository.pending_restart = False repository.data.installed = True repository.data.installed_version = "1" repository.data.last_version = "2" repository.data.releases = True assert repository.display_status == "pending-upgrade" hacs.core.ha_version = AwesomeVersion("0.0.0") repository.repository_manifest.homeassistant = "1.0.0" assert repository.display_status == "pending-upgrade" repository.data.last_version = "1" assert repository.display_status == "installed" ================================================ FILE: tests/repositories/test_download_repository.py ================================================ from collections.abc import Generator from homeassistant.core import HomeAssistant import pytest from tests.common import ( CategoryTestData, WSClient, category_test_data_parametrized, get_hacs, ) from tests.conftest import SnapshotFixture @pytest.mark.parametrize("category_test_data", category_test_data_parametrized()) async def test_download_repository( hass: HomeAssistant, setup_integration: Generator, ws_client: WSClient, category_test_data: CategoryTestData, snapshots: SnapshotFixture, ): hacs = get_hacs(hass) repo = hacs.repositories.get_by_full_name(category_test_data["repository"]) assert repo is not None assert repo.data.installed is False assert len(hacs.repositories.list_downloaded) == 1 # workaround for local path bug in tests repo.content.path.local = repo.localpath response = await ws_client.send_and_receive_json( "hacs/repository/download", {"repository": repo.data.id}, ) assert response["success"] == True assert len(hacs.repositories.list_downloaded) == 2 assert repo.data.installed is True await snapshots.assert_hacs_data( hacs, f"{category_test_data['repository']}/test_download_repository.json", ) ================================================ FILE: tests/repositories/test_get_documentation.py ================================================ """Tests for the get_documentation method on the HacsRepository class.""" from __future__ import annotations import json from typing import Any import pytest from slugify import slugify from custom_components.hacs.base import HacsBase from custom_components.hacs.repositories.base import HacsRepository from tests.common import ResponseMocker, client_session_proxy from tests.conftest import SnapshotFixture @pytest.mark.parametrize( "data", [ {"installed": True, "installed_version": "1.0.0"}, {"installed": True, "installed_version": "1.0.0","last_version": "2.0.0"}, {"installed": False, "last_version": "2.0.0"}, {"installed": False, "last_version": "99.99.99"}, ], ) async def test_repository_get_documentation( hacs: HacsBase, data: dict[str, Any], response_mocker: ResponseMocker, snapshots: SnapshotFixture, ): repository = HacsRepository(hacs=hacs) repository.data.full_name = "hacs-test-org/integration-basic" for key, value in data.items(): setattr(repository.data, key, value) hacs.session = await client_session_proxy(hacs.hass) docs = await repository.get_documentation(filename="README.md", version=None) snapshots.assert_match( docs or "None", f"{repository.data.full_name}/get_documentation/{slugify(json.dumps(data), separator="_")}.md", ) ================================================ FILE: tests/repositories/test_get_hacs_json.py ================================================ from unittest.mock import patch import pytest from custom_components.hacs.base import HacsBase from custom_components.hacs.repositories.base import HacsRepository from tests.common import ResponseMocker, client_session_proxy @pytest.mark.parametrize("version,name", [("1.0.0", "Integration basic 1.0.0"), ("99.99.99", None)]) async def test_validate_repository( hacs: HacsBase, version: str, name: str | None, response_mocker: ResponseMocker, ): repository = HacsRepository(hacs=hacs) repository.data.full_name = "hacs-test-org/integration-basic" hacs.session = await client_session_proxy(hacs.hass) manifest = await repository.get_hacs_json(version=version) if name: assert manifest.name == name else: assert manifest is None async def test_get_hacs_json_with_exception(hacs: HacsBase): """Test that get_hacs_json returns None on exception due to decorator.""" repository = HacsRepository(hacs=hacs) repository.data.full_name = "hacs-test-org/integration-basic" # Mock get_hacs_json_raw to raise an exception with patch.object(repository, "get_hacs_json_raw", side_effect=Exception("Test exception")): result = await repository.get_hacs_json(version="1.0.0") assert result is None # Mock HacsManifest.from_dict to raise an exception with patch("custom_components.hacs.repositories.base.HacsManifest.from_dict", side_effect=ValueError("Invalid manifest")): result = await repository.get_hacs_json(version="1.0.0") assert result is None ================================================ FILE: tests/repositories/test_get_hacs_json_raw.py ================================================ from unittest.mock import patch import pytest from custom_components.hacs.base import HacsBase from custom_components.hacs.repositories.base import HacsRepository from tests.common import ResponseMocker, client_session_proxy @pytest.mark.parametrize("version,expected", [ ("1.0.0", {"name": "Integration basic 1.0.0"}), ("99.99.99", None), ]) async def test_get_hacs_json_raw( hacs: HacsBase, version: str, expected: dict | None, response_mocker: ResponseMocker, ): repository = HacsRepository(hacs=hacs) repository.data.full_name = "hacs-test-org/integration-basic" hacs.session = await client_session_proxy(hacs.hass) manifest = await repository.get_hacs_json_raw(version=version) if expected is not None: assert manifest["name"] == expected["name"] else: assert manifest is None async def test_get_hacs_json_raw_with_exception(hacs: HacsBase): """Test that get_hacs_json_raw returns None on exception due to decorator.""" repository = HacsRepository(hacs=hacs) repository.data.full_name = "hacs-test-org/integration-basic" # Mock the async_download_file to raise an exception with patch.object(hacs, "async_download_file", side_effect=Exception("Test exception")): result = await repository.get_hacs_json_raw(version="1.0.0") assert result is None # Mock the json_loads to raise an exception with patch("custom_components.hacs.repositories.base.json_loads", side_effect=ValueError("Invalid JSON")): result = await repository.get_hacs_json_raw(version="1.0.0") assert result is None ================================================ FILE: tests/repositories/test_get_reposiotry_releases.py ================================================ from collections.abc import Generator from homeassistant.core import HomeAssistant import pytest from tests.common import ( CategoryTestData, MockedResponse, ResponseMocker, WSClient, category_test_data_parametrized, get_hacs, safe_json_dumps, ) from tests.conftest import SnapshotFixture @pytest.mark.parametrize("category_test_data", category_test_data_parametrized()) async def test_get_reposiotry_releases( hass: HomeAssistant, setup_integration: Generator, response_mocker: ResponseMocker, ws_client: WSClient, category_test_data: CategoryTestData, snapshots: SnapshotFixture, ): hacs = get_hacs(hass) repo = hacs.repositories.get_by_full_name(category_test_data["repository"]) assert repo is not None response_mocker.add( f"https://api.github.com/repos/{ category_test_data['repository']}/releases", response=MockedResponse( content=[ { "name": category_test_data["version_update"], "tag_name": category_test_data["version_update"], "published_at": "2019-02-26T15:02:39Z", "prerelease": False, } ] ), ) response = await ws_client.send_and_receive_json( "hacs/repository/releases", {"repository_id": repo.data.id}, ) assert response["success"] == True snapshots.assert_match( safe_json_dumps(response), f"{category_test_data['repository'] }/test_get_reposiotry_releases.json", ) ================================================ FILE: tests/repositories/test_hacs_manifest.py ================================================ """HACS Manifest Test Suite.""" # pylint: disable=missing-docstring import pytest from custom_components.hacs.exceptions import HacsException from custom_components.hacs.repositories.base import HacsManifest def test_manifest_structure(): manifest = HacsManifest.from_dict({"name": "TEST"}) assert isinstance(manifest.manifest, dict) assert isinstance(manifest.name, str) assert manifest.name == "TEST" assert isinstance(manifest.content_in_root, bool) assert not manifest.content_in_root assert isinstance(manifest.zip_release, bool) assert not manifest.zip_release assert isinstance(manifest.filename, (str, type(None))) assert manifest.filename is None assert isinstance(manifest.country, list) assert not manifest.country assert isinstance(manifest.homeassistant, (str, type(None))) assert manifest.homeassistant is None assert isinstance(manifest.persistent_directory, (str, type(None))) assert manifest.persistent_directory is None assert isinstance(manifest.hacs, (str, type(None))) assert not manifest.hacs assert isinstance(manifest.hide_default_branch, bool) assert not manifest.hide_default_branch def test_edge_pass_none(): with pytest.raises(HacsException): assert HacsManifest.from_dict(None) ================================================ FILE: tests/repositories/test_plugin_repository.py ================================================ """Tests for specific plugin repository implementations.""" from collections.abc import Generator from homeassistant.core import HomeAssistant import pytest from custom_components.hacs.repositories.plugin import HacsPluginRepository from tests.common import get_hacs @pytest.fixture async def downloaded_plugin_repository( hass: HomeAssistant, setup_integration: Generator, ) -> HacsPluginRepository: """Return a HacsPluginRepository instance.""" hacs = get_hacs(hass) repository = hacs.repositories.get_by_full_name( "hacs-test-org/plugin-basic") await repository.async_install(version="1.0.0") return repository @pytest.mark.parametrize( "repository_name, namespace", [ ("hacs-test-org/plugin-basic", "/hacsfiles/plugin-basic"), ("hacs-test-org/plugin-advanced", "/hacsfiles/plugin-advanced"), ("hacs-test-org/awesome-plugin", "/hacsfiles/awesome-plugin"), ], ) async def test_dashboard_namespace( downloaded_plugin_repository: HacsPluginRepository, repository_name: str, namespace: str, ) -> None: """Test the dashboard resource namespace.""" downloaded_plugin_repository.data.full_name = repository_name assert downloaded_plugin_repository.generate_dashboard_resource_namespace() == namespace @pytest.mark.parametrize( "downloaded, selected, available, expected", [ (None, None, None, ""), ("1.0.0", None, None, "100"), (None, "2.0.1", None, "201"), (None, None, "3.4.2", "342"), ("1.7-dev09-r2", None, None, "17092"), ], ) async def test_dashboard_hacstag( downloaded_plugin_repository: HacsPluginRepository, downloaded: str | None, selected: str | None, available: str | None, expected: str, ) -> None: """Test the dashboard resource hacstag.""" downloaded_plugin_repository.data.installed_commit = None downloaded_plugin_repository.data.last_commit = None downloaded_plugin_repository.data.installed_version = downloaded downloaded_plugin_repository.data.last_version = available downloaded_plugin_repository.data.selected_tag = selected assert ( downloaded_plugin_repository.generate_dashboard_resource_hacstag() == f"{downloaded_plugin_repository.data.id}{expected}" ) async def test_dashboard_url(downloaded_plugin_repository: HacsPluginRepository) -> None: """Test the dashboard resource url.""" assert ( downloaded_plugin_repository.generate_dashboard_resource_url() == "/hacsfiles/plugin-basic/plugin-basic.js?hacstag=1296267100" ) async def test_get_resource_handler( hass: HomeAssistant, downloaded_plugin_repository: HacsPluginRepository, caplog: pytest.LogCaptureFixture, ) -> None: """Test the resource handler.""" resources = downloaded_plugin_repository._get_resource_handler() assert resources is not None async def test_get_resource_handler_wrong_version( hass: HomeAssistant, downloaded_plugin_repository: HacsPluginRepository, caplog: pytest.LogCaptureFixture, ) -> None: """Test the resource handler with wrong storage version.""" try: hass.data["lovelace"].resources.store.version = 2 except AttributeError: # Changed to 2025.2.0 # Changed in https://github.com/home-assistant/core/pull/136313 hass.data["lovelace"]["resources"].store.version = 2 resources = downloaded_plugin_repository._get_resource_handler() assert resources is None assert "Can not use the dashboard resources" in caplog.text async def test_get_resource_handler_wrong_key( hass: HomeAssistant, downloaded_plugin_repository: HacsPluginRepository, caplog: pytest.LogCaptureFixture, ) -> None: """Test the resource handler with wrong storage key.""" try: hass.data["lovelace"].resources.store.key = "wrong_key" except AttributeError: # Changed to 2025.2.0 # Changed in https://github.com/home-assistant/core/pull/136313 hass.data["lovelace"]["resources"].store.key = "wrong_key" resources = downloaded_plugin_repository._get_resource_handler() assert resources is None assert "Can not use the dashboard resources" in caplog.text async def test_get_resource_handler_none_store( hass: HomeAssistant, downloaded_plugin_repository: HacsPluginRepository, caplog: pytest.LogCaptureFixture, ) -> None: """Test the resource handler with store being none.""" try: hass.data["lovelace"].resources.store = None except AttributeError: # Changed to 2025.2.0 # Changed in https://github.com/home-assistant/core/pull/136313 hass.data["lovelace"]["resources"].store = None resources = downloaded_plugin_repository._get_resource_handler() assert resources is None assert "YAML mode detected, can not update resources" in caplog.text async def test_get_resource_handler_no_store( hass: HomeAssistant, downloaded_plugin_repository: HacsPluginRepository, caplog: pytest.LogCaptureFixture, ) -> None: """Test the resource handler with no store.""" try: hass.data["lovelace"].resources.store = None except AttributeError: # Changed to 2025.2.0 # Changed in https://github.com/home-assistant/core/pull/136313 del hass.data["lovelace"]["resources"].store resources = downloaded_plugin_repository._get_resource_handler() assert resources is None assert "YAML mode detected, can not update resources" in caplog.text async def test_get_resource_handler_no_lovelace_resources( hass: HomeAssistant, downloaded_plugin_repository: HacsPluginRepository, caplog: pytest.LogCaptureFixture, ) -> None: """Test the resource handler with no lovelace resources.""" try: hass.data["lovelace"].resources = None except AttributeError: # Changed to 2025.2.0 # Changed in https://github.com/home-assistant/core/pull/136313 del hass.data["lovelace"]["resources"] resources = downloaded_plugin_repository._get_resource_handler() assert resources is None assert "Can not access the dashboard resources" in caplog.text async def test_get_resource_handler_no_lovelace_data( hass: HomeAssistant, downloaded_plugin_repository: HacsPluginRepository, caplog: pytest.LogCaptureFixture, ) -> None: """Test the resource handler with no lovelace data.""" del hass.data["lovelace"] resources = downloaded_plugin_repository._get_resource_handler() assert resources is None assert "Can not access the lovelace integration data" in caplog.text async def test_get_resource_handler_no_hass_data( hass: HomeAssistant, downloaded_plugin_repository: HacsPluginRepository, caplog: pytest.LogCaptureFixture, ) -> None: """Test the resource handler with no hass data.""" hass_data = hass.data hass.data = None resources = downloaded_plugin_repository._get_resource_handler() assert resources is None assert "Can not access the hass data" in caplog.text hass.data = hass_data async def test_remove_dashboard_resource( hass: HomeAssistant, downloaded_plugin_repository: HacsPluginRepository, caplog: pytest.LogCaptureFixture, ) -> None: """Test adding a dashboard resource.""" resource_handler = downloaded_plugin_repository._get_resource_handler() await resource_handler.async_load() current_urls = [resource["url"] for resource in resource_handler.async_items()] assert len(current_urls) == 1 assert downloaded_plugin_repository.generate_dashboard_resource_url() in current_urls await downloaded_plugin_repository.remove_dashboard_resources() assert ( "Removing dashboard resource /hacsfiles/plugin-basic/plugin-basic.js?hacstag=1296267100" in caplog.text ) current_urls = [resource["url"] for resource in resource_handler.async_items()] assert len(current_urls) == 0 async def test_add_dashboard_resource( hass: HomeAssistant, downloaded_plugin_repository: HacsPluginRepository, caplog: pytest.LogCaptureFixture, ) -> None: """Test adding a dashboard resource.""" resource_handler = downloaded_plugin_repository._get_resource_handler() resource_handler.data.clear() current_urls = [resource["url"] for resource in resource_handler.async_items()] assert len(current_urls) == 0 await downloaded_plugin_repository.update_dashboard_resources() assert ( "dding dashboard resource /hacsfiles/plugin-basic/plugin-basic.js?hacstag=1296267100" in caplog.text ) async def test_update_dashboard_resource( hass: HomeAssistant, downloaded_plugin_repository: HacsPluginRepository, caplog: pytest.LogCaptureFixture, ) -> None: """Test adding a dashboard resource.""" resource_handler = downloaded_plugin_repository._get_resource_handler() await resource_handler.async_load() current_urls = [resource["url"] for resource in resource_handler.async_items()] assert len(current_urls) == 1 prev_url = downloaded_plugin_repository.generate_dashboard_resource_url() assert prev_url in current_urls assert current_urls[0] == prev_url downloaded_plugin_repository.data.installed_version = "1.1.0" await downloaded_plugin_repository.update_dashboard_resources() assert ( "Updating existing dashboard resource from " "/hacsfiles/plugin-basic/plugin-basic.js?hacstag=1296267100 to " "/hacsfiles/plugin-basic/plugin-basic.js?hacstag=1296267110" in caplog.text ) after_url = downloaded_plugin_repository.generate_dashboard_resource_url() assert after_url != prev_url current_urls = [resource["url"] for resource in resource_handler.async_items()] assert len(current_urls) == 1 assert current_urls[0] == after_url async def test_add_dashboard_resource_with_invalid_file_name( hass: HomeAssistant, downloaded_plugin_repository: HacsPluginRepository, caplog: pytest.LogCaptureFixture, ) -> None: """Test adding a dashboard resource.""" resource_handler = downloaded_plugin_repository._get_resource_handler() resource_handler.data.clear() current_urls = [resource["url"] for resource in resource_handler.async_items()] assert len(current_urls) == 0 downloaded_plugin_repository.data.file_name = "dist/plugin-basic.js" await downloaded_plugin_repository.update_dashboard_resources() assert " have defined an invalid file name dist/plugin-basic.js" in caplog.text assert ( "Adding dashboard resource /hacsfiles/plugin-basic/plugin-basic.js?hacstag=1296267100" in caplog.text ) ================================================ FILE: tests/repositories/test_register_repository.py ================================================ from collections.abc import Generator from homeassistant.core import HomeAssistant from homeassistant.helpers.dispatcher import async_dispatcher_connect import pytest from custom_components.hacs.enums import HacsCategory, HacsDispatchEvent from tests.common import WSClient, get_hacs, recursive_remove_key, safe_json_dumps from tests.conftest import SnapshotFixture @pytest.mark.parametrize( "repository_full_name,category", ( ("hacs-test-org/integration-basic-custom", HacsCategory.INTEGRATION), ("hacs-test-org/plugin-custom-dist", HacsCategory.PLUGIN), ), ) async def test_register_repository( hass: HomeAssistant, setup_integration: Generator, repository_full_name: str, category: HacsCategory, snapshots: SnapshotFixture, ws_client: WSClient, ): hacs = get_hacs(hass) assert hacs.repositories.get_by_full_name(repository_full_name) is None response = await ws_client.send_and_receive_json( "hacs/repositories/add", {"repository": repository_full_name, "category": category.value}, ) assert response["success"] == True repo = hacs.repositories.get_by_full_name(repository_full_name) assert repo is not None response = await ws_client.send_and_receive_json( "hacs/repository/info", {"repository_id": repo.data.id}, ) assert response["success"] == True snapshots.assert_match( safe_json_dumps(recursive_remove_key(response["result"], ("last_updated", "local_path"))), f"{repository_full_name}/test_register_repository.json", ) @pytest.mark.parametrize( "repository_full_name,result", ( ( "home-assistant/core", "You can not add homeassistant/core, to use core integrations check the Home Assistant documentation for how to add them.", ), ( "home-assistant/addons", "The repository does not seem to be a integration, but an add-on repository. HACS does not manage add-ons.", ), ( "hassio-addons/example", "The repository does not seem to be a integration, but an add-on repository. HACS does not manage add-ons.", ), ( "hacs-test-org/addon-basic", "The repository does not seem to be a integration, but an add-on repository. HACS does not manage add-ons.", ), ( "hacs-test-org/integration-invalid", " Repository structure for main is not compliant", ), ), ) async def test_register_repository_failures( hass: HomeAssistant, setup_integration: Generator, repository_full_name: str, result: str, ws_client: WSClient, ): messages = [] async_dispatcher_connect( hass, HacsDispatchEvent.ERROR, lambda message: messages.append(message), ) hacs = get_hacs(hass) assert hacs.repositories.get_by_full_name(repository_full_name) is None response = await ws_client.send_and_receive_json( "hacs/repositories/add", {"repository": repository_full_name, "category": HacsCategory.INTEGRATION}, ) await hass.async_block_till_done() assert response["success"] == True repo = hacs.repositories.get_by_full_name(repository_full_name) assert repo is None assert response["result"] == {} assert len(messages) == 1 assert messages[0]["action"] == "add_repository" assert messages[0]["message"] == result ================================================ FILE: tests/repositories/test_remove_repository.py ================================================ from collections.abc import Generator import os from pathlib import Path from homeassistant.core import HomeAssistant import pytest from custom_components.hacs.repositories.plugin import HacsPluginRepository from tests.common import ( CategoryTestData, WSClient, category_test_data_parametrized, get_hacs, ) from tests.conftest import SnapshotFixture @pytest.mark.parametrize("category_test_data", category_test_data_parametrized()) async def test_remove_repository( hass: HomeAssistant, setup_integration: Generator, ws_client: WSClient, category_test_data: CategoryTestData, snapshots: SnapshotFixture, ): hacs = get_hacs(hass) repo = hacs.repositories.get_by_full_name(category_test_data["repository"]) assert repo is not None assert repo.data.installed is False repo.data.installed = True assert len(hacs.repositories.list_downloaded) == 2 match repo.data.category: case "theme" | "python_script": repo.data.file_name = category_test_data["files"][0] case "plugin": repo.data.file_name = category_test_data["files"][0] assert isinstance(repo, HacsPluginRepository) resources = repo._get_resource_handler() assert resources.async_items() == [] await repo.update_dashboard_resources() repo.update_filenames() first_resource = resources.async_items()[0] assert first_resource["url"] == repo.generate_dashboard_resource_url() # workaround for local path bug in tests repo.content.path.local = repo.localpath for file in category_test_data["files"]: Path(repo.localpath, Path(file).parent).mkdir(parents=True, exist_ok=True) Path(repo.localpath, file).touch() await snapshots.assert_hacs_data( hacs, f"{category_test_data['repository']}/test_remove_repository_pre.json", ) response = await ws_client.send_and_receive_json( "hacs/repository/remove", {"repository": repo.data.id}, ) assert response["success"] == True assert len(hacs.repositories.list_downloaded) == 1 assert repo.data.installed is False if repo.content.single: for file in category_test_data["files"]: assert not os.path.exists(Path(repo.content.path.local, file)) else: assert not os.path.exists(repo.localpath) await snapshots.assert_hacs_data( hacs, f"{category_test_data['repository']}/test_remove_repository_post.json", ) ================================================ FILE: tests/repositories/test_removed_repository.py ================================================ """HACS Repository Data Test Suite.""" import pytest from custom_components.hacs.base import RemovedRepository BASE_DATA = { "repository": "remmoved/repository", "reason": None, "link": None, "removal_type": None, "acknowledged": False, } @pytest.mark.parametrize( "data", ( {"removal_type": "remove"}, {"reason": "Repository was removed from HACS"}, {"link": "https://example.com/remmoved/repository"}, {"acknowledged": True}, {"acknowledged": False}, ), ) def test_removed_repository(data: dict[str, any]): """Test RemovedRepository.""" removed = RemovedRepository(repository="remmoved/repository") assert removed.to_json() == BASE_DATA removed.update_data(data) assert removed.to_json() == {**BASE_DATA, **data} ================================================ FILE: tests/repositories/test_update_repository.py ================================================ from collections.abc import Generator import json import re from unittest.mock import patch from homeassistant.core import HomeAssistant, HomeAssistantError from homeassistant.helpers.entity_registry import async_get as async_get_entity_registry import pytest from custom_components.hacs.const import DOMAIN from tests.common import ( CategoryTestData, MockedResponse, ResponseMocker, WSClient, category_test_data_parametrized, get_hacs, ) from tests.conftest import SnapshotFixture @pytest.mark.parametrize("category_test_data", category_test_data_parametrized()) async def test_update_repository_entity( hass: HomeAssistant, setup_integration: Generator, category_test_data: CategoryTestData, snapshots: SnapshotFixture, ): hacs = get_hacs(hass) repo = hacs.repositories.get_by_full_name(category_test_data["repository"]) assert repo is not None repo.data.installed = True repo.data.installed_version = category_test_data["version_base"] await hass.config_entries.async_reload(hacs.configuration.config_entry.entry_id) await hass.async_block_till_done() # Get a new HACS instance after reload hacs = get_hacs(hass) er = async_get_entity_registry(hacs.hass) entity_id = er.async_get_entity_id("update", DOMAIN, repo.data.id) await hass.services.async_call( "update", "install", service_data={"entity_id": entity_id, "version": category_test_data["version_update"]}, blocking=True, ) repo = hacs.repositories.get_by_full_name(category_test_data["repository"]) assert repo.data.installed_version == category_test_data["version_update"] await snapshots.assert_hacs_data( hacs, f"{category_test_data['repository'] }/test_update_repository_entity.json", ) @pytest.mark.parametrize("category_test_data", category_test_data_parametrized()) async def test_update_repository_websocket( hass: HomeAssistant, setup_integration: Generator, ws_client: WSClient, category_test_data: CategoryTestData, snapshots: SnapshotFixture, ): hacs = get_hacs(hass) repo = hacs.repositories.get_by_full_name(category_test_data["repository"]) assert repo is not None repo.data.installed = True repo.data.installed_version = category_test_data["version_base"] response = await ws_client.send_and_receive_json( "hacs/repository/download", {"repository": repo.data.id, "version": category_test_data["version_update"]}, ) assert response["success"] == True assert repo.data.installed_version == category_test_data["version_update"] await snapshots.assert_hacs_data( hacs, f"{category_test_data['repository'] }/test_update_repository_websocket.json", ) async def test_update_repository_entity_no_manifest( hass: HomeAssistant, setup_integration: Generator, snapshots: SnapshotFixture, response_mocker: ResponseMocker, ): hacs = get_hacs(hass) repo = hacs.repositories.get_by_full_name( "hacs-test-org/integration-basic") assert repo is not None repo.data.installed = True repo.data.installed_version = "1.0.0" await hass.config_entries.async_reload(hacs.configuration.config_entry.entry_id) await hass.async_block_till_done() response_mocker.add( "https://raw.githubusercontent.com/hacs-test-org/integration-basic/3.0.0/hacs.json", MockedResponse(status=404), ) # Get a new HACS instance after reload hacs = get_hacs(hass) er = async_get_entity_registry(hacs.hass) entity_id = er.async_get_entity_id("update", DOMAIN, repo.data.id) with pytest.raises( HomeAssistantError, match=re.escape( "The version 3.0.0 for this integration can not be used with HACS."), ): await hass.services.async_call( "update", "install", service_data={"entity_id": entity_id, "version": "3.0.0"}, blocking=True, ) async def test_update_repository_entity_old_core_version( hass: HomeAssistant, setup_integration: Generator, snapshots: SnapshotFixture, response_mocker: ResponseMocker, ): hacs = get_hacs(hass) repo = hacs.repositories.get_by_full_name( "hacs-test-org/integration-basic") assert repo is not None repo.data.installed = True repo.data.installed_version = "1.0.0" await hass.config_entries.async_reload(hacs.configuration.config_entry.entry_id) await hass.async_block_till_done() response_mocker.add( "https://raw.githubusercontent.com/hacs-test-org/integration-basic/3.0.0/hacs.json", MockedResponse(content=json.dumps({"homeassistant": "9999.99.99"})), ) # Get a new HACS instance after reload hacs = get_hacs(hass) er = async_get_entity_registry(hacs.hass) entity_id = er.async_get_entity_id("update", DOMAIN, repo.data.id) with pytest.raises( HomeAssistantError, match=re.escape( "This version requires Home Assistant 9999.99.99 or newer."), ): await hass.services.async_call( "update", "install", service_data={"entity_id": entity_id, "version": "3.0.0"}, blocking=True, ) async def test_update_repository_entity_old_hacs_version( hass: HomeAssistant, setup_integration: Generator, snapshots: SnapshotFixture, response_mocker: ResponseMocker, ): hacs = get_hacs(hass) repo = hacs.repositories.get_by_full_name( "hacs-test-org/integration-basic") assert repo is not None repo.data.installed = True repo.data.installed_version = "1.0.0" await hass.config_entries.async_reload(hacs.configuration.config_entry.entry_id) await hass.async_block_till_done() response_mocker.add( "https://raw.githubusercontent.com/hacs-test-org/integration-basic/3.0.0/hacs.json", MockedResponse(content=json.dumps({"hacs": "9999.99.99"})), ) # Get a new HACS instance after reload hacs = get_hacs(hass) er = async_get_entity_registry(hacs.hass) entity_id = er.async_get_entity_id("update", DOMAIN, repo.data.id) with pytest.raises(HomeAssistantError, match=re.escape("This version requires HACS 9999.99.99 or newer.")): await hass.services.async_call( "update", "install", service_data={"entity_id": entity_id, "version": "3.0.0"}, blocking=True, ) async def test_update_repository_entity_download_failure( hass: HomeAssistant, setup_integration: Generator, snapshots: SnapshotFixture, response_mocker: ResponseMocker, ): hacs = get_hacs(hass) repo = hacs.repositories.get_by_full_name( "hacs-test-org/integration-basic") assert repo is not None repo.data.installed = True repo.data.installed_version = "1.0.0" await hass.config_entries.async_reload(hacs.configuration.config_entry.entry_id) await hass.async_block_till_done() response_mocker.add( "https://github.com/hacs-test-org/integration-basic/archive/refs/tags/2.0.0.zip", MockedResponse(status=503), ) response_mocker.add( "https://github.com/hacs-test-org/integration-basic/archive/refs/heads/2.0.0.zip", MockedResponse(status=503), ) # Get a new HACS instance after reload hacs = get_hacs(hass) er = async_get_entity_registry(hacs.hass) entity_id = er.async_get_entity_id("update", DOMAIN, repo.data.id) with pytest.raises( HomeAssistantError, match=re.escape( "Downloading hacs-test-org/integration-basic with version 2.0.0 failed with (Could not download, see log for details)", ), ): await hass.services.async_call( "update", "install", service_data={"entity_id": entity_id, "version": "2.0.0"}, blocking=True, ) async def test_update_repository_entity_same_provided_version( hass: HomeAssistant, setup_integration: Generator ): hacs = get_hacs(hass) repo = hacs.repositories.get_by_full_name( "hacs-test-org/integration-basic") assert repo is not None repo.data.installed = True repo.data.installed_version = "2.0.0" await hass.config_entries.async_reload(hacs.configuration.config_entry.entry_id) await hass.async_block_till_done() # Get a new HACS instance after reload hacs = get_hacs(hass) er = async_get_entity_registry(hacs.hass) entity_id = er.async_get_entity_id("update", DOMAIN, repo.data.id) with pytest.raises( HomeAssistantError, match=re.escape( "Version 2.0.0 of hacs-test-org/integration-basic is already downloaded", ), ): await hass.services.async_call( "update", "install", service_data={"entity_id": entity_id, "version": "2.0.0"}, blocking=True, ) async def test_update_repository_entity_no_update( hass: HomeAssistant, setup_integration: Generator, ): hacs = get_hacs(hass) repo = hacs.repositories.get_by_full_name( "hacs-test-org/integration-basic") assert repo is not None repo.data.installed = True repo.data.installed_version = "1.0.0" await hass.config_entries.async_reload(hacs.configuration.config_entry.entry_id) await hass.async_block_till_done() # Get a new HACS instance after reload hacs = get_hacs(hass) er = async_get_entity_registry(hacs.hass) entity_id = er.async_get_entity_id("update", DOMAIN, repo.data.id) with pytest.raises( HomeAssistantError, match=re.escape( "No update available for update.basic_integration_update", ), ): await hass.services.async_call( "update", "install", service_data={"entity_id": entity_id}, blocking=True, ) ================================================ FILE: tests/ruff.toml ================================================ extend = "../pyproject.toml" src = [ "tests", ] [lint] ignore = [ "A002", "ASYNC230", "D104", "E712", "N811", "PLC0414", "PT006", "PT007", "PT011", "PT014", "PT019", "PT028", "PTH118", "PTH120", "PTH207", "PLW0108", "RET505", "S101", "TRY002", "UP035", ] ================================================ FILE: tests/scripts/data/test_generate_category_data.py ================================================ """Test generate category data.""" import asyncio import json import os from typing import Any from homeassistant.core import HomeAssistant import pytest from scripts.data.generate_category_data import OUTPUT_DIR, generate_category_data from tests.common import ( FIXTURES_PATH, CategoryTestData, MockedResponse, ResponseMocker, category_test_data_parametrized, recursive_remove_key, safe_json_dumps, ) from tests.conftest import SnapshotFixture BASE_HEADERS = {"Content-Type": "application/json"} RATE_LIMIT_HEADER = { **BASE_HEADERS, "X-RateLimit-Limit": "9999", "X-RateLimit-Remaining": "9999", "X-RateLimit-Reset": "9999", } def get_generated_category_data(category: str) -> dict[str, Any]: """Get the generated data.""" compare = {} with open(f"{OUTPUT_DIR}/{category}/data.json", encoding="utf-8") as file: compare["data"] = recursive_remove_key( json.loads(file.read()), ("last_fetched",)) with open(f"{OUTPUT_DIR}/{category}/repositories.json", encoding="utf-8") as file: compare["repositories"] = recursive_remove_key( json.loads(file.read()), ()) with open(f"{OUTPUT_DIR}/summary.json", encoding="utf-8") as file: compare["summary"] = recursive_remove_key(json.loads(file.read()), ()) return compare @pytest.mark.parametrize("category_test_data", category_test_data_parametrized()) async def test_generate_category_data_single_repository( hass: HomeAssistant, response_mocker: ResponseMocker, snapshots: SnapshotFixture, category_test_data: CategoryTestData, ): """Test behaviour if single repository.""" response_mocker.add( f"https://data-v2.hacs.xyz/{category_test_data['category']}/data.json", MockedResponse(content={}), ) await generate_category_data(category_test_data["category"], category_test_data["repository"]) with open(f"{OUTPUT_DIR}/{category_test_data['category']}/data.json", encoding="utf-8") as file: snapshots.assert_match( safe_json_dumps(recursive_remove_key( json.loads(file.read()), ("last_fetched",))), f"scripts/data/generate_category_data/single/{category_test_data['category']}/{ category_test_data['repository']}/data.json", ) with open( f"{OUTPUT_DIR}/{category_test_data['category']}/repositories.json", encoding="utf-8", ) as file: snapshots.assert_match( safe_json_dumps(json.loads(file.read())), f"scripts/data/generate_category_data/single/{category_test_data['category']}/{ category_test_data['repository']}/repositories.json", ) with open( f"{OUTPUT_DIR}/summary.json", encoding="utf-8", ) as file: snapshots.assert_match( safe_json_dumps(json.loads(file.read())), f"scripts/data/generate_category_data/single/{category_test_data['category']}/{ category_test_data['repository']}/summary.json", ) @pytest.mark.parametrize("category_test_data", category_test_data_parametrized()) async def test_generate_category_data( hass: HomeAssistant, response_mocker: ResponseMocker, snapshots: SnapshotFixture, category_test_data: CategoryTestData, ): """Test behaviour if single repository.""" response_mocker.add( f"https://data-v2.hacs.xyz/{category_test_data['category']}/data.json", MockedResponse(content={}), ) await generate_category_data(category_test_data["category"]) with open(f"{OUTPUT_DIR}/{category_test_data['category']}/data.json", encoding="utf-8") as file: snapshots.assert_match( safe_json_dumps(recursive_remove_key( json.loads(file.read()), ("last_fetched",))), f"scripts/data/generate_category_data/{ category_test_data['category']}//data.json", ) with open( f"{OUTPUT_DIR}/{category_test_data['category']}/repositories.json", encoding="utf-8", ) as file: snapshots.assert_match( safe_json_dumps(recursive_remove_key(json.loads(file.read()), ())), f"scripts/data/generate_category_data/{ category_test_data['category']}/repositories.json", ) with open( f"{OUTPUT_DIR}/summary.json", encoding="utf-8", ) as file: snapshots.assert_match( safe_json_dumps(recursive_remove_key(json.loads(file.read()), ())), f"scripts/data/generate_category_data/{ category_test_data['category']}/summary.json", ) @pytest.mark.parametrize("category_test_data", category_test_data_parametrized()) async def test_generate_category_data_with_prior_content( hass: HomeAssistant, response_mocker: ResponseMocker, snapshots: SnapshotFixture, category_test_data: CategoryTestData, ): """Test behaviour with prior content.""" category_data = { "integration": { "domain": "example", "manifest": {"name": "Proxy manifest"}, "manifest_name": "Proxy manifest", } } response_mocker.add( f"https://data-v2.hacs.xyz/{category_test_data['category']}/data.json", MockedResponse( content={ category_test_data["id"]: { "description": "This your first repo!", "downloads": 0, "etag_repository": "321", "full_name": category_test_data["repository"], "last_updated": "2011-01-26T19:06:43Z", "last_version": category_test_data["version_base"], "prerelease": "0.0.0", "stargazers_count": 0, "topics": ["api", "atom", "electron", "octocat"], **category_data.get(category_test_data["category"], {}), } } ), ) await generate_category_data(category_test_data["category"]) snapshots.assert_match( safe_json_dumps(get_generated_category_data( category_test_data["category"])), f"scripts/data/test_generate_category_data_with_prior_content/{ category_test_data['category']}.json", ) @pytest.mark.parametrize( "category_test_data", category_test_data_parametrized( categories=["integration"]) ) @pytest.mark.parametrize("error", (asyncio.CancelledError, asyncio.TimeoutError, Exception("base"))) async def test_generate_category_data_errors_release( hass: HomeAssistant, response_mocker: ResponseMocker, snapshots: SnapshotFixture, category_test_data: CategoryTestData, error: Exception, request: pytest.FixtureRequest, ): """Test behaviour if single repository.""" response_mocker.add( f"https://api.github.com/repos/{ category_test_data['repository']}/releases", MockedResponse(exception=error), ) await generate_category_data(category_test_data["category"]) snapshots.assert_match( safe_json_dumps(get_generated_category_data( category_test_data["category"])), f"scripts/data/test_generate_category_data_errors_release/{ category_test_data['category']}/{request.node.callspec.id.split("-")[0]}.json", ) @pytest.mark.parametrize( "category_test_data", category_test_data_parametrized( categories=["integration"]) ) @pytest.mark.parametrize("status", (304, 404)) async def test_generate_category_data_error_status_release( hass: HomeAssistant, response_mocker: ResponseMocker, snapshots: SnapshotFixture, category_test_data: CategoryTestData, status: int, ): """Test behaviour with error status and existing content.""" response_mocker.add( f"https://data-v2.hacs.xyz/{category_test_data['category']}/data.json", MockedResponse( content={ category_test_data["id"]: { "description": "This your first repo!", "downloads": 0, "etag_repository": "321", "full_name": category_test_data["repository"], "last_updated": "2011-01-26T19:06:43Z", "last_version": category_test_data["version_base"], "stargazers_count": 0, "topics": ["api", "atom", "electron", "octocat"], "domain": "example", "manifest": {"name": "Proxy manifest"}, "manifest_name": "Proxy manifest", } } ), ) response_mocker.add( f"https://api.github.com/repos/{ category_test_data['repository']}/releases", MockedResponse(status=status, content=[]), ) await generate_category_data(category_test_data["category"]) snapshots.assert_match( safe_json_dumps(get_generated_category_data( category_test_data["category"])), f"scripts/data/test_generate_category_data_error_status_release/{ category_test_data['category']}/{status}.json", ) @pytest.mark.parametrize( "category_test_data", category_test_data_parametrized( categories=["integration"]) ) async def test_generate_category_data_with_30plus_prereleases( hass: HomeAssistant, response_mocker: ResponseMocker, snapshots: SnapshotFixture, category_test_data: CategoryTestData, ): """Test behaviour with prior content.""" response_mocker.add( f"https://data-v2.hacs.xyz/{category_test_data['category']}/data.json", MockedResponse( content={ category_test_data["id"]: { "description": "This your first repo!", "downloads": 0, "etag_repository": "321", "full_name": category_test_data["repository"], "last_updated": "2011-01-26T19:06:43Z", "last_version": category_test_data["version_base"], "stargazers_count": 0, "topics": ["api", "atom", "electron", "octocat"], "domain": "example", "manifest": {"name": "Proxy manifest"}, "manifest_name": "Proxy manifest", } } ), ) with open( os.path.join( FIXTURES_PATH, "proxy/api.github.com/repos/hacs-test-org/integration-basic/releases.json", ) ) as file: release_fixture = json.loads(file.read())[0] response_mocker.add( f"https://api.github.com/repos/{ category_test_data['repository']}/releases", MockedResponse(content=[release_fixture for _ in range(30)]), ) await generate_category_data(category_test_data["category"]) snapshots.assert_match( safe_json_dumps(get_generated_category_data( category_test_data["category"])), f"scripts/data/test_generate_category_data_with_30plus_prereleases/{ category_test_data['category']}.json", ) ================================================ FILE: tests/snapshots/action/test_hacs_action_integration/bad_documentation.log ================================================ Checking repository. Running checks against main Getting custom_components/example/manifest.json for ref=main Getting hacs.json for version=main Getting manifest.json for version=main completed completed completed completed completed failed: invalid url for dictionary value @ data['documentation']. Got None (More info: https://hacs.xyz/docs/publish/include#check-manifest ) completed completed 1/8 checks failed Validation completed ::group::data { "data": { "archived": false, "authors": [], "category": "integration", "config_flow": true, "default_branch": "main", "description": "This your first repo!", "domain": "example", "downloads": 0, "etag_repository": "321", "etag_releases": null, "file_name": "", "first_install": false, "full_name": "hacs-test-org/integration-basic", "hide": false, "has_issues": true, "id": "1296269", "installed_commit": null, "installed_version": null, "installed": false, "last_commit": null, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest_name": "Proxy manifest", "new": true, "open_issues": 0, "prerelease": "3.0.0", "published_tags": [ "1.0.0" ], "releases": true, "selected_tag": "main", "show_beta": false, "stargazers_count": 80, "topics": [ "octocat", "atom", "electron", "api" ] }, "manifest": { "content_in_root": false, "country": [], "filename": null, "hacs": null, "hide_default_branch": false, "homeassistant": null, "manifest": { "name": "Proxy manifest" }, "name": "Proxy manifest", "persistent_directory": null, "render_readme": false, "zip_release": false }, "release": { "tag": "1.0.0", "assets": [ "example.zip" ] }, "category": "integration", "ref": "main" } ::endgroup:: ================================================ FILE: tests/snapshots/action/test_hacs_action_integration/bad_issue_tracker.log ================================================ Checking repository. Running checks against main Getting custom_components/example/manifest.json for ref=main Getting hacs.json for version=main Getting manifest.json for version=main completed completed completed completed completed failed: invalid url for dictionary value @ data['issue_tracker']. Got None (More info: https://hacs.xyz/docs/publish/include#check-manifest ) completed completed 1/8 checks failed Validation completed ::group::data { "data": { "archived": false, "authors": [], "category": "integration", "config_flow": true, "default_branch": "main", "description": "This your first repo!", "domain": "example", "downloads": 0, "etag_repository": "321", "etag_releases": null, "file_name": "", "first_install": false, "full_name": "hacs-test-org/integration-basic", "hide": false, "has_issues": true, "id": "1296269", "installed_commit": null, "installed_version": null, "installed": false, "last_commit": null, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest_name": "Proxy manifest", "new": true, "open_issues": 0, "prerelease": "3.0.0", "published_tags": [ "1.0.0" ], "releases": true, "selected_tag": "main", "show_beta": false, "stargazers_count": 80, "topics": [ "octocat", "atom", "electron", "api" ] }, "manifest": { "content_in_root": false, "country": [], "filename": null, "hacs": null, "hide_default_branch": false, "homeassistant": null, "manifest": { "name": "Proxy manifest" }, "name": "Proxy manifest", "persistent_directory": null, "render_readme": false, "zip_release": false }, "release": { "tag": "1.0.0", "assets": [ "example.zip" ] }, "category": "integration", "ref": "main" } ::endgroup:: ================================================ FILE: tests/snapshots/action/test_hacs_action_integration/no_releases.log ================================================ Checking repository. Running checks against main Getting custom_components/example/manifest.json for ref=main Getting hacs.json for version=main Getting manifest.json for version=main completed completed completed completed completed completed completed completed All (8) checks passed Validation completed ::group::data { "data": { "archived": false, "authors": [], "category": "integration", "config_flow": true, "default_branch": "main", "description": "This your first repo!", "domain": "example", "downloads": 0, "etag_repository": "321", "etag_releases": null, "file_name": "", "first_install": false, "full_name": "hacs-test-org/integration-basic", "hide": false, "has_issues": true, "id": "1296269", "installed_commit": null, "installed_version": null, "installed": false, "last_commit": null, "last_updated": "2011-01-26T19:06:43Z", "last_version": null, "manifest_name": "Proxy manifest", "new": true, "open_issues": 0, "prerelease": null, "published_tags": [], "releases": false, "selected_tag": "main", "show_beta": false, "stargazers_count": 80, "topics": [ "octocat", "atom", "electron", "api" ] }, "manifest": { "content_in_root": false, "country": [], "filename": null, "hacs": null, "hide_default_branch": false, "homeassistant": null, "manifest": { "name": "Proxy manifest" }, "name": "Proxy manifest", "persistent_directory": null, "render_readme": false, "zip_release": false }, "release": null, "category": "integration", "ref": "main" } ::endgroup:: ================================================ FILE: tests/snapshots/action/test_hacs_action_integration/releases_without_assets.log ================================================ Checking repository. Running checks against main Getting custom_components/example/manifest.json for ref=main Getting hacs.json for version=main Getting manifest.json for version=main completed completed completed completed completed completed completed completed All (8) checks passed Validation completed ::group::data { "data": { "archived": false, "authors": [], "category": "integration", "config_flow": true, "default_branch": "main", "description": "This your first repo!", "domain": "example", "downloads": 0, "etag_repository": "321", "etag_releases": null, "file_name": "", "first_install": false, "full_name": "hacs-test-org/integration-basic", "hide": false, "has_issues": true, "id": "1296269", "installed_commit": null, "installed_version": null, "installed": false, "last_commit": null, "last_updated": "2011-01-26T19:06:43Z", "last_version": "v1.0.0", "manifest_name": "Proxy manifest", "new": true, "open_issues": 0, "prerelease": null, "published_tags": [ "v1.0.0" ], "releases": true, "selected_tag": "main", "show_beta": false, "stargazers_count": 80, "topics": [ "octocat", "atom", "electron", "api" ] }, "manifest": { "content_in_root": false, "country": [], "filename": null, "hacs": null, "hide_default_branch": false, "homeassistant": null, "manifest": { "name": "Proxy manifest" }, "name": "Proxy manifest", "persistent_directory": null, "render_readme": false, "zip_release": false }, "release": { "tag": "v1.0.0", "assets": [] }, "category": "integration", "ref": "main" } ::endgroup:: ================================================ FILE: tests/snapshots/action/test_hacs_action_integration/valid_manifest.log ================================================ Checking repository. Running checks against main Getting custom_components/example/manifest.json for ref=main Getting hacs.json for version=main Getting manifest.json for version=main completed completed completed completed completed completed completed completed All (8) checks passed Validation completed ::group::data { "data": { "archived": false, "authors": [], "category": "integration", "config_flow": true, "default_branch": "main", "description": "This your first repo!", "domain": "example", "downloads": 0, "etag_repository": "321", "etag_releases": null, "file_name": "", "first_install": false, "full_name": "hacs-test-org/integration-basic", "hide": false, "has_issues": true, "id": "1296269", "installed_commit": null, "installed_version": null, "installed": false, "last_commit": null, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest_name": "Proxy manifest", "new": true, "open_issues": 0, "prerelease": "3.0.0", "published_tags": [ "1.0.0" ], "releases": true, "selected_tag": "main", "show_beta": false, "stargazers_count": 80, "topics": [ "octocat", "atom", "electron", "api" ] }, "manifest": { "content_in_root": false, "country": [], "filename": null, "hacs": null, "hide_default_branch": false, "homeassistant": null, "manifest": { "name": "Proxy manifest" }, "name": "Proxy manifest", "persistent_directory": null, "render_readme": false, "zip_release": false }, "release": { "tag": "1.0.0", "assets": [ "example.zip" ] }, "category": "integration", "ref": "main" } ::endgroup:: ================================================ FILE: tests/snapshots/api-usage/tests/action/test_hacs_action_integrationtest-hacs-action-integration-bad-documentation.json ================================================ { "tests/action/test_hacs_action_integration.py::test_hacs_action_integration[bad_documentation]": { "https://api.github.com/repos/hacs-test-org/integration-basic": 2, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/main": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 1, "https://brands.home-assistant.io/domains.json": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/main/custom_components/example/manifest.json": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/main/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/action/test_hacs_action_integrationtest-hacs-action-integration-bad-issue-tracker.json ================================================ { "tests/action/test_hacs_action_integration.py::test_hacs_action_integration[bad_issue_tracker]": { "https://api.github.com/repos/hacs-test-org/integration-basic": 2, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/main": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 1, "https://brands.home-assistant.io/domains.json": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/main/custom_components/example/manifest.json": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/main/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/action/test_hacs_action_integrationtest-hacs-action-integration-no-releases.json ================================================ { "tests/action/test_hacs_action_integration.py::test_hacs_action_integration[no_releases]": { "https://api.github.com/repos/hacs-test-org/integration-basic": 2, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/main": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 1, "https://brands.home-assistant.io/domains.json": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/main/custom_components/example/manifest.json": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/main/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/action/test_hacs_action_integrationtest-hacs-action-integration-releases-without-assets.json ================================================ { "tests/action/test_hacs_action_integration.py::test_hacs_action_integration[releases_without_assets]": { "https://api.github.com/repos/hacs-test-org/integration-basic": 2, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/main": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 1, "https://brands.home-assistant.io/domains.json": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/main/custom_components/example/manifest.json": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/main/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/action/test_hacs_action_integrationtest-hacs-action-integration-valid-manifest.json ================================================ { "tests/action/test_hacs_action_integration.py::test_hacs_action_integration[valid_manifest]": { "https://api.github.com/repos/hacs-test-org/integration-basic": 2, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/main": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 1, "https://brands.home-assistant.io/domains.json": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/main/custom_components/example/manifest.json": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/main/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/hacsbase/test_backuptest-directory.json ================================================ { "tests/hacsbase/test_backup.py::test_directory": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/hacsbase/test_backuptest-file.json ================================================ { "tests/hacsbase/test_backup.py::test_file": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/hacsbase/test_backuptest-muilti.json ================================================ { "tests/hacsbase/test_backup.py::test_muilti": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/hacsbase/test_hacsbase_datatest-hacs-data-async-write1.json ================================================ { "tests/hacsbase/test_hacsbase_data.py::test_hacs_data_async_write1": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/hacsbase/test_hacsbase_datatest-hacs-data-async-write2.json ================================================ { "tests/hacsbase/test_hacsbase_data.py::test_hacs_data_async_write2": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/hacsbase/test_hacsbase_datatest-hacs-data-restore-write-not-new.json ================================================ { "tests/hacsbase/test_hacsbase_data.py::test_hacs_data_restore_write_not_new": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/hacsbase/test_hacstest-add-remove-repository.json ================================================ { "tests/hacsbase/test_hacs.py::test_add_remove_repository": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/hacsbase/test_hacstest-hacs.json ================================================ { "tests/hacsbase/test_hacs.py::test_hacs": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_gather_files_to_downloadtest-gather-appdaemon-files-base.json ================================================ { "tests/helpers/download/test_gather_files_to_download.py::test_gather_appdaemon_files_base": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_gather_files_to_downloadtest-gather-appdaemon-files-with-subdir.json ================================================ { "tests/helpers/download/test_gather_files_to_download.py::test_gather_appdaemon_files_with_subdir": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_gather_files_to_downloadtest-gather-content-in-root-theme.json ================================================ { "tests/helpers/download/test_gather_files_to_download.py::test_gather_content_in_root_theme": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_gather_files_to_downloadtest-gather-files-to-download.json ================================================ { "tests/helpers/download/test_gather_files_to_download.py::test_gather_files_to_download": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_gather_files_to_downloadtest-gather-plugin-different-card-name.json ================================================ { "tests/helpers/download/test_gather_files_to_download.py::test_gather_plugin_different_card_name": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_gather_files_to_downloadtest-gather-plugin-files-from-dist.json ================================================ { "tests/helpers/download/test_gather_files_to_download.py::test_gather_plugin_files_from_dist": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_gather_files_to_downloadtest-gather-plugin-files-from-release-multiple.json ================================================ { "tests/helpers/download/test_gather_files_to_download.py::test_gather_plugin_files_from_release_multiple": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_gather_files_to_downloadtest-gather-plugin-files-from-release.json ================================================ { "tests/helpers/download/test_gather_files_to_download.py::test_gather_plugin_files_from_release": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_gather_files_to_downloadtest-gather-plugin-files-from-root.json ================================================ { "tests/helpers/download/test_gather_files_to_download.py::test_gather_plugin_files_from_root": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_gather_files_to_downloadtest-gather-plugin-multiple-files-in-root.json ================================================ { "tests/helpers/download/test_gather_files_to_download.py::test_gather_plugin_multiple_files_in_root": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_gather_files_to_downloadtest-gather-plugin-multiple-plugin-files-from-dist.json ================================================ { "tests/helpers/download/test_gather_files_to_download.py::test_gather_plugin_multiple_plugin_files_from_dist": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_gather_files_to_downloadtest-gather-zip-release.json ================================================ { "tests/helpers/download/test_gather_files_to_download.py::test_gather_zip_release": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_gather_files_to_downloadtest-single-file-repo.json ================================================ { "tests/helpers/download/test_gather_files_to_download.py::test_single_file_repo": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_should_try_releasestest-base.json ================================================ { "tests/helpers/download/test_should_try_releases.py::test_base": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_should_try_releasestest-category-is-wrong.json ================================================ { "tests/helpers/download/test_should_try_releases.py::test_category_is_wrong": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_should_try_releasestest-no-releases.json ================================================ { "tests/helpers/download/test_should_try_releases.py::test_no_releases": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_should_try_releasestest-ref-is-default.json ================================================ { "tests/helpers/download/test_should_try_releases.py::test_ref_is_default": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/helpers/download/test_should_try_releasestest-zip-release.json ================================================ { "tests/helpers/download/test_should_try_releases.py::test_zip_release": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/integration/test_integration_setuptest-integration-setup.json ================================================ { "tests/integration/test_integration_setup.py::test_integration_setup": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/helpers/test_propertiestest-repository-helpers-properties-can-be-installed.json ================================================ { "tests/repositories/helpers/test_properties.py::test_repository_helpers_properties_can_be_installed": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/helpers/test_propertiestest-repository-helpers-properties-pending-update.json ================================================ { "tests/repositories/helpers/test_properties.py::test_repository_helpers_properties_pending_update": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_can_installtest-hacs-can-install.json ================================================ { "tests/repositories/test_can_install.py::test_hacs_can_install": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_display_statustest-display-status.json ================================================ { "tests/repositories/test_display_status.py::test_display_status": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_download_repositorytest-download-repository-hacs-test-org-appdaemon-basic.json ================================================ { "tests/repositories/test_download_repository.py::test_download_repository[hacs-test-org/appdaemon-basic]": { "https://api.github.com/repos/hacs-test-org/appdaemon-basic": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps/example": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://github.com/hacs-test-org/appdaemon-basic/archive/refs/tags/1.0.0.zip": 1, "https://raw.githubusercontent.com/hacs-test-org/appdaemon-basic/1.0.0/README.md": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_download_repositorytest-download-repository-hacs-test-org-integration-basic.json ================================================ { "tests/repositories/test_download_repository.py::test_download_repository[hacs-test-org/integration-basic]": { "https://api.github.com/repos/hacs-test-org/integration-basic": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://github.com/hacs-test-org/integration-basic/archive/refs/tags/1.0.0.zip": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/1.0.0/README.md": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_download_repositorytest-download-repository-hacs-test-org-plugin-basic.json ================================================ { "tests/repositories/test_download_repository.py::test_download_repository[hacs-test-org/plugin-basic]": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_download_repositorytest-download-repository-hacs-test-org-python-script-basic.json ================================================ { "tests/repositories/test_download_repository.py::test_download_repository[hacs-test-org/python_script-basic]": { "https://api.github.com/repos/hacs-test-org/python_script-basic": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/python_script-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/python_script-basic/1.0.0/python_scripts/example.py": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_download_repositorytest-download-repository-hacs-test-org-template-basic.json ================================================ { "tests/repositories/test_download_repository.py::test_download_repository[hacs-test-org/template-basic]": { "https://api.github.com/repos/hacs-test-org/template-basic": 1, "https://api.github.com/repos/hacs-test-org/template-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/template-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/template-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/template-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/template-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/template-basic/1.0.0/example.jinja": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_download_repositorytest-download-repository-hacs-test-org-theme-basic.json ================================================ { "tests/repositories/test_download_repository.py::test_download_repository[hacs-test-org/theme-basic]": { "https://api.github.com/repos/hacs-test-org/theme-basic": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/theme-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/theme-basic/1.0.0/themes/example.yaml": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_get_documentationtest-repository-get-documentation-data0.json ================================================ { "tests/repositories/test_get_documentation.py::test_repository_get_documentation[data0]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/1.0.0/README.md": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_get_documentationtest-repository-get-documentation-data1.json ================================================ { "tests/repositories/test_get_documentation.py::test_repository_get_documentation[data1]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/1.0.0/README.md": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_get_documentationtest-repository-get-documentation-data2.json ================================================ { "tests/repositories/test_get_documentation.py::test_repository_get_documentation[data2]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/2.0.0/README.md": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_get_documentationtest-repository-get-documentation-data3.json ================================================ { "tests/repositories/test_get_documentation.py::test_repository_get_documentation[data3]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/99.99.99/README.md": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_get_hacs_json_rawtest-get-hacs-json-raw-1-0-0-expected0.json ================================================ { "tests/repositories/test_get_hacs_json_raw.py::test_get_hacs_json_raw[1.0.0-expected0]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/1.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_get_hacs_json_rawtest-get-hacs-json-raw-99-99-99-none.json ================================================ { "tests/repositories/test_get_hacs_json_raw.py::test_get_hacs_json_raw[99.99.99-None]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/99.99.99/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_get_hacs_json_rawtest-get-hacs-json-raw-with-exception.json ================================================ { "tests/repositories/test_get_hacs_json_raw.py::test_get_hacs_json_raw_with_exception": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/1.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_get_hacs_jsontest-get-hacs-json-with-exception.json ================================================ { "tests/repositories/test_get_hacs_json.py::test_get_hacs_json_with_exception": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/1.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_get_hacs_jsontest-validate-repository-1-0-0-integration-basic-1-0-0.json ================================================ { "tests/repositories/test_get_hacs_json.py::test_validate_repository[1.0.0-Integration basic 1.0.0]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/1.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_get_hacs_jsontest-validate-repository-99-99-99-none.json ================================================ { "tests/repositories/test_get_hacs_json.py::test_validate_repository[99.99.99-None]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/99.99.99/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_get_reposiotry_releasestest-get-reposiotry-releases-hacs-test-org-appdaemon-basic.json ================================================ { "tests/repositories/test_get_reposiotry_releases.py::test_get_reposiotry_releases[hacs-test-org/appdaemon-basic]": { "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_get_reposiotry_releasestest-get-reposiotry-releases-hacs-test-org-integration-basic.json ================================================ { "tests/repositories/test_get_reposiotry_releases.py::test_get_reposiotry_releases[hacs-test-org/integration-basic]": { "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_get_reposiotry_releasestest-get-reposiotry-releases-hacs-test-org-plugin-basic.json ================================================ { "tests/repositories/test_get_reposiotry_releases.py::test_get_reposiotry_releases[hacs-test-org/plugin-basic]": { "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_get_reposiotry_releasestest-get-reposiotry-releases-hacs-test-org-python-script-basic.json ================================================ { "tests/repositories/test_get_reposiotry_releases.py::test_get_reposiotry_releases[hacs-test-org/python_script-basic]": { "https://api.github.com/repos/hacs-test-org/python_script-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_get_reposiotry_releasestest-get-reposiotry-releases-hacs-test-org-template-basic.json ================================================ { "tests/repositories/test_get_reposiotry_releases.py::test_get_reposiotry_releases[hacs-test-org/template-basic]": { "https://api.github.com/repos/hacs-test-org/template-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_get_reposiotry_releasestest-get-reposiotry-releases-hacs-test-org-theme-basic.json ================================================ { "tests/repositories/test_get_reposiotry_releases.py::test_get_reposiotry_releases[hacs-test-org/theme-basic]": { "https://api.github.com/repos/hacs-test-org/theme-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-add-dashboard-resource-with-invalid-file-name.json ================================================ { "tests/repositories/test_plugin_repository.py::test_add_dashboard_resource_with_invalid_file_name": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-add-dashboard-resource.json ================================================ { "tests/repositories/test_plugin_repository.py::test_add_dashboard_resource": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-dashboard-hacstag-1-0-0-none-none-100.json ================================================ { "tests/repositories/test_plugin_repository.py::test_dashboard_hacstag[1.0.0-None-None-100]": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-dashboard-hacstag-1-7-dev09-r2-none-none-17092.json ================================================ { "tests/repositories/test_plugin_repository.py::test_dashboard_hacstag[1.7-dev09-r2-None-None-17092]": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-dashboard-hacstag-none-2-0-1-none-201.json ================================================ { "tests/repositories/test_plugin_repository.py::test_dashboard_hacstag[None-2.0.1-None-201]": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-dashboard-hacstag-none-none-3-4-2-342.json ================================================ { "tests/repositories/test_plugin_repository.py::test_dashboard_hacstag[None-None-3.4.2-342]": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-dashboard-hacstag-none-none-none.json ================================================ { "tests/repositories/test_plugin_repository.py::test_dashboard_hacstag[None-None-None-]": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-dashboard-namespace-hacs-test-org-awesome-plugin-hacsfiles-awesome-plugin.json ================================================ { "tests/repositories/test_plugin_repository.py::test_dashboard_namespace[hacs-test-org/awesome-plugin-/hacsfiles/awesome-plugin]": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-dashboard-namespace-hacs-test-org-plugin-advanced-hacsfiles-plugin-advanced.json ================================================ { "tests/repositories/test_plugin_repository.py::test_dashboard_namespace[hacs-test-org/plugin-advanced-/hacsfiles/plugin-advanced]": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-dashboard-namespace-hacs-test-org-plugin-basic-hacsfiles-plugin-basic.json ================================================ { "tests/repositories/test_plugin_repository.py::test_dashboard_namespace[hacs-test-org/plugin-basic-/hacsfiles/plugin-basic]": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-dashboard-url.json ================================================ { "tests/repositories/test_plugin_repository.py::test_dashboard_url": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-get-resource-handler-no-hass-data.json ================================================ { "tests/repositories/test_plugin_repository.py::test_get_resource_handler_no_hass_data": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-get-resource-handler-no-lovelace-data.json ================================================ { "tests/repositories/test_plugin_repository.py::test_get_resource_handler_no_lovelace_data": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-get-resource-handler-no-lovelace-resources.json ================================================ { "tests/repositories/test_plugin_repository.py::test_get_resource_handler_no_lovelace_resources": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-get-resource-handler-no-store.json ================================================ { "tests/repositories/test_plugin_repository.py::test_get_resource_handler_no_store": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-get-resource-handler-none-store.json ================================================ { "tests/repositories/test_plugin_repository.py::test_get_resource_handler_none_store": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-get-resource-handler-wrong-key.json ================================================ { "tests/repositories/test_plugin_repository.py::test_get_resource_handler_wrong_key": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-get-resource-handler-wrong-version.json ================================================ { "tests/repositories/test_plugin_repository.py::test_get_resource_handler_wrong_version": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-get-resource-handler.json ================================================ { "tests/repositories/test_plugin_repository.py::test_get_resource_handler": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-remove-dashboard-resource.json ================================================ { "tests/repositories/test_plugin_repository.py::test_remove_dashboard_resource": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_plugin_repositorytest-update-dashboard-resource.json ================================================ { "tests/repositories/test_plugin_repository.py::test_update_dashboard_resource": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_register_repositorytest-register-repository-failures-hacs-test-org-addon-basic-the-repository-does-not-seem-to-be-a-integration-but-an-add-on-repository-hacs-does-not-manage-add-ons.json ================================================ { "tests/repositories/test_register_repository.py::test_register_repository_failures[hacs-test-org/addon-basic-The repository does not seem to be a integration, but an add-on repository. HACS does not manage add-ons.]": { "https://api.github.com/repos/hacs-test-org/addon-basic": 1, "https://api.github.com/repos/hacs-test-org/addon-basic/git/trees/main": 1, "https://api.github.com/repos/hacs-test-org/addon-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_register_repositorytest-register-repository-failures-hacs-test-org-integration-invalid-integration-hacs-test-org-integration-invalid-repository-structure-for-main-is-not-compliant.json ================================================ { "tests/repositories/test_register_repository.py::test_register_repository_failures[hacs-test-org/integration-invalid- Repository structure for main is not compliant]": { "https://api.github.com/repos/hacs-test-org/integration-invalid": 1, "https://api.github.com/repos/hacs-test-org/integration-invalid/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-invalid/git/trees/main": 1, "https://api.github.com/repos/hacs-test-org/integration-invalid/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_register_repositorytest-register-repository-failures-hassio-addons-example-the-repository-does-not-seem-to-be-a-integration-but-an-add-on-repository-hacs-does-not-manage-add-ons.json ================================================ { "tests/repositories/test_register_repository.py::test_register_repository_failures[hassio-addons/example-The repository does not seem to be a integration, but an add-on repository. HACS does not manage add-ons.]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_register_repositorytest-register-repository-failures-home-assistant-addons-the-repository-does-not-seem-to-be-a-integration-but-an-add-on-repository-hacs-does-not-manage-add-ons.json ================================================ { "tests/repositories/test_register_repository.py::test_register_repository_failures[home-assistant/addons-The repository does not seem to be a integration, but an add-on repository. HACS does not manage add-ons.]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_register_repositorytest-register-repository-failures-home-assistant-core-you-can-not-add-homeassistant-core-to-use-core-integrations-check-the-home-assistant-documentation-for-how-to-add-them.json ================================================ { "tests/repositories/test_register_repository.py::test_register_repository_failures[home-assistant/core-You can not add homeassistant/core, to use core integrations check the Home Assistant documentation for how to add them.]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_register_repositorytest-register-repository-hacs-test-org-integration-basic-custom-integration.json ================================================ { "tests/repositories/test_register_repository.py::test_register_repository[hacs-test-org/integration-basic-custom-integration]": { "https://api.github.com/repos/hacs-test-org/integration-basic-custom": 2, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/branches/main": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/custom_components/example/manifest.json": 2, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/hacs.json": 2, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/trees/1.0.0": 2, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/releases": 2, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic-custom/1.0.0/README.md": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_register_repositorytest-register-repository-hacs-test-org-plugin-custom-dist-plugin.json ================================================ { "tests/repositories/test_register_repository.py::test_register_repository[hacs-test-org/plugin-custom-dist-plugin]": { "https://api.github.com/repos/hacs-test-org/plugin-custom-dist": 2, "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/contents/hacs.json": 2, "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/git/trees/1.0.0": 2, "https://api.github.com/repos/hacs-test-org/plugin-custom-dist/releases": 2, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-custom-dist/1.0.0/README.md": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_remove_repositorytest-remove-repository-hacs-test-org-appdaemon-basic.json ================================================ { "tests/repositories/test_remove_repository.py::test_remove_repository[hacs-test-org/appdaemon-basic]": { "https://api.github.com/repos/hacs-test-org/appdaemon-basic": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps/example": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_remove_repositorytest-remove-repository-hacs-test-org-integration-basic.json ================================================ { "tests/repositories/test_remove_repository.py::test_remove_repository[hacs-test-org/integration-basic]": { "https://api.github.com/repos/hacs-test-org/integration-basic": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_remove_repositorytest-remove-repository-hacs-test-org-plugin-basic.json ================================================ { "tests/repositories/test_remove_repository.py::test_remove_repository[hacs-test-org/plugin-basic]": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_remove_repositorytest-remove-repository-hacs-test-org-python-script-basic.json ================================================ { "tests/repositories/test_remove_repository.py::test_remove_repository[hacs-test-org/python_script-basic]": { "https://api.github.com/repos/hacs-test-org/python_script-basic": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_remove_repositorytest-remove-repository-hacs-test-org-template-basic.json ================================================ { "tests/repositories/test_remove_repository.py::test_remove_repository[hacs-test-org/template-basic]": { "https://api.github.com/repos/hacs-test-org/template-basic": 1, "https://api.github.com/repos/hacs-test-org/template-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/template-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/template-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/template-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_remove_repositorytest-remove-repository-hacs-test-org-theme-basic.json ================================================ { "tests/repositories/test_remove_repository.py::test_remove_repository[hacs-test-org/theme-basic]": { "https://api.github.com/repos/hacs-test-org/theme-basic": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-entity-download-failure.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_entity_download_failure": { "https://api.github.com/repos/hacs-test-org/integration-basic": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1, "https://github.com/hacs-test-org/integration-basic/archive/refs/heads/2.0.0.zip": 1, "https://github.com/hacs-test-org/integration-basic/archive/refs/tags/2.0.0.zip": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/1.0.0/custom_components/example/manifest.json": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/2.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-entity-hacs-test-org-appdaemon-basic.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_entity[hacs-test-org/appdaemon-basic]": { "https://api.github.com/repos/hacs-test-org/appdaemon-basic": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps/example": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1, "https://github.com/hacs-test-org/appdaemon-basic/archive/refs/tags/2.0.0.zip": 1, "https://raw.githubusercontent.com/hacs-test-org/appdaemon-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/appdaemon-basic/2.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-entity-hacs-test-org-integration-basic.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_entity[hacs-test-org/integration-basic]": { "https://api.github.com/repos/hacs-test-org/integration-basic": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1, "https://github.com/hacs-test-org/integration-basic/archive/refs/tags/2.0.0.zip": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/2.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-entity-hacs-test-org-plugin-basic.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_entity[hacs-test-org/plugin-basic]": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/2.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-entity-hacs-test-org-python-script-basic.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_entity[hacs-test-org/python_script-basic]": { "https://api.github.com/repos/hacs-test-org/python_script-basic": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1, "https://raw.githubusercontent.com/hacs-test-org/python_script-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/python_script-basic/1.0.0/python_scripts/example.py": 1, "https://raw.githubusercontent.com/hacs-test-org/python_script-basic/2.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-entity-hacs-test-org-template-basic.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_entity[hacs-test-org/template-basic]": { "https://api.github.com/repos/hacs-test-org/template-basic": 1, "https://api.github.com/repos/hacs-test-org/template-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/template-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/template-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/template-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1, "https://raw.githubusercontent.com/hacs-test-org/template-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/template-basic/1.0.0/example.jinja": 1, "https://raw.githubusercontent.com/hacs-test-org/template-basic/2.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-entity-hacs-test-org-theme-basic.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_entity[hacs-test-org/theme-basic]": { "https://api.github.com/repos/hacs-test-org/theme-basic": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1, "https://raw.githubusercontent.com/hacs-test-org/theme-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/theme-basic/1.0.0/themes/example.yaml": 1, "https://raw.githubusercontent.com/hacs-test-org/theme-basic/2.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-entity-no-manifest.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_entity_no_manifest": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/3.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-entity-no-update.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_entity_no_update": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-entity-old-core-version.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_entity_old_core_version": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/3.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-entity-old-hacs-version.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_entity_old_hacs_version": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/3.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-entity-same-provided-version.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_entity_same_provided_version": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-websocket-hacs-test-org-appdaemon-basic.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_websocket[hacs-test-org/appdaemon-basic]": { "https://api.github.com/repos/hacs-test-org/appdaemon-basic": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps/example": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://github.com/hacs-test-org/appdaemon-basic/archive/refs/tags/2.0.0.zip": 1, "https://raw.githubusercontent.com/hacs-test-org/appdaemon-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/appdaemon-basic/2.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-websocket-hacs-test-org-integration-basic.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_websocket[hacs-test-org/integration-basic]": { "https://api.github.com/repos/hacs-test-org/integration-basic": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://github.com/hacs-test-org/integration-basic/archive/refs/tags/2.0.0.zip": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/integration-basic/2.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-websocket-hacs-test-org-plugin-basic.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_websocket[hacs-test-org/plugin-basic]": { "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/1.0.0/plugin-basic.js": 1, "https://raw.githubusercontent.com/hacs-test-org/plugin-basic/2.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-websocket-hacs-test-org-python-script-basic.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_websocket[hacs-test-org/python_script-basic]": { "https://api.github.com/repos/hacs-test-org/python_script-basic": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/python_script-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/python_script-basic/1.0.0/python_scripts/example.py": 1, "https://raw.githubusercontent.com/hacs-test-org/python_script-basic/2.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-websocket-hacs-test-org-template-basic.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_websocket[hacs-test-org/template-basic]": { "https://api.github.com/repos/hacs-test-org/template-basic": 1, "https://api.github.com/repos/hacs-test-org/template-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/template-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/template-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/template-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/template-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/template-basic/1.0.0/example.jinja": 1, "https://raw.githubusercontent.com/hacs-test-org/template-basic/2.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/repositories/test_update_repositorytest-update-repository-websocket-hacs-test-org-theme-basic.json ================================================ { "tests/repositories/test_update_repository.py::test_update_repository_websocket[hacs-test-org/theme-basic]": { "https://api.github.com/repos/hacs-test-org/theme-basic": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/branches/main": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/releases": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://raw.githubusercontent.com/hacs-test-org/theme-basic/1.0.0/README.md": 1, "https://raw.githubusercontent.com/hacs-test-org/theme-basic/1.0.0/themes/example.yaml": 1, "https://raw.githubusercontent.com/hacs-test-org/theme-basic/2.0.0/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-error-status-release-304-hacs-test-org-integration-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_error_status_release[304-hacs-test-org/integration-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/integration-basic": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/releases": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 1, "https://api.github.com/repos/hacs/default/contents/integration": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/branches/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-error-status-release-404-hacs-test-org-integration-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_error_status_release[404-hacs-test-org/integration-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/integration-basic": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/releases": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 2, "https://api.github.com/repos/hacs/default/contents/integration": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/branches/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-errors-release-cancellederror-hacs-test-org-integration-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_errors_release[CancelledError-hacs-test-org/integration-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/integration-basic": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/releases": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 2, "https://api.github.com/repos/hacs/default/contents/integration": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/branches/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-errors-release-error2-hacs-test-org-integration-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_errors_release[error2-hacs-test-org/integration-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/integration-basic": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/releases": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 2, "https://api.github.com/repos/hacs/default/contents/integration": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/branches/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-errors-release-timeouterror-hacs-test-org-integration-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_errors_release[TimeoutError-hacs-test-org/integration-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/integration-basic": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/releases": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 2, "https://api.github.com/repos/hacs/default/contents/integration": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/branches/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-hacs-test-org-appdaemon-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data[hacs-test-org/appdaemon-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps/example": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases": 1, "https://api.github.com/repos/hacs/default/contents/appdaemon": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-hacs-test-org-integration-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data[hacs-test-org/integration-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/integration-basic": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/releases": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 1, "https://api.github.com/repos/hacs/default/contents/integration": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/branches/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-hacs-test-org-plugin-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data[hacs-test-org/plugin-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/default/contents/plugin": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-hacs-test-org-python-script-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data[hacs-test-org/python_script-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/releases": 1, "https://api.github.com/repos/hacs/default/contents/python_script": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-hacs-test-org-template-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data[hacs-test-org/template-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/template-basic": 1, "https://api.github.com/repos/hacs-test-org/template-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/template-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/template-basic/releases": 1, "https://api.github.com/repos/hacs/default/contents/template": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-hacs-test-org-theme-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data[hacs-test-org/theme-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/theme-basic": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/releases": 1, "https://api.github.com/repos/hacs/default/contents/theme": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-single-repository-hacs-test-org-appdaemon-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_single_repository[hacs-test-org/appdaemon-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/apps/example": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-single-repository-hacs-test-org-integration-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_single_repository[hacs-test-org/integration-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/integration-basic": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 1, "https://data-v2.hacs.xyz/integration/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-single-repository-hacs-test-org-plugin-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_single_repository[hacs-test-org/plugin-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-single-repository-hacs-test-org-python-script-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_single_repository[hacs-test-org/python_script-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/releases": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-single-repository-hacs-test-org-template-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_single_repository[hacs-test-org/template-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/template-basic": 1, "https://api.github.com/repos/hacs-test-org/template-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/template-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/template-basic/releases": 1, "https://data-v2.hacs.xyz/template/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-single-repository-hacs-test-org-theme-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_single_repository[hacs-test-org/theme-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/theme-basic": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/releases": 1, "https://data-v2.hacs.xyz/theme/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-with-30plus-prereleases-hacs-test-org-integration-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_with_30plus_prereleases[hacs-test-org/integration-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/integration-basic": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/releases": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases/latest": 1, "https://api.github.com/repos/hacs/default/contents/integration": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/branches/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-with-prior-content-hacs-test-org-appdaemon-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_with_prior_content[hacs-test-org/appdaemon-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/appdaemon-basic/releases": 1, "https://api.github.com/repos/hacs/default/contents/appdaemon": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-with-prior-content-hacs-test-org-integration-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_with_prior_content[hacs-test-org/integration-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/integration-basic": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/custom_components/example/manifest.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/contents/hacs.json": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic-custom/releases": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/integration-basic/releases": 1, "https://api.github.com/repos/hacs/default/contents/integration": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/branches/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-with-prior-content-hacs-test-org-plugin-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_with_prior_content[hacs-test-org/plugin-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/plugin-basic/releases": 1, "https://api.github.com/repos/hacs/default/contents/plugin": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-with-prior-content-hacs-test-org-python-script-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_with_prior_content[hacs-test-org/python_script-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/python_script-basic/releases": 1, "https://api.github.com/repos/hacs/default/contents/python_script": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-with-prior-content-hacs-test-org-template-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_with_prior_content[hacs-test-org/template-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/template-basic": 1, "https://api.github.com/repos/hacs-test-org/template-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/template-basic/releases": 1, "https://api.github.com/repos/hacs/default/contents/template": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/scripts/data/test_generate_category_datatest-generate-category-data-with-prior-content-hacs-test-org-theme-basic.json ================================================ { "tests/scripts/data/test_generate_category_data.py::test_generate_category_data_with_prior_content[hacs-test-org/theme-basic]": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs-test-org/theme-basic": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/git/trees/1.0.0": 1, "https://api.github.com/repos/hacs-test-org/theme-basic/releases": 1, "https://api.github.com/repos/hacs/default/contents/theme": 1, "https://data-v2.hacs.xyz/removed/repositories.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_config_flowtest-flow-with-activation-failure.json ================================================ { "tests/test_config_flow.py::test_flow_with_activation_failure": { "https://github.com/login/device/code": 1, "https://github.com/login/oauth/access_token": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_config_flowtest-flow-with-registration-failure.json ================================================ { "tests/test_config_flow.py::test_flow_with_registration_failure": { "https://github.com/login/device/code": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_config_flowtest-flow-with-remove-while-activating.json ================================================ { "tests/test_config_flow.py::test_flow_with_remove_while_activating": { "https://github.com/login/device/code": 1, "https://github.com/login/oauth/access_token": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_config_flowtest-full-user-flow-implementation.json ================================================ { "tests/test_config_flow.py::test_full_user_flow_implementation": { "https://github.com/login/device/code": 1, "https://github.com/login/oauth/access_token": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_config_flowtest-options-flow.json ================================================ { "tests/test_config_flow.py::test_options_flow": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-data-hacs-test-org-appdaemon-basic.json ================================================ { "tests/test_data_client.py::test_basic_functionality_data[hacs-test-org/appdaemon-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-data-hacs-test-org-integration-basic.json ================================================ { "tests/test_data_client.py::test_basic_functionality_data[hacs-test-org/integration-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-data-hacs-test-org-plugin-basic.json ================================================ { "tests/test_data_client.py::test_basic_functionality_data[hacs-test-org/plugin-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-data-hacs-test-org-python-script-basic.json ================================================ { "tests/test_data_client.py::test_basic_functionality_data[hacs-test-org/python_script-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-data-hacs-test-org-template-basic.json ================================================ { "tests/test_data_client.py::test_basic_functionality_data[hacs-test-org/template-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/template/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-data-hacs-test-org-theme-basic.json ================================================ { "tests/test_data_client.py::test_basic_functionality_data[hacs-test-org/theme-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/theme/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-data-validate-appdaemon-data0.json ================================================ { "tests/test_data_client.py::test_basic_functionality_data_validate[appdaemon-data0]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-data-validate-critical-data6.json ================================================ { "tests/test_data_client.py::test_basic_functionality_data_validate[critical-data6]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/critical/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-data-validate-integration-data1.json ================================================ { "tests/test_data_client.py::test_basic_functionality_data_validate[integration-data1]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-data-validate-plugin-data2.json ================================================ { "tests/test_data_client.py::test_basic_functionality_data_validate[plugin-data2]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/plugin/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-data-validate-python-script-data3.json ================================================ { "tests/test_data_client.py::test_basic_functionality_data_validate[python_script-data3]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/python_script/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-data-validate-removed-data7.json ================================================ { "tests/test_data_client.py::test_basic_functionality_data_validate[removed-data7]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/removed/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-data-validate-template-data4.json ================================================ { "tests/test_data_client.py::test_basic_functionality_data_validate[template-data4]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/template/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-data-validate-theme-data5.json ================================================ { "tests/test_data_client.py::test_basic_functionality_data_validate[theme-data5]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/theme/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-repositories-hacs-test-org-appdaemon-basic.json ================================================ { "tests/test_data_client.py::test_basic_functionality_repositories[hacs-test-org/appdaemon-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-repositories-hacs-test-org-integration-basic.json ================================================ { "tests/test_data_client.py::test_basic_functionality_repositories[hacs-test-org/integration-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-repositories-hacs-test-org-plugin-basic.json ================================================ { "tests/test_data_client.py::test_basic_functionality_repositories[hacs-test-org/plugin-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/plugin/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-repositories-hacs-test-org-python-script-basic.json ================================================ { "tests/test_data_client.py::test_basic_functionality_repositories[hacs-test-org/python_script-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/python_script/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-repositories-hacs-test-org-template-basic.json ================================================ { "tests/test_data_client.py::test_basic_functionality_repositories[hacs-test-org/template-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/template/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-basic-functionality-repositories-hacs-test-org-theme-basic.json ================================================ { "tests/test_data_client.py::test_basic_functionality_repositories[hacs-test-org/theme-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/theme/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-discard-invalid-repo-data-appdaemon-data0.json ================================================ { "tests/test_data_client.py::test_discard_invalid_repo_data[appdaemon-data0]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-discard-invalid-repo-data-integration-data1.json ================================================ { "tests/test_data_client.py::test_discard_invalid_repo_data[integration-data1]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-discard-invalid-repo-data-plugin-data2.json ================================================ { "tests/test_data_client.py::test_discard_invalid_repo_data[plugin-data2]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-discard-invalid-repo-data-python-script-data3.json ================================================ { "tests/test_data_client.py::test_discard_invalid_repo_data[python_script-data3]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-discard-invalid-repo-data-template-data4.json ================================================ { "tests/test_data_client.py::test_discard_invalid_repo_data[template-data4]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-discard-invalid-repo-data-theme-data5.json ================================================ { "tests/test_data_client.py::test_discard_invalid_repo_data[theme-data5]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-exception-handling-exception-error-fetching-data-from-hacs-test.json ================================================ { "tests/test_data_client.py::test_exception_handling[Exception-Error fetching data from HACS: Test]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-exception-handling-timeouterror-timeout-of-60s-reached.json ================================================ { "tests/test_data_client.py::test_exception_handling[TimeoutError-Timeout of 60s reached]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-status-handling-1009-hacsexception.json ================================================ { "tests/test_data_client.py::test_status_handling[1009-HacsException]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-status-handling-200-does-not-raise.json ================================================ { "tests/test_data_client.py::test_status_handling[200-does_not_raise]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-status-handling-201-does-not-raise.json ================================================ { "tests/test_data_client.py::test_status_handling[201-does_not_raise]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-status-handling-301-hacsexception.json ================================================ { "tests/test_data_client.py::test_status_handling[301-HacsException]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-status-handling-302-hacsexception.json ================================================ { "tests/test_data_client.py::test_status_handling[302-HacsException]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-status-handling-304-hacsnotmodifiedexception.json ================================================ { "tests/test_data_client.py::test_status_handling[304-HacsNotModifiedException]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-status-handling-400-hacsexception.json ================================================ { "tests/test_data_client.py::test_status_handling[400-HacsException]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-status-handling-401-hacsexception.json ================================================ { "tests/test_data_client.py::test_status_handling[401-HacsException]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-status-handling-403-hacsexception.json ================================================ { "tests/test_data_client.py::test_status_handling[403-HacsException]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-status-handling-418-hacsexception.json ================================================ { "tests/test_data_client.py::test_status_handling[418-HacsException]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-status-handling-429-hacsexception.json ================================================ { "tests/test_data_client.py::test_status_handling[429-HacsException]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-status-handling-500-hacsexception.json ================================================ { "tests/test_data_client.py::test_status_handling[500-HacsException]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_data_clienttest-status-handling-529-hacsexception.json ================================================ { "tests/test_data_client.py::test_status_handling[529-HacsException]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/integration/repositories.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_diagnosticstest-diagnostics-with-exception.json ================================================ { "tests/test_diagnostics.py::test_diagnostics_with_exception": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_diagnosticstest-diagnostics.json ================================================ { "tests/test_diagnostics.py::test_diagnostics": { "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_sensor_cleanuptest-sensor-cleanup.json ================================================ { "tests/test_sensor_cleanup.py::test_sensor_cleanup": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 1, "https://data-v2.hacs.xyz/critical/data.json": 1, "https://data-v2.hacs.xyz/integration/data.json": 1, "https://data-v2.hacs.xyz/plugin/data.json": 1, "https://data-v2.hacs.xyz/python_script/data.json": 1, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 1, "https://data-v2.hacs.xyz/theme/data.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_switchtest-switch-entity-state-hacs-test-org-appdaemon-basic.json ================================================ { "tests/test_switch.py::test_switch_entity_state[hacs-test-org/appdaemon-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 2, "https://data-v2.hacs.xyz/critical/data.json": 2, "https://data-v2.hacs.xyz/integration/data.json": 2, "https://data-v2.hacs.xyz/plugin/data.json": 2, "https://data-v2.hacs.xyz/python_script/data.json": 2, "https://data-v2.hacs.xyz/removed/data.json": 2, "https://data-v2.hacs.xyz/template/data.json": 2, "https://data-v2.hacs.xyz/theme/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_switchtest-switch-entity-state-hacs-test-org-integration-basic.json ================================================ { "tests/test_switch.py::test_switch_entity_state[hacs-test-org/integration-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 2, "https://data-v2.hacs.xyz/critical/data.json": 2, "https://data-v2.hacs.xyz/integration/data.json": 2, "https://data-v2.hacs.xyz/plugin/data.json": 2, "https://data-v2.hacs.xyz/python_script/data.json": 2, "https://data-v2.hacs.xyz/removed/data.json": 2, "https://data-v2.hacs.xyz/template/data.json": 2, "https://data-v2.hacs.xyz/theme/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_switchtest-switch-entity-state-hacs-test-org-plugin-basic.json ================================================ { "tests/test_switch.py::test_switch_entity_state[hacs-test-org/plugin-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 2, "https://data-v2.hacs.xyz/critical/data.json": 2, "https://data-v2.hacs.xyz/integration/data.json": 2, "https://data-v2.hacs.xyz/plugin/data.json": 2, "https://data-v2.hacs.xyz/python_script/data.json": 2, "https://data-v2.hacs.xyz/removed/data.json": 2, "https://data-v2.hacs.xyz/template/data.json": 2, "https://data-v2.hacs.xyz/theme/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_switchtest-switch-entity-state-hacs-test-org-python-script-basic.json ================================================ { "tests/test_switch.py::test_switch_entity_state[hacs-test-org/python_script-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 2, "https://data-v2.hacs.xyz/critical/data.json": 2, "https://data-v2.hacs.xyz/integration/data.json": 2, "https://data-v2.hacs.xyz/plugin/data.json": 2, "https://data-v2.hacs.xyz/python_script/data.json": 2, "https://data-v2.hacs.xyz/removed/data.json": 2, "https://data-v2.hacs.xyz/template/data.json": 2, "https://data-v2.hacs.xyz/theme/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_switchtest-switch-entity-state-hacs-test-org-template-basic.json ================================================ { "tests/test_switch.py::test_switch_entity_state[hacs-test-org/template-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 2, "https://data-v2.hacs.xyz/critical/data.json": 2, "https://data-v2.hacs.xyz/integration/data.json": 2, "https://data-v2.hacs.xyz/plugin/data.json": 2, "https://data-v2.hacs.xyz/python_script/data.json": 2, "https://data-v2.hacs.xyz/removed/data.json": 2, "https://data-v2.hacs.xyz/template/data.json": 2, "https://data-v2.hacs.xyz/theme/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_switchtest-switch-entity-state-hacs-test-org-theme-basic.json ================================================ { "tests/test_switch.py::test_switch_entity_state[hacs-test-org/theme-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 2, "https://data-v2.hacs.xyz/critical/data.json": 2, "https://data-v2.hacs.xyz/integration/data.json": 2, "https://data-v2.hacs.xyz/plugin/data.json": 2, "https://data-v2.hacs.xyz/python_script/data.json": 2, "https://data-v2.hacs.xyz/removed/data.json": 2, "https://data-v2.hacs.xyz/template/data.json": 2, "https://data-v2.hacs.xyz/theme/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_system_healthtest-system-health-after-unload.json ================================================ { "tests/test_system_health.py::test_system_health_after_unload": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_system_healthtest-system-health.json ================================================ { "tests/test_system_health.py::test_system_health": { "https://api.github.com": 1, "https://api.github.com/rate_limit": 1, "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/data.json": 1, "https://github.com/": 1, "https://raw.githubusercontent.com/hacs/integration/main/hacs.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_updatetest-update-entity-state-hacs-test-org-appdaemon-basic.json ================================================ { "tests/test_update.py::test_update_entity_state[hacs-test-org/appdaemon-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 2, "https://data-v2.hacs.xyz/critical/data.json": 2, "https://data-v2.hacs.xyz/integration/data.json": 2, "https://data-v2.hacs.xyz/plugin/data.json": 2, "https://data-v2.hacs.xyz/python_script/data.json": 2, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 2, "https://data-v2.hacs.xyz/theme/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_updatetest-update-entity-state-hacs-test-org-integration-basic.json ================================================ { "tests/test_update.py::test_update_entity_state[hacs-test-org/integration-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 2, "https://data-v2.hacs.xyz/critical/data.json": 2, "https://data-v2.hacs.xyz/integration/data.json": 2, "https://data-v2.hacs.xyz/plugin/data.json": 2, "https://data-v2.hacs.xyz/python_script/data.json": 2, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 2, "https://data-v2.hacs.xyz/theme/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_updatetest-update-entity-state-hacs-test-org-plugin-basic.json ================================================ { "tests/test_update.py::test_update_entity_state[hacs-test-org/plugin-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 2, "https://data-v2.hacs.xyz/critical/data.json": 2, "https://data-v2.hacs.xyz/integration/data.json": 2, "https://data-v2.hacs.xyz/plugin/data.json": 2, "https://data-v2.hacs.xyz/python_script/data.json": 2, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 2, "https://data-v2.hacs.xyz/theme/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_updatetest-update-entity-state-hacs-test-org-python-script-basic.json ================================================ { "tests/test_update.py::test_update_entity_state[hacs-test-org/python_script-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 2, "https://data-v2.hacs.xyz/critical/data.json": 2, "https://data-v2.hacs.xyz/integration/data.json": 2, "https://data-v2.hacs.xyz/plugin/data.json": 2, "https://data-v2.hacs.xyz/python_script/data.json": 2, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 2, "https://data-v2.hacs.xyz/theme/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_updatetest-update-entity-state-hacs-test-org-template-basic.json ================================================ { "tests/test_update.py::test_update_entity_state[hacs-test-org/template-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 2, "https://data-v2.hacs.xyz/critical/data.json": 2, "https://data-v2.hacs.xyz/integration/data.json": 2, "https://data-v2.hacs.xyz/plugin/data.json": 2, "https://data-v2.hacs.xyz/python_script/data.json": 2, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 2, "https://data-v2.hacs.xyz/theme/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/test_updatetest-update-entity-state-hacs-test-org-theme-basic.json ================================================ { "tests/test_update.py::test_update_entity_state[hacs-test-org/theme-basic]": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://data-v2.hacs.xyz/appdaemon/data.json": 2, "https://data-v2.hacs.xyz/critical/data.json": 2, "https://data-v2.hacs.xyz/integration/data.json": 2, "https://data-v2.hacs.xyz/plugin/data.json": 2, "https://data-v2.hacs.xyz/python_script/data.json": 2, "https://data-v2.hacs.xyz/removed/data.json": 1, "https://data-v2.hacs.xyz/template/data.json": 2, "https://data-v2.hacs.xyz/theme/data.json": 2 } } ================================================ FILE: tests/snapshots/api-usage/tests/utils/test_pathtest-is-safe.json ================================================ { "tests/utils/test_path.py::test_is_safe": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/utils/test_queue_managertest-queue-manager.json ================================================ { "tests/utils/test_queue_manager.py::test_queue_manager": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/utils/test_versiontest-version-to-download.json ================================================ { "tests/utils/test_version.py::test_version_to_download": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_async_run_repository_checkstest-async-run-repository-checks.json ================================================ { "tests/validate/test_async_run_repository_checks.py::test_async_run_repository_checks": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://brands.home-assistant.io/domains.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_brands_checktest-added-to-brands.json ================================================ { "tests/validate/test_brands_check.py::test_added_to_brands": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://brands.home-assistant.io/domains.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_brands_checktest-local-brands-asset-content-in-root.json ================================================ { "tests/validate/test_brands_check.py::test_local_brands_asset_content_in_root": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_brands_checktest-local-brands-asset-missing-falls-back-to-remote.json ================================================ { "tests/validate/test_brands_check.py::test_local_brands_asset_missing_falls_back_to_remote": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://brands.home-assistant.io/domains.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_brands_checktest-local-brands-asset-not-in-root.json ================================================ { "tests/validate/test_brands_check.py::test_local_brands_asset_not_in_root": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_brands_checktest-not-added-to-brands.json ================================================ { "tests/validate/test_brands_check.py::test_not_added_to_brands": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1, "https://brands.home-assistant.io/domains.json": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_hacsjson_checktest-hacs-manifest-integration-zip-release-with-filename.json ================================================ { "tests/validate/test_hacsjson_check.py::test_hacs_manifest_integration_zip_release_with_filename": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_hacsjson_checktest-hacs-manifest-no-manifest.json ================================================ { "tests/validate/test_hacsjson_check.py::test_hacs_manifest_no_manifest": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_hacsjson_checktest-hacs-manifest-with-invalid-manifest.json ================================================ { "tests/validate/test_hacsjson_check.py::test_hacs_manifest_with_invalid_manifest": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_hacsjson_checktest-hacs-manifest-with-missing-filename.json ================================================ { "tests/validate/test_hacsjson_check.py::test_hacs_manifest_with_missing_filename": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_hacsjson_checktest-hacs-manifest-with-valid-manifest.json ================================================ { "tests/validate/test_hacsjson_check.py::test_hacs_manifest_with_valid_manifest": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_images_checktest-repository-has-images.json ================================================ { "tests/validate/test_images_check.py::test_repository_has_images": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_images_checktest-repository-has-not-images.json ================================================ { "tests/validate/test_images_check.py::test_repository_has_not_images": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_integration_manifest_checktest-hacs-manifest-with-invalid-manifest.json ================================================ { "tests/validate/test_integration_manifest_check.py::test_hacs_manifest_with_invalid_manifest": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_integration_manifest_checktest-integration-manifest-with-valid-manifest.json ================================================ { "tests/validate/test_integration_manifest_check.py::test_integration_manifest_with_valid_manifest": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_integration_manifest_checktest-integration-no-manifest.json ================================================ { "tests/validate/test_integration_manifest_check.py::test_integration_no_manifest": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_repository_archived_checktest-repository-archived.json ================================================ { "tests/validate/test_repository_archived_check.py::test_repository_archived": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_repository_archived_checktest-repository-not-archived.json ================================================ { "tests/validate/test_repository_archived_check.py::test_repository_not_archived": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_repository_description_checktest-repository-hacs-description.json ================================================ { "tests/validate/test_repository_description_check.py::test_repository_hacs_description": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_repository_description_checktest-repository-no-description.json ================================================ { "tests/validate/test_repository_description_check.py::test_repository_no_description": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_repository_information_file_checktest-has-info-file.json ================================================ { "tests/validate/test_repository_information_file_check.py::test_has_info_file": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_repository_information_file_checktest-has-info-md-file.json ================================================ { "tests/validate/test_repository_information_file_check.py::test_has_info_md_file": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_repository_information_file_checktest-has-readme-file.json ================================================ { "tests/validate/test_repository_information_file_check.py::test_has_readme_file": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_repository_information_file_checktest-has-readme-md-file.json ================================================ { "tests/validate/test_repository_information_file_check.py::test_has_readme_md_file": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_repository_information_file_checktest-no-info-file.json ================================================ { "tests/validate/test_repository_information_file_check.py::test_no_info_file": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_repository_information_file_checktest-no-readme-file.json ================================================ { "tests/validate/test_repository_information_file_check.py::test_no_readme_file": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_repository_issues_checktest-repository-issues-enabled.json ================================================ { "tests/validate/test_repository_issues_check.py::test_repository_issues_enabled": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_repository_issues_checktest-repository-issues-not-enabled.json ================================================ { "tests/validate/test_repository_issues_check.py::test_repository_issues_not_enabled": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_repository_topics_checktest-repository-hacs-topics.json ================================================ { "tests/validate/test_repository_topics_check.py::test_repository_hacs_topics": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/api-usage/tests/validate/test_repository_topics_checktest-repository-no-topics.json ================================================ { "tests/validate/test_repository_topics_check.py::test_repository_no_topics": { "https://api.github.com/repos/hacs/integration": 1, "https://api.github.com/repos/hacs/integration/contents/custom_components/hacs/manifest.json": 1, "https://api.github.com/repos/hacs/integration/contents/hacs.json": 1, "https://api.github.com/repos/hacs/integration/git/trees/main": 1, "https://api.github.com/repos/hacs/integration/releases": 1 } } ================================================ FILE: tests/snapshots/config_flow/test_already_configured.json ================================================ { "description_placeholders": null, "handler": "hacs", "reason": "single_instance_allowed", "type": "abort" } ================================================ FILE: tests/snapshots/config_flow/test_flow_with_activation_failure.json ================================================ { "description_placeholders": null, "handler": "hacs", "reason": "could_not_register", "type": "abort" } ================================================ FILE: tests/snapshots/config_flow/test_flow_with_registration_failure.json ================================================ { "description_placeholders": null, "handler": "hacs", "reason": "could_not_register", "type": "abort" } ================================================ FILE: tests/snapshots/config_flow/test_full_user_flow_implementation.json ================================================ { "context": { "source": "user" }, "data": { "token": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }, "description": null, "description_placeholders": null, "handler": "hacs", "options": { "experimental": true }, "result": { "__type": "", "repr": "" }, "title": "", "type": "create_entry", "version": 1 } ================================================ FILE: tests/snapshots/data_client/base/data/appdaemon.json ================================================ { "1296265": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/appdaemon-basic", "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "manifest": {} } } ================================================ FILE: tests/snapshots/data_client/base/data/integration.json ================================================ { "1296269": { "description": "This your first repo!", "domain": "example", "etag_repository": "321", "full_name": "hacs-test-org/integration-basic", "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "manifest": {}, "manifest_name": "Basic integration" } } ================================================ FILE: tests/snapshots/data_client/base/data/plugin.json ================================================ { "1296267": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/plugin-basic", "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "manifest": {} } } ================================================ FILE: tests/snapshots/data_client/base/data/python_script.json ================================================ { "1296262": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/python_script-basic", "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "manifest": {} } } ================================================ FILE: tests/snapshots/data_client/base/data/template.json ================================================ { "1296268": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/template-basic", "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "manifest": {} } } ================================================ FILE: tests/snapshots/data_client/base/data/theme.json ================================================ { "1296266": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/theme-basic", "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "manifest": {} } } ================================================ FILE: tests/snapshots/data_client/base/data_validate/appdaemon.json ================================================ { "unvalidated": { "12345": { "etag_repository": "blah", "full_name": "blah", "last_commit": "abc", "last_fetched": 0, "last_updated": "blah", "manifest": {} } }, "validated": {} } ================================================ FILE: tests/snapshots/data_client/base/data_validate/critical.json ================================================ { "unvalidated": [ { "reason": "blah", "repository": "test" } ], "validated": [] } ================================================ FILE: tests/snapshots/data_client/base/data_validate/integration.json ================================================ { "unvalidated": { "12345": { "domain": "abc", "etag_repository": "blah", "full_name": "blah", "last_commit": "abc", "last_fetched": 0, "last_updated": "blah", "manifest": {}, "manifest_name": "abc" } }, "validated": {} } ================================================ FILE: tests/snapshots/data_client/base/data_validate/plugin.json ================================================ { "unvalidated": { "12345": { "etag_repository": "blah", "full_name": "blah", "last_commit": "abc", "last_fetched": 0, "last_updated": "blah", "manifest": {} } }, "validated": {} } ================================================ FILE: tests/snapshots/data_client/base/data_validate/python_script.json ================================================ { "unvalidated": { "12345": { "etag_repository": "blah", "full_name": "blah", "last_commit": "abc", "last_fetched": 0, "last_updated": "blah", "manifest": {} } }, "validated": {} } ================================================ FILE: tests/snapshots/data_client/base/data_validate/removed.json ================================================ { "unvalidated": [ { "repository": "test" } ], "validated": [] } ================================================ FILE: tests/snapshots/data_client/base/data_validate/template.json ================================================ { "unvalidated": { "12345": { "etag_repository": "blah", "full_name": "blah", "last_commit": "abc", "last_fetched": 0, "last_updated": "blah", "manifest": {} } }, "validated": {} } ================================================ FILE: tests/snapshots/data_client/base/data_validate/theme.json ================================================ { "unvalidated": { "12345": { "etag_repository": "blah", "full_name": "blah", "last_commit": "abc", "last_fetched": 0, "last_updated": "blah", "manifest": {} } }, "validated": {} } ================================================ FILE: tests/snapshots/data_client/base/repositories/appdaemon.json ================================================ [ "hacs-test-org/appdaemon-basic" ] ================================================ FILE: tests/snapshots/data_client/base/repositories/integration.json ================================================ [ "hacs-test-org/integration-basic" ] ================================================ FILE: tests/snapshots/data_client/base/repositories/plugin.json ================================================ [ "hacs-test-org/plugin-basic" ] ================================================ FILE: tests/snapshots/data_client/base/repositories/python_script.json ================================================ [ "hacs-test-org/python_script-basic" ] ================================================ FILE: tests/snapshots/data_client/base/repositories/template.json ================================================ [ "hacs-test-org/template-basic" ] ================================================ FILE: tests/snapshots/data_client/base/repositories/theme.json ================================================ [ "hacs-test-org/theme-basic" ] ================================================ FILE: tests/snapshots/diagnostics/base.json ================================================ { "custom_repositories": [], "entry": { "data": { "token": "**REDACTED**" }, "disabled_by": null, "domain": "hacs", "options": { "appdaemon": true }, "pref_disable_new_entities": false, "pref_disable_polling": false, "source": "user", "title": "", "unique_id": "12345", "version": 1 }, "hacs": { "archived_repositories": [], "categories": [ "appdaemon", "integration", "plugin", "python_script", "template", "theme" ], "configuration": { "appdaemon": true, "country": "ALL", "debug": false, "dev": true, "python_script": false, "release_limit": 5, "theme": false }, "disabled_reason": null, "ignored_repositories": [], "lovelace_mode": "auto-gen", "new": true, "renamed_repositories": {}, "stage": "running", "startup": false, "version": "0.0.0" }, "rate_limit": { "rate": { "limit": 5000, "remaining": 4999, "reset": 1372700873, "used": 1 }, "resources": { "actions_runner_registration": { "limit": 10000, "remaining": 10000, "reset": 1691594631, "used": 0 }, "code_scanning_upload": { "limit": 500, "remaining": 499, "reset": 1691594631, "used": 1 }, "core": { "limit": 5000, "remaining": 4999, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "remaining": 4993, "reset": 1691593228, "used": 7 }, "integration_manifest": { "limit": 5000, "remaining": 4999, "reset": 1691594631, "used": 1 }, "scim": { "limit": 15000, "remaining": 15000, "reset": 1691594631, "used": 0 }, "search": { "limit": 30, "remaining": 18, "reset": 1691591091, "used": 12 }, "source_import": { "limit": 100, "remaining": 99, "reset": 1691591091, "used": 1 } } }, "repositories": [ { "data": { "archived": false, "authors": [], "category": "integration", "config_flow": false, "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "downloads": 0, "etag_releases": null, "etag_repository": null, "file_name": "", "first_install": false, "full_name": "hacs/integration", "has_issues": true, "hide": false, "id": "172733314", "installed": true, "installed_commit": null, "installed_version": "0.0.0", "last_commit": null, "last_version": null, "manifest_name": "HACS", "new": false, "open_issues": 2, "prerelease": null, "published_tags": [], "releases": true, "selected_tag": null, "show_beta": false, "stargazers_count": 4065, "topics": [ "community", "package-manager" ] }, "integration_manifest": { "domain": "hacs", "name": "HACS" }, "paths": { "localpath": "/config/custom_components/hacs", "remote": "custom_components/hacs" }, "ref": "main", "repository_manifest": { "content_in_root": false, "country": [], "filename": null, "hacs": null, "hide_default_branch": false, "homeassistant": null, "manifest": { "name": "HACS" }, "name": "HACS", "persistent_directory": null, "render_readme": false, "zip_release": false } } ] } ================================================ FILE: tests/snapshots/diagnostics/exception.json ================================================ { "custom_repositories": [], "entry": { "data": { "token": "**REDACTED**" }, "disabled_by": null, "domain": "hacs", "options": { "appdaemon": true }, "pref_disable_new_entities": false, "pref_disable_polling": false, "source": "user", "title": "", "unique_id": "12345", "version": 1 }, "hacs": { "archived_repositories": [], "categories": [ "appdaemon", "integration", "plugin", "python_script", "template", "theme" ], "configuration": { "appdaemon": true, "country": "ALL", "debug": false, "dev": true, "python_script": false, "release_limit": 5, "theme": false }, "disabled_reason": null, "ignored_repositories": [], "lovelace_mode": "auto-gen", "new": true, "renamed_repositories": {}, "stage": "running", "startup": false, "version": "0.0.0" }, "rate_limit": "Something went wrong", "repositories": [ { "data": { "archived": false, "authors": [], "category": "integration", "config_flow": false, "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "downloads": 0, "etag_releases": null, "etag_repository": null, "file_name": "", "first_install": false, "full_name": "hacs/integration", "has_issues": true, "hide": false, "id": "172733314", "installed": true, "installed_commit": null, "installed_version": "0.0.0", "last_commit": null, "last_version": null, "manifest_name": "HACS", "new": false, "open_issues": 2, "prerelease": null, "published_tags": [], "releases": true, "selected_tag": null, "show_beta": false, "stargazers_count": 4065, "topics": [ "community", "package-manager" ] }, "integration_manifest": { "domain": "hacs", "name": "HACS" }, "paths": { "localpath": "/config/custom_components/hacs", "remote": "custom_components/hacs" }, "ref": "main", "repository_manifest": { "content_in_root": false, "country": [], "filename": null, "hacs": null, "hide_default_branch": false, "homeassistant": null, "manifest": { "name": "HACS" }, "name": "HACS", "persistent_directory": null, "render_readme": false, "zip_release": false } } ] } ================================================ FILE: tests/snapshots/hacs-test-org/appdaemon-basic/test_discard_invalid_repo_data.json ================================================ { "_dashboard_resources": [], "_data": { "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/appdaemon-basic/test_download_repository.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "category": "appdaemon", "default_branch": "main", "description": "This your first repo!", "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "name": "Example app" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "1.0.0" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/appdaemon/apps/appdaemon-basic/__init__.py" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "friendly_name": "Example app update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "1.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/appdaemon-basic/releases/1.0.0", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.example_app_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "off", "translation_key": null, "unique_id": "1296265" }, { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/appdaemon-basic/test_get_reposiotry_releases.json ================================================ { "id": 1, "result": [ { "name": "2.0.0", "prerelease": false, "published_at": "2019-02-26T15:02:39Z", "tag": "2.0.0" } ], "success": true, "type": "result" } ================================================ FILE: tests/snapshots/hacs-test-org/appdaemon-basic/test_remove_repository_post.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/appdaemon-basic/test_remove_repository_pre.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "category": "appdaemon", "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265", "installed": true, "last_fetched": 0.0, "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "repository_manifest": {} } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/appdaemon/apps/appdaemon-basic/__init__.py", "/config/appdaemon/apps/appdaemon-basic/example.py" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/appdaemon-basic/test_switch/entity_states.json ================================================ { "switch": { "initial": { "attributes": { "friendly_name": "Appdaemon Basic Pre-release" }, "context": { "parent_id": null, "user_id": null }, "entity_id": "switch.appdaemon_basic_pre_release", "state": "off" }, "updated": { "attributes": { "friendly_name": "Appdaemon Basic Pre-release" }, "context": { "parent_id": null, "user_id": null }, "entity_id": "switch.appdaemon_basic_pre_release", "state": "on" } }, "update": { "initial": { "attributes": { "auto_update": false, "friendly_name": "Appdaemon Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "2.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/appdaemon-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.appdaemon_basic_update", "state": "on" }, "updated": { "attributes": { "auto_update": false, "friendly_name": "Appdaemon Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "3.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/appdaemon-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.appdaemon_basic_update", "state": "on" } } } ================================================ FILE: tests/snapshots/hacs-test-org/appdaemon-basic/test_update_entity_state.json ================================================ { "initial_state": { "attributes": { "auto_update": false, "friendly_name": "Appdaemon Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "1.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/appdaemon-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.appdaemon_basic_update", "state": "off" }, "updated_state": { "attributes": { "auto_update": false, "friendly_name": "Appdaemon Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "2.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/appdaemon-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.appdaemon_basic_update", "state": "on" } } ================================================ FILE: tests/snapshots/hacs-test-org/appdaemon-basic/test_update_repository_entity.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "category": "appdaemon", "default_branch": "main", "description": "This your first repo!", "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "name": "Example app" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "2.0.0" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/appdaemon/apps/appdaemon-basic/__init__.py" ], "_entities": [ { "area_id": null, "attributes": null, "disabled_by": "integration", "entity_category": "diagnostic", "entity_id": "switch.appdaemon_basic_pre_release", "has_entity_name": true, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": null, "translation_key": "pre-release", "unique_id": "1296265" }, { "area_id": null, "attributes": { "auto_update": false, "friendly_name": "Example app update", "in_progress": false, "installed_version": "2.0.0", "latest_version": "1.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/appdaemon-basic/releases/1.0.0", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.appdaemon_basic_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "off", "translation_key": null, "unique_id": "1296265" }, { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" }, { "area_id": null, "attributes": null, "disabled_by": "integration", "entity_category": "diagnostic", "entity_id": "switch.hacs_pre_release", "has_entity_name": true, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": null, "translation_key": "pre-release", "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": false, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/appdaemon-basic/test_update_repository_websocket.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "category": "appdaemon", "default_branch": "main", "description": "This your first repo!", "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "name": "Example app" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "2.0.0" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/appdaemon/apps/appdaemon-basic/__init__.py" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/integration-basic/get_documentation/installed_false_last_version_2_0_0.md ================================================ ## Example readme file (2.0.0) ================================================ FILE: tests/snapshots/hacs-test-org/integration-basic/get_documentation/installed_false_last_version_99_99_99.md ================================================ None ================================================ FILE: tests/snapshots/hacs-test-org/integration-basic/get_documentation/installed_true_installed_version_1_0_0.md ================================================ ## Example readme file (1.0.0) Sorry, your browser does not support inline SVG. ================================================ FILE: tests/snapshots/hacs-test-org/integration-basic/get_documentation/installed_true_installed_version_1_0_0_last_version_2_0_0.md ================================================ ## Example readme file (1.0.0) Sorry, your browser does not support inline SVG. ================================================ FILE: tests/snapshots/hacs-test-org/integration-basic/test_discard_invalid_repo_data.json ================================================ { "_dashboard_resources": [], "_data": { "integration": { "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/integration-basic/test_download_repository.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "category": "integration", "config_flow": true, "default_branch": "main", "description": "This your first repo!", "domain": "example", "downloads": 42, "full_name": "hacs-test-org/integration-basic", "id": "1296269", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest_name": "Proxy manifest", "prerelease": "3.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "1.0.0" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/custom_components/example/manifest.json" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/example/icon.png", "friendly_name": "Proxy manifest update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "1.0.0", "release_summary": "Restart of Home Assistant required", "release_url": "https://github.com/hacs-test-org/integration-basic/releases/1.0.0", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.proxy_manifest_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "off", "translation_key": null, "unique_id": "1296269" }, { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/integration-basic/test_get_reposiotry_releases.json ================================================ { "id": 1, "result": [ { "name": "2.0.0", "prerelease": false, "published_at": "2019-02-26T15:02:39Z", "tag": "2.0.0" } ], "success": true, "type": "result" } ================================================ FILE: tests/snapshots/hacs-test-org/integration-basic/test_remove_repository_post.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/integration-basic/test_remove_repository_pre.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "category": "integration", "description": "This your first repo!", "domain": "example", "etag_repository": "321", "full_name": "hacs-test-org/integration-basic", "id": "1296269", "installed": true, "last_fetched": 0.0, "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "manifest_name": "Basic integration", "repository_manifest": {} }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/custom_components/example/__init__.py", "/config/custom_components/example/manifest.json", "/config/custom_components/example/module/__init__.py" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/integration-basic/test_switch/entity_states.json ================================================ { "switch": { "initial": { "attributes": { "friendly_name": "Basic integration Pre-release" }, "context": { "parent_id": null, "user_id": null }, "entity_id": "switch.basic_integration_pre_release", "state": "off" }, "updated": { "attributes": { "friendly_name": "Basic integration Pre-release" }, "context": { "parent_id": null, "user_id": null }, "entity_id": "switch.basic_integration_pre_release", "state": "on" } }, "update": { "initial": { "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/example/icon.png", "friendly_name": "Basic integration update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "2.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/integration-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.basic_integration_update", "state": "on" }, "updated": { "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/example/icon.png", "friendly_name": "Basic integration update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "3.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/integration-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.basic_integration_update", "state": "on" } } } ================================================ FILE: tests/snapshots/hacs-test-org/integration-basic/test_update_entity_state.json ================================================ { "initial_state": { "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/example/icon.png", "friendly_name": "Basic integration update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "1.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/integration-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.basic_integration_update", "state": "off" }, "updated_state": { "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/example/icon.png", "friendly_name": "Basic integration update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "2.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/integration-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.basic_integration_update", "state": "on" } } ================================================ FILE: tests/snapshots/hacs-test-org/integration-basic/test_update_repository_entity.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "category": "integration", "config_flow": true, "default_branch": "main", "description": "This your first repo!", "domain": "example", "downloads": 42, "full_name": "hacs-test-org/integration-basic", "id": "1296269", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest_name": "Proxy manifest", "prerelease": "3.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "2.0.0" }, "172733314": { "category": "integration", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/custom_components/example/__init__.py", "/config/custom_components/example/manifest.json" ], "_entities": [ { "area_id": null, "attributes": null, "disabled_by": "integration", "entity_category": "diagnostic", "entity_id": "switch.basic_integration_pre_release", "has_entity_name": true, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": null, "translation_key": "pre-release", "unique_id": "1296269" }, { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/example/icon.png", "friendly_name": "Proxy manifest update", "in_progress": false, "installed_version": "2.0.0", "latest_version": "1.0.0", "release_summary": "Restart of Home Assistant required", "release_url": "https://github.com/hacs-test-org/integration-basic/releases/1.0.0", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.basic_integration_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "off", "translation_key": null, "unique_id": "1296269" }, { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" }, { "area_id": null, "attributes": null, "disabled_by": "integration", "entity_category": "diagnostic", "entity_id": "switch.hacs_pre_release", "has_entity_name": true, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": null, "translation_key": "pre-release", "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": false, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/integration-basic/test_update_repository_websocket.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "category": "integration", "config_flow": true, "default_branch": "main", "description": "This your first repo!", "domain": "example", "downloads": 42, "full_name": "hacs-test-org/integration-basic", "id": "1296269", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest_name": "Proxy manifest", "prerelease": "3.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "2.0.0" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/custom_components/example/__init__.py", "/config/custom_components/example/manifest.json" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/integration-basic-custom/test_register_repository.json ================================================ { "additional_info": "", "authors": [], "available_version": "1.0.0", "beta": false, "can_download": true, "category": "integration", "config_flow": false, "country": [], "custom": true, "default_branch": "main", "description": "This your first repo!", "domain": "example", "downloads": 42, "file_name": "", "full_name": "hacs-test-org/integration-basic-custom", "hide_default_branch": false, "homeassistant": null, "id": "91296269", "installed": false, "installed_version": "", "issues": 0, "name": "Proxy manifest", "new": false, "pending_upgrade": false, "ref": "1.0.0", "releases": [ "1.0.0" ], "selected_tag": null, "stars": 80, "state": null, "status": "default", "topics": [ "api", "atom", "electron", "octocat" ], "version_or_commit": "version" } ================================================ FILE: tests/snapshots/hacs-test-org/plugin-basic/test_discard_invalid_repo_data.json ================================================ { "_dashboard_resources": [], "_data": { "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/plugin-basic/test_download_repository.json ================================================ { "_dashboard_resources": [ { "type": "module", "url": "/hacsfiles/plugin-basic/plugin-basic.js?hacstag=1296267100" } ], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "category": "plugin", "default_branch": "main", "description": "This your first repo!", "full_name": "hacs-test-org/plugin-basic", "id": "1296267", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "1.0.0" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/www/community/plugin-basic/plugin-basic.js", "/config/www/community/plugin-basic/plugin-basic.js.gz" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "friendly_name": "Proxy manifest update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "1.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/plugin-basic/releases/1.0.0", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.proxy_manifest_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "off", "translation_key": null, "unique_id": "1296267" }, { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": true, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/plugin-basic/test_get_reposiotry_releases.json ================================================ { "id": 1, "result": [ { "name": "2.0.0", "prerelease": false, "published_at": "2019-02-26T15:02:39Z", "tag": "2.0.0" } ], "success": true, "type": "result" } ================================================ FILE: tests/snapshots/hacs-test-org/plugin-basic/test_remove_repository_post.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/plugin-basic/test_remove_repository_pre.json ================================================ { "_dashboard_resources": [ { "type": "module", "url": "/hacsfiles/plugin-basic/example.js?hacstag=1296267100" } ], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "category": "plugin", "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/plugin-basic", "id": "1296267", "installed": true, "last_fetched": 0.0, "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "repository_manifest": {} } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/www/community/plugin-basic/example.js", "/config/www/community/plugin-basic/example.js.gz" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/plugin-basic/test_switch/entity_states.json ================================================ { "switch": { "initial": { "attributes": { "friendly_name": "Plugin Basic Pre-release" }, "context": { "parent_id": null, "user_id": null }, "entity_id": "switch.plugin_basic_pre_release", "state": "off" }, "updated": { "attributes": { "friendly_name": "Plugin Basic Pre-release" }, "context": { "parent_id": null, "user_id": null }, "entity_id": "switch.plugin_basic_pre_release", "state": "on" } }, "update": { "initial": { "attributes": { "auto_update": false, "friendly_name": "Plugin Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "2.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/plugin-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.plugin_basic_update", "state": "on" }, "updated": { "attributes": { "auto_update": false, "friendly_name": "Plugin Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "3.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/plugin-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.plugin_basic_update", "state": "on" } } } ================================================ FILE: tests/snapshots/hacs-test-org/plugin-basic/test_update_entity_state.json ================================================ { "initial_state": { "attributes": { "auto_update": false, "friendly_name": "Plugin Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "1.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/plugin-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.plugin_basic_update", "state": "off" }, "updated_state": { "attributes": { "auto_update": false, "friendly_name": "Plugin Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "2.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/plugin-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.plugin_basic_update", "state": "on" } } ================================================ FILE: tests/snapshots/hacs-test-org/plugin-basic/test_update_repository_entity.json ================================================ { "_dashboard_resources": [ { "type": "module", "url": "/hacsfiles/plugin-basic/plugin-basic.js?hacstag=1296267200" } ], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "category": "plugin", "default_branch": "main", "description": "This your first repo!", "full_name": "hacs-test-org/plugin-basic", "id": "1296267", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "2.0.0" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/www/community/plugin-basic/plugin-basic.js", "/config/www/community/plugin-basic/plugin-basic.js.gz" ], "_entities": [ { "area_id": null, "attributes": null, "disabled_by": "integration", "entity_category": "diagnostic", "entity_id": "switch.plugin_basic_pre_release", "has_entity_name": true, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": null, "translation_key": "pre-release", "unique_id": "1296267" }, { "area_id": null, "attributes": { "auto_update": false, "friendly_name": "Proxy manifest update", "in_progress": false, "installed_version": "2.0.0", "latest_version": "1.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/plugin-basic/releases/1.0.0", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.plugin_basic_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "off", "translation_key": null, "unique_id": "1296267" }, { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" }, { "area_id": null, "attributes": null, "disabled_by": "integration", "entity_category": "diagnostic", "entity_id": "switch.hacs_pre_release", "has_entity_name": true, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": null, "translation_key": "pre-release", "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": true, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": false, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/plugin-basic/test_update_repository_websocket.json ================================================ { "_dashboard_resources": [ { "type": "module", "url": "/hacsfiles/plugin-basic/plugin-basic.js?hacstag=1296267200" } ], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "category": "plugin", "default_branch": "main", "description": "This your first repo!", "full_name": "hacs-test-org/plugin-basic", "id": "1296267", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "2.0.0" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/www/community/plugin-basic/plugin-basic.js", "/config/www/community/plugin-basic/plugin-basic.js.gz" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": true, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/plugin-custom-dist/test_register_repository.json ================================================ { "additional_info": "", "authors": [], "available_version": "1.0.0", "beta": false, "can_download": true, "category": "plugin", "config_flow": false, "country": [], "custom": true, "default_branch": "main", "description": "This your first repo!", "domain": null, "downloads": 0, "file_name": "plugin-custom-dist.js", "full_name": "hacs-test-org/plugin-custom-dist", "hide_default_branch": false, "homeassistant": null, "id": "12962674", "installed": false, "installed_version": "", "issues": 0, "name": "Proxy manifest", "new": false, "pending_upgrade": false, "ref": "1.0.0", "releases": [ "1.0.0" ], "selected_tag": null, "stars": 80, "state": null, "status": "default", "topics": [ "api", "atom", "electron", "octocat" ], "version_or_commit": "version" } ================================================ FILE: tests/snapshots/hacs-test-org/python_script-basic/test_discard_invalid_repo_data.json ================================================ { "_dashboard_resources": [], "_data": { "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/python_script-basic/test_download_repository.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "category": "python_script", "default_branch": "main", "description": "This your first repo!", "full_name": "hacs-test-org/python_script-basic", "id": "1296262", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "name": "Example app" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "1.0.0" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/python_scripts/example.py" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "friendly_name": "Example app update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "1.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/python_script-basic/releases/1.0.0", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.example_app_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "off", "translation_key": null, "unique_id": "1296262" }, { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/python_script-basic/test_get_reposiotry_releases.json ================================================ { "id": 1, "result": [ { "name": "2.0.0", "prerelease": false, "published_at": "2019-02-26T15:02:39Z", "tag": "2.0.0" } ], "success": true, "type": "result" } ================================================ FILE: tests/snapshots/hacs-test-org/python_script-basic/test_remove_repository_post.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/python_script-basic/test_remove_repository_pre.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "category": "python_script", "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/python_script-basic", "id": "1296262", "installed": true, "last_fetched": 0.0, "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "repository_manifest": {} } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/python_scripts/example.py" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/python_script-basic/test_switch/entity_states.json ================================================ { "switch": { "initial": { "attributes": { "friendly_name": "Python Script Basic Pre-release" }, "context": { "parent_id": null, "user_id": null }, "entity_id": "switch.python_script_basic_pre_release", "state": "off" }, "updated": { "attributes": { "friendly_name": "Python Script Basic Pre-release" }, "context": { "parent_id": null, "user_id": null }, "entity_id": "switch.python_script_basic_pre_release", "state": "on" } }, "update": { "initial": { "attributes": { "auto_update": false, "friendly_name": "Python Script Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "2.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/python_script-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.python_script_basic_update", "state": "on" }, "updated": { "attributes": { "auto_update": false, "friendly_name": "Python Script Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "3.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/python_script-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.python_script_basic_update", "state": "on" } } } ================================================ FILE: tests/snapshots/hacs-test-org/python_script-basic/test_update_entity_state.json ================================================ { "initial_state": { "attributes": { "auto_update": false, "friendly_name": "Python Script Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "1.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/python_script-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.python_script_basic_update", "state": "off" }, "updated_state": { "attributes": { "auto_update": false, "friendly_name": "Python Script Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "2.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/python_script-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.python_script_basic_update", "state": "on" } } ================================================ FILE: tests/snapshots/hacs-test-org/python_script-basic/test_update_repository_entity.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "category": "python_script", "default_branch": "main", "description": "This your first repo!", "full_name": "hacs-test-org/python_script-basic", "id": "1296262", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "name": "Example app" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "2.0.0" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/python_scripts/example.py" ], "_entities": [ { "area_id": null, "attributes": null, "disabled_by": "integration", "entity_category": "diagnostic", "entity_id": "switch.python_script_basic_pre_release", "has_entity_name": true, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": null, "translation_key": "pre-release", "unique_id": "1296262" }, { "area_id": null, "attributes": { "auto_update": false, "friendly_name": "Example app update", "in_progress": false, "installed_version": "2.0.0", "latest_version": "1.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/python_script-basic/releases/1.0.0", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.python_script_basic_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "off", "translation_key": null, "unique_id": "1296262" }, { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" }, { "area_id": null, "attributes": null, "disabled_by": "integration", "entity_category": "diagnostic", "entity_id": "switch.hacs_pre_release", "has_entity_name": true, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": null, "translation_key": "pre-release", "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": false, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/python_script-basic/test_update_repository_websocket.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "category": "python_script", "default_branch": "main", "description": "This your first repo!", "full_name": "hacs-test-org/python_script-basic", "id": "1296262", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "name": "Example app" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "2.0.0" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/python_scripts/example.py" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/template-basic/test_discard_invalid_repo_data.json ================================================ { "_dashboard_resources": [], "_data": { "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/template-basic/test_download_repository.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "category": "template", "default_branch": "main", "description": "This your first repo!", "downloads": 42, "full_name": "hacs-test-org/template-basic", "id": "1296268", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "filename": "example.jinja", "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "1.0.0" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/custom_templates/example.jinja" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "friendly_name": "Proxy manifest update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "1.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/template-basic/releases/1.0.0", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.proxy_manifest_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "off", "translation_key": null, "unique_id": "1296268" }, { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/template-basic/test_get_reposiotry_releases.json ================================================ { "id": 1, "result": [ { "name": "2.0.0", "prerelease": false, "published_at": "2019-02-26T15:02:39Z", "tag": "2.0.0" } ], "success": true, "type": "result" } ================================================ FILE: tests/snapshots/hacs-test-org/template-basic/test_remove_repository_post.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/template-basic/test_remove_repository_pre.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "category": "template", "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/template-basic", "id": "1296268", "installed": true, "last_fetched": 0.0, "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "repository_manifest": {} } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/custom_templates/example.jinja" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/template-basic/test_switch/entity_states.json ================================================ { "switch": { "initial": { "attributes": { "friendly_name": "Template Basic Pre-release" }, "context": { "parent_id": null, "user_id": null }, "entity_id": "switch.template_basic_pre_release", "state": "off" }, "updated": { "attributes": { "friendly_name": "Template Basic Pre-release" }, "context": { "parent_id": null, "user_id": null }, "entity_id": "switch.template_basic_pre_release", "state": "on" } }, "update": { "initial": { "attributes": { "auto_update": false, "friendly_name": "Template Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "2.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/template-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.template_basic_update", "state": "on" }, "updated": { "attributes": { "auto_update": false, "friendly_name": "Template Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "3.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/template-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.template_basic_update", "state": "on" } } } ================================================ FILE: tests/snapshots/hacs-test-org/template-basic/test_update_entity_state.json ================================================ { "initial_state": { "attributes": { "auto_update": false, "friendly_name": "Template Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "1.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/template-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.template_basic_update", "state": "off" }, "updated_state": { "attributes": { "auto_update": false, "friendly_name": "Template Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "2.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/template-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.template_basic_update", "state": "on" } } ================================================ FILE: tests/snapshots/hacs-test-org/template-basic/test_update_repository_entity.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "category": "template", "default_branch": "main", "description": "This your first repo!", "downloads": 42, "full_name": "hacs-test-org/template-basic", "id": "1296268", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "filename": "example.jinja", "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "2.0.0" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/custom_templates/example.jinja" ], "_entities": [ { "area_id": null, "attributes": null, "disabled_by": "integration", "entity_category": "diagnostic", "entity_id": "switch.template_basic_pre_release", "has_entity_name": true, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": null, "translation_key": "pre-release", "unique_id": "1296268" }, { "area_id": null, "attributes": { "auto_update": false, "friendly_name": "Proxy manifest update", "in_progress": false, "installed_version": "2.0.0", "latest_version": "1.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/template-basic/releases/1.0.0", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.template_basic_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "off", "translation_key": null, "unique_id": "1296268" }, { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" }, { "area_id": null, "attributes": null, "disabled_by": "integration", "entity_category": "diagnostic", "entity_id": "switch.hacs_pre_release", "has_entity_name": true, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": null, "translation_key": "pre-release", "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": false, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/template-basic/test_update_repository_websocket.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "category": "template", "default_branch": "main", "description": "This your first repo!", "downloads": 42, "full_name": "hacs-test-org/template-basic", "id": "1296268", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "filename": "example.jinja", "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "2.0.0" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [ "/config/custom_templates/example.jinja" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/theme-basic/test_discard_invalid_repo_data.json ================================================ { "_dashboard_resources": [], "_data": { "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } } }, "_directory": [], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/theme-basic/test_download_repository.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "category": "theme", "default_branch": "main", "description": "This your first repo!", "full_name": "hacs-test-org/theme-basic", "id": "1296266", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "filename": "example.jinja", "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "1.0.0" } } }, "_directory": [ "/config/themes/example/example.yaml" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "friendly_name": "Proxy manifest update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "1.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/theme-basic/releases/1.0.0", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.proxy_manifest_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "off", "translation_key": null, "unique_id": "1296266" }, { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/theme-basic/test_get_reposiotry_releases.json ================================================ { "id": 1, "result": [ { "name": "2.0.0", "prerelease": false, "published_at": "2019-02-26T15:02:39Z", "tag": "2.0.0" } ], "success": true, "type": "result" } ================================================ FILE: tests/snapshots/hacs-test-org/theme-basic/test_remove_repository_post.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/theme-basic/test_remove_repository_pre.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "category": "theme", "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/theme-basic", "id": "1296266", "installed": true, "last_fetched": 0.0, "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "repository_manifest": {} } } }, "_directory": [ "/config/themes/example/example.yaml" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/theme-basic/test_switch/entity_states.json ================================================ { "switch": { "initial": { "attributes": { "friendly_name": "Theme Basic Pre-release" }, "context": { "parent_id": null, "user_id": null }, "entity_id": "switch.theme_basic_pre_release", "state": "off" }, "updated": { "attributes": { "friendly_name": "Theme Basic Pre-release" }, "context": { "parent_id": null, "user_id": null }, "entity_id": "switch.theme_basic_pre_release", "state": "on" } }, "update": { "initial": { "attributes": { "auto_update": false, "friendly_name": "Theme Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "2.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/theme-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.theme_basic_update", "state": "on" }, "updated": { "attributes": { "auto_update": false, "friendly_name": "Theme Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "3.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/theme-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.theme_basic_update", "state": "on" } } } ================================================ FILE: tests/snapshots/hacs-test-org/theme-basic/test_update_entity_state.json ================================================ { "initial_state": { "attributes": { "auto_update": false, "friendly_name": "Theme Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "1.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/theme-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.theme_basic_update", "state": "off" }, "updated_state": { "attributes": { "auto_update": false, "friendly_name": "Theme Basic update", "in_progress": false, "installed_version": "1.0.0", "latest_version": "2.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/theme-basic", "skipped_version": null, "supported_features": 23, "title": null }, "context": { "parent_id": null, "user_id": null }, "entity_id": "update.theme_basic_update", "state": "on" } } ================================================ FILE: tests/snapshots/hacs-test-org/theme-basic/test_update_repository_entity.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "category": "theme", "default_branch": "main", "description": "This your first repo!", "full_name": "hacs-test-org/theme-basic", "id": "1296266", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "filename": "example.jinja", "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "2.0.0" } } }, "_directory": [ "/config/themes/example/example.yaml" ], "_entities": [ { "area_id": null, "attributes": null, "disabled_by": "integration", "entity_category": "diagnostic", "entity_id": "switch.theme_basic_pre_release", "has_entity_name": true, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": null, "translation_key": "pre-release", "unique_id": "1296266" }, { "area_id": null, "attributes": { "auto_update": false, "friendly_name": "Proxy manifest update", "in_progress": false, "installed_version": "2.0.0", "latest_version": "1.0.0", "release_summary": null, "release_url": "https://github.com/hacs-test-org/theme-basic/releases/1.0.0", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.theme_basic_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "off", "translation_key": null, "unique_id": "1296266" }, { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" }, { "area_id": null, "attributes": null, "disabled_by": "integration", "entity_category": "diagnostic", "entity_id": "switch.hacs_pre_release", "has_entity_name": true, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": null, "translation_key": "pre-release", "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": false, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/hacs-test-org/theme-basic/test_update_repository_websocket.json ================================================ { "_dashboard_resources": [], "_data": { "appdaemon": { "1296265": { "full_name": "hacs-test-org/appdaemon-basic", "id": "1296265" } }, "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "category": "theme", "default_branch": "main", "description": "This your first repo!", "full_name": "hacs-test-org/theme-basic", "id": "1296266", "installed": true, "installed_commit": "7fd1a60", "last_commit": "7fd1a60", "last_fetched": 1551193359.0, "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "published_tags": [ "1.0.0" ], "releases": true, "repository_manifest": { "filename": "example.jinja", "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ], "version_installed": "2.0.0" } } }, "_directory": [ "/config/themes/example/example.yaml" ], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/appdaemon/data.json ================================================ { "1296265": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/appdaemon-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Example app" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/appdaemon/repositories.json ================================================ [ "hacs-test-org/appdaemon-basic" ] ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/appdaemon/summary.json ================================================ { "changed": 1, "changed_pct": 100, "current_count": 0, "diff": 1, "new_count": 1, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/integration/data.json ================================================ { "1296269": { "description": "This your first repo!", "domain": "example", "downloads": 42, "etag_repository": "321", "full_name": "hacs-test-org/integration-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "manifest_name": "Proxy manifest", "prerelease": "3.0.0", "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] }, "91296269": { "description": "This your first repo!", "domain": "example", "downloads": 42, "etag_repository": "321", "full_name": "hacs-test-org/integration-basic-custom", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "manifest_name": "Proxy manifest", "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/integration/repositories.json ================================================ [ "hacs-test-org/integration-basic", "hacs-test-org/integration-basic-custom" ] ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/integration/summary.json ================================================ { "changed": 2, "changed_pct": 100, "current_count": 0, "diff": 2, "new_count": 2, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/plugin/data.json ================================================ { "1296267": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/plugin-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/plugin/repositories.json ================================================ [ "hacs-test-org/plugin-basic" ] ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/plugin/summary.json ================================================ { "changed": 1, "changed_pct": 100, "current_count": 0, "diff": 1, "new_count": 1, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/python_script/data.json ================================================ { "1296262": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/python_script-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Example app" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/python_script/repositories.json ================================================ [ "hacs-test-org/python_script-basic" ] ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/python_script/summary.json ================================================ { "changed": 1, "changed_pct": 100, "current_count": 0, "diff": 1, "new_count": 1, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/appdaemon/hacs-test-org/appdaemon-basic/data.json ================================================ { "1296265": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/appdaemon-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Example app" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/appdaemon/hacs-test-org/appdaemon-basic/repositories.json ================================================ [ "hacs-test-org/appdaemon-basic" ] ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/appdaemon/hacs-test-org/appdaemon-basic/summary.json ================================================ { "changed": 1, "changed_pct": 100, "current_count": 0, "diff": 1, "new_count": 1, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/integration/hacs-test-org/integration-basic/data.json ================================================ { "1296269": { "description": "This your first repo!", "domain": "example", "downloads": 42, "etag_repository": "321", "full_name": "hacs-test-org/integration-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "manifest_name": "Proxy manifest", "prerelease": "3.0.0", "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/integration/hacs-test-org/integration-basic/repositories.json ================================================ [ "hacs-test-org/integration-basic" ] ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/integration/hacs-test-org/integration-basic/summary.json ================================================ { "changed": 1, "changed_pct": 100, "current_count": 0, "diff": 1, "new_count": 1, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/plugin/hacs-test-org/plugin-basic/data.json ================================================ { "1296267": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/plugin-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/plugin/hacs-test-org/plugin-basic/repositories.json ================================================ [ "hacs-test-org/plugin-basic" ] ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/plugin/hacs-test-org/plugin-basic/summary.json ================================================ { "changed": 1, "changed_pct": 100, "current_count": 0, "diff": 1, "new_count": 1, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/python_script/hacs-test-org/python_script-basic/data.json ================================================ { "1296262": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/python_script-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Example app" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/python_script/hacs-test-org/python_script-basic/repositories.json ================================================ [ "hacs-test-org/python_script-basic" ] ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/python_script/hacs-test-org/python_script-basic/summary.json ================================================ { "changed": 1, "changed_pct": 100, "current_count": 0, "diff": 1, "new_count": 1, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/template/hacs-test-org/template-basic/data.json ================================================ { "1296268": { "description": "This your first repo!", "downloads": 42, "etag_repository": "321", "full_name": "hacs-test-org/template-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/template/hacs-test-org/template-basic/repositories.json ================================================ [ "hacs-test-org/template-basic" ] ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/template/hacs-test-org/template-basic/summary.json ================================================ { "changed": 1, "changed_pct": 100, "current_count": 0, "diff": 1, "new_count": 1, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/theme/hacs-test-org/theme-basic/data.json ================================================ { "1296266": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/theme-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/theme/hacs-test-org/theme-basic/repositories.json ================================================ [ "hacs-test-org/theme-basic" ] ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/single/theme/hacs-test-org/theme-basic/summary.json ================================================ { "changed": 1, "changed_pct": 100, "current_count": 0, "diff": 1, "new_count": 1, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/template/data.json ================================================ { "1296268": { "description": "This your first repo!", "downloads": 42, "etag_repository": "321", "full_name": "hacs-test-org/template-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/template/repositories.json ================================================ [ "hacs-test-org/template-basic" ] ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/template/summary.json ================================================ { "changed": 1, "changed_pct": 100, "current_count": 0, "diff": 1, "new_count": 1, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/theme/data.json ================================================ { "1296266": { "description": "This your first repo!", "etag_repository": "321", "full_name": "hacs-test-org/theme-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } } ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/theme/repositories.json ================================================ [ "hacs-test-org/theme-basic" ] ================================================ FILE: tests/snapshots/scripts/data/generate_category_data/theme/summary.json ================================================ { "changed": 1, "changed_pct": 100, "current_count": 0, "diff": 1, "new_count": 1, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } ================================================ FILE: tests/snapshots/scripts/data/test_generate_category_data_error_status_release/integration/304.json ================================================ { "data": { "1296269": { "description": "This your first repo!", "domain": "example", "etag_repository": "321", "full_name": "hacs-test-org/integration-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "manifest_name": "Proxy manifest", "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] }, "91296269": { "description": "This your first repo!", "domain": "example", "downloads": 42, "etag_repository": "321", "full_name": "hacs-test-org/integration-basic-custom", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "manifest_name": "Proxy manifest", "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } }, "repositories": [ "hacs-test-org/integration-basic", "hacs-test-org/integration-basic-custom" ], "summary": { "changed": 2, "changed_pct": 100, "current_count": 1, "diff": 1, "new_count": 2, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } } ================================================ FILE: tests/snapshots/scripts/data/test_generate_category_data_error_status_release/integration/404.json ================================================ { "data": { "1296269": { "description": "This your first repo!", "domain": "example", "downloads": 42, "etag_repository": "321", "full_name": "hacs-test-org/integration-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "manifest_name": "Proxy manifest", "prerelease": "3.0.0", "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] }, "91296269": { "description": "This your first repo!", "domain": "example", "downloads": 42, "etag_repository": "321", "full_name": "hacs-test-org/integration-basic-custom", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "manifest_name": "Proxy manifest", "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } }, "repositories": [ "hacs-test-org/integration-basic", "hacs-test-org/integration-basic-custom" ], "summary": { "changed": 2, "changed_pct": 100, "current_count": 1, "diff": 1, "new_count": 2, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } } ================================================ FILE: tests/snapshots/scripts/data/test_generate_category_data_errors_release/integration/CancelledError.json ================================================ { "data": { "1296269": { "description": "This your first repo!", "domain": "example", "downloads": 42, "etag_repository": "321", "full_name": "hacs-test-org/integration-basic", "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "manifest": {}, "manifest_name": "Basic integration", "prerelease": "3.0.0", "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] }, "91296269": { "description": "This your first repo!", "domain": "example", "downloads": 42, "etag_repository": "321", "full_name": "hacs-test-org/integration-basic-custom", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "manifest_name": "Proxy manifest", "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } }, "repositories": [ "hacs-test-org/integration-basic", "hacs-test-org/integration-basic-custom" ], "summary": { "changed": 2, "changed_pct": 100, "current_count": 1, "diff": 1, "new_count": 2, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } } ================================================ FILE: tests/snapshots/scripts/data/test_generate_category_data_errors_release/integration/TimeoutError.json ================================================ { "data": { "1296269": { "description": "This your first repo!", "domain": "example", "downloads": 42, "etag_repository": "321", "full_name": "hacs-test-org/integration-basic", "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "manifest": {}, "manifest_name": "Basic integration", "prerelease": "3.0.0", "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] }, "91296269": { "description": "This your first repo!", "domain": "example", "downloads": 42, "etag_repository": "321", "full_name": "hacs-test-org/integration-basic-custom", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "manifest_name": "Proxy manifest", "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } }, "repositories": [ "hacs-test-org/integration-basic", "hacs-test-org/integration-basic-custom" ], "summary": { "changed": 2, "changed_pct": 100, "current_count": 1, "diff": 1, "new_count": 2, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } } ================================================ FILE: tests/snapshots/scripts/data/test_generate_category_data_errors_release/integration/error2.json ================================================ { "data": { "1296269": { "description": "This your first repo!", "domain": "example", "downloads": 42, "etag_repository": "321", "full_name": "hacs-test-org/integration-basic", "last_updated": "2020-01-20T09:34:52Z", "last_version": "1.0.0", "manifest": {}, "manifest_name": "Basic integration", "prerelease": "3.0.0", "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] }, "91296269": { "description": "This your first repo!", "domain": "example", "downloads": 42, "etag_repository": "321", "full_name": "hacs-test-org/integration-basic-custom", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "manifest_name": "Proxy manifest", "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } }, "repositories": [ "hacs-test-org/integration-basic", "hacs-test-org/integration-basic-custom" ], "summary": { "changed": 2, "changed_pct": 100, "current_count": 1, "diff": 1, "new_count": 2, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } } ================================================ FILE: tests/snapshots/scripts/data/test_generate_category_data_with_30plus_prereleases/integration.json ================================================ { "data": { "1296269": { "description": "This your first repo!", "domain": "example", "downloads": 42, "etag_repository": "321", "full_name": "hacs-test-org/integration-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "manifest_name": "Proxy manifest", "prerelease": "3.0.0", "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] }, "91296269": { "description": "This your first repo!", "domain": "example", "downloads": 42, "etag_repository": "321", "full_name": "hacs-test-org/integration-basic-custom", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "manifest_name": "Proxy manifest", "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } }, "repositories": [ "hacs-test-org/integration-basic", "hacs-test-org/integration-basic-custom" ], "summary": { "changed": 2, "changed_pct": 100, "current_count": 1, "diff": 1, "new_count": 2, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } } ================================================ FILE: tests/snapshots/scripts/data/test_generate_category_data_with_prior_content/appdaemon.json ================================================ { "data": { "1296265": { "description": "This your first repo!", "etag_releases": "321", "etag_repository": "321", "full_name": "hacs-test-org/appdaemon-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": {}, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } }, "repositories": [ "hacs-test-org/appdaemon-basic" ], "summary": { "changed": 1, "changed_pct": 100, "current_count": 1, "diff": 0, "new_count": 1, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } } ================================================ FILE: tests/snapshots/scripts/data/test_generate_category_data_with_prior_content/integration.json ================================================ { "data": { "1296269": { "description": "This your first repo!", "domain": "example", "downloads": 42, "etag_releases": "321", "etag_repository": "321", "full_name": "hacs-test-org/integration-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "manifest_name": "Proxy manifest", "prerelease": "3.0.0", "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] }, "91296269": { "description": "This your first repo!", "domain": "example", "downloads": 42, "etag_repository": "321", "full_name": "hacs-test-org/integration-basic-custom", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": { "name": "Proxy manifest" }, "manifest_name": "Proxy manifest", "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } }, "repositories": [ "hacs-test-org/integration-basic", "hacs-test-org/integration-basic-custom" ], "summary": { "changed": 2, "changed_pct": 100, "current_count": 1, "diff": 1, "new_count": 2, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } } ================================================ FILE: tests/snapshots/scripts/data/test_generate_category_data_with_prior_content/plugin.json ================================================ { "data": { "1296267": { "description": "This your first repo!", "etag_releases": "321", "etag_repository": "321", "full_name": "hacs-test-org/plugin-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": {}, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } }, "repositories": [ "hacs-test-org/plugin-basic" ], "summary": { "changed": 1, "changed_pct": 100, "current_count": 1, "diff": 0, "new_count": 1, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } } ================================================ FILE: tests/snapshots/scripts/data/test_generate_category_data_with_prior_content/python_script.json ================================================ { "data": { "1296262": { "description": "This your first repo!", "etag_releases": "321", "etag_repository": "321", "full_name": "hacs-test-org/python_script-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": {}, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } }, "repositories": [ "hacs-test-org/python_script-basic" ], "summary": { "changed": 1, "changed_pct": 100, "current_count": 1, "diff": 0, "new_count": 1, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } } ================================================ FILE: tests/snapshots/scripts/data/test_generate_category_data_with_prior_content/template.json ================================================ { "data": { "1296268": { "description": "This your first repo!", "downloads": 42, "etag_releases": "321", "etag_repository": "321", "full_name": "hacs-test-org/template-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": {}, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } }, "repositories": [ "hacs-test-org/template-basic" ], "summary": { "changed": 1, "changed_pct": 100, "current_count": 1, "diff": 0, "new_count": 1, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } } ================================================ FILE: tests/snapshots/scripts/data/test_generate_category_data_with_prior_content/theme.json ================================================ { "data": { "1296266": { "description": "This your first repo!", "etag_releases": "321", "etag_repository": "321", "full_name": "hacs-test-org/theme-basic", "last_updated": "2011-01-26T19:06:43Z", "last_version": "1.0.0", "manifest": {}, "stargazers_count": 80, "topics": [ "api", "atom", "electron", "octocat" ] } }, "repositories": [ "hacs-test-org/theme-basic" ], "summary": { "changed": 1, "changed_pct": 100, "current_count": 1, "diff": 0, "new_count": 1, "rate_limit": { "core": { "limit": 5000, "reset": 1691591363, "used": 1 }, "graphql": { "limit": 5000, "reset": 1691593228, "used": 7 } } } } ================================================ FILE: tests/snapshots/system_health/system_health.json ================================================ { "Available Repositories": 7, "Downloaded Repositories": 1, "GitHub API": "ok", "GitHub API Calls Remaining": 4999, "GitHub Content": "ok", "GitHub Web": "ok", "HACS Data": "ok", "Installed Version": "0.0.0", "Stage": "running" } ================================================ FILE: tests/snapshots/system_health/system_health_after_unload.json ================================================ { "Disabled": "HACS is not loaded, but HA still requests this information..." } ================================================ FILE: tests/snapshots/test_integration_setup.json ================================================ { "_dashboard_resources": [], "_data": { "integration": { "1296269": { "full_name": "hacs-test-org/integration-basic", "id": "1296269" }, "172733314": { "category": "integration", "default_branch": "main", "description": "HACS gives you a powerful UI to handle downloads of all your custom needs.", "domain": "hacs", "full_name": "hacs/integration", "id": "172733314", "installed": true, "last_fetched": 1551193359.0, "last_updated": "2023-11-18T21:22:03Z", "manifest_name": "HACS", "open_issues": 2, "releases": true, "repository_manifest": { "name": "HACS" }, "stargazers_count": 4065, "topics": [ "community", "package-manager" ], "version_installed": "0.0.0" } }, "plugin": { "1296267": { "full_name": "hacs-test-org/plugin-basic", "id": "1296267" } }, "python_script": { "1296262": { "full_name": "hacs-test-org/python_script-basic", "id": "1296262" } }, "template": { "1296268": { "full_name": "hacs-test-org/template-basic", "id": "1296268" } }, "theme": { "1296266": { "full_name": "hacs-test-org/theme-basic", "id": "1296266" } } }, "_directory": [], "_entities": [ { "area_id": null, "attributes": { "auto_update": false, "entity_picture": "https://brands.home-assistant.io/_/hacs/icon.png", "friendly_name": "HACS update", "in_progress": false, "installed_version": "0.0.0", "latest_version": "", "release_summary": null, "release_url": "https://github.com/hacs/integration/releases/", "skipped_version": null, "supported_features": 23, "title": null }, "disabled_by": null, "entity_category": "config", "entity_id": "update.hacs_update", "has_entity_name": false, "hidden_by": null, "icon": null, "name": null, "options": {}, "platform": "hacs", "state": "on", "translation_key": null, "unique_id": "172733314" } ], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": "running", "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": true, "new": true, "startup": false }, "system": { "action": false, "disabled_reason": null, "generator": false, "running": true } }, "websocket_commands": [ "hacs/critical/acknowledge", "hacs/critical/list", "hacs/info", "hacs/repositories/add", "hacs/repositories/clear_new", "hacs/repositories/list", "hacs/repositories/remove", "hacs/repositories/removed", "hacs/repository/beta", "hacs/repository/download", "hacs/repository/ignore", "hacs/repository/info", "hacs/repository/refresh", "hacs/repository/release_notes", "hacs/repository/releases", "hacs/repository/remove", "hacs/repository/state", "hacs/repository/version", "hacs/subscribe" ] } ================================================ FILE: tests/snapshots/test_integration_setup_with_custom_updater.json ================================================ { "_dashboard_resources": [], "_data": {}, "_directory": [], "_entities": [], "_hacs": { "configuration": { "debug": false, "dev": true }, "stage": null, "status": { "active_frontend_endpoint_plugin": false, "active_frontend_endpoint_theme": false, "inital_fetch_done": false, "new": false, "startup": true }, "system": { "action": false, "disabled_reason": "constrains", "generator": false, "running": true } } } ================================================ FILE: tests/test_config_flow.py ================================================ import asyncio from collections.abc import Generator from unittest.mock import patch from aiogithubapi import GitHubException from freezegun.api import FrozenDateTimeFactory from homeassistant import config_entries from homeassistant.const import CONF_ACCESS_TOKEN from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType, UnknownFlow import pytest from custom_components.hacs.const import DOMAIN from tests.common import ( TOKEN, MockedResponse, ResponseMocker, create_config_entry, get_hacs, recursive_remove_key, safe_json_dumps, ) from tests.conftest import SnapshotFixture @pytest.fixture def _mock_setup_entry(hass: HomeAssistant) -> Generator[None, None, None]: """Mock setting up a config entry.""" hass.data.pop("custom_components", None) with patch("custom_components.hacs.async_setup_entry", return_value=True): yield async def test_full_user_flow_implementation( time_freezer: FrozenDateTimeFactory, hass: HomeAssistant, _mock_setup_entry: None, response_mocker: ResponseMocker, snapshots: SnapshotFixture, check_report_issue: None, ) -> None: """Test the full manual user flow from start to finish.""" response_mocker.add( url="https://github.com/login/device/code", response=MockedResponse( content={ "device_code": "3584d83530557fdd1f46af8289938c8ef79f9dc5", "user_code": "WDJB-MJHT", "verification_uri": "https://github.com/login/device", "expires_in": 900, "interval": 5, }, headers={"Content-Type": "application/json"}, ), ) access_token_responses = [ # User has not yet entered the code {"error": "authorization_pending"}, # User enters the code {CONF_ACCESS_TOKEN: TOKEN, "token_type": "bearer", "scope": ""}, ] async def json(**kwargs): return access_token_responses.pop(0) response_mocker.add( url="https://github.com/login/oauth/access_token", response=MockedResponse( json=json, headers={"Content-Type": "application/json"}, keep=True), ) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER}, ) assert result["step_id"] == "user" assert result["type"] == FlowResultType.FORM result = await hass.config_entries.flow.async_configure( result["flow_id"], user_input={ "acc_logs": True, "acc_addons": True, "acc_untested": True, "acc_disable": False, }, ) assert result["errors"] == {"base": "acc"} result = await hass.config_entries.flow.async_configure( result["flow_id"], user_input={ "acc_logs": True, "acc_addons": True, "acc_untested": True, "acc_disable": True, }, ) assert result["step_id"] == "device" assert result["type"] == FlowResultType.SHOW_PROGRESS time_freezer.tick(10) await hass.async_block_till_done() result = await hass.config_entries.flow.async_configure(result["flow_id"]) assert result["type"] == FlowResultType.CREATE_ENTRY snapshots.assert_match( safe_json_dumps(recursive_remove_key( result, ("flow_id", "minor_version", "subentries"))), "config_flow/test_full_user_flow_implementation.json", ) async def test_flow_with_remove_while_activating( hass: HomeAssistant, _mock_setup_entry: None, response_mocker: ResponseMocker, check_report_issue: None, ) -> None: """Test flow with user canceling while activating.""" response_mocker.add( url="https://github.com/login/device/code", response=MockedResponse( content={ "device_code": "3584d83530557fdd1f46af8289938c8ef79f9dc5", "user_code": "WDJB-MJHT", "verification_uri": "https://github.com/login/device", "expires_in": 900, "interval": 5, }, headers={"Content-Type": "application/json"}, ), ) access_token_event = asyncio.Event() async def json(**kwargs): access_token_event.set() return {"error": "authorization_pending"} response_mocker.add( url="https://github.com/login/oauth/access_token", response=MockedResponse( json=json, headers={"Content-Type": "application/json"}, keep=True), ) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER}, ) assert result["step_id"] == "user" assert result["type"] == FlowResultType.FORM result = await hass.config_entries.flow.async_configure( result["flow_id"], user_input={ "acc_logs": True, "acc_addons": True, "acc_untested": True, "acc_disable": True, }, ) assert result["step_id"] == "device" assert result["type"] == FlowResultType.SHOW_PROGRESS # Wait for access token request await access_token_event.wait() assert hass.config_entries.flow.async_get(result["flow_id"]) # Simulate user canceling the flow hass.config_entries.flow._async_remove_flow_progress(result["flow_id"]) await hass.async_block_till_done() with pytest.raises(UnknownFlow): hass.config_entries.flow.async_get(result["flow_id"]) async def test_flow_with_registration_failure( hass: HomeAssistant, _mock_setup_entry: None, response_mocker: ResponseMocker, snapshots: SnapshotFixture, check_report_issue: None, ) -> None: """Test flow with registration failure of the device.""" response_mocker.add( url="https://github.com/login/device/code", response=MockedResponse( exception=GitHubException("Registration failed")), ) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER}, ) assert result["step_id"] == "user" assert result["type"] == FlowResultType.FORM result = await hass.config_entries.flow.async_configure( result["flow_id"], user_input={ "acc_logs": True, "acc_addons": True, "acc_untested": True, "acc_disable": True, }, ) await hass.async_block_till_done() assert result["type"] == FlowResultType.ABORT snapshots.assert_match( safe_json_dumps(recursive_remove_key( result, ("flow_id", "minor_version"))), "config_flow/test_flow_with_registration_failure.json", ) async def test_flow_with_activation_failure( time_freezer: FrozenDateTimeFactory, hass: HomeAssistant, _mock_setup_entry: None, response_mocker: ResponseMocker, snapshots: SnapshotFixture, check_report_issue: None, ) -> None: """Test flow with activation failure of the device.""" response_mocker.add( url="https://github.com/login/device/code", response=MockedResponse( content={ "device_code": "3584d83530557fdd1f46af8289938c8ef79f9dc5", "user_code": "WDJB-MJHT", "verification_uri": "https://github.com/login/device", "expires_in": 900, "interval": 5, }, headers={"Content-Type": "application/json"}, ), ) def raise_github_exception() -> None: raise GitHubException("Activation failed") access_token_responses = [ # User has not yet entered the code lambda: {"error": "authorization_pending"}, # Activation fails raise_github_exception, ] async def json(**kwargs): return access_token_responses.pop(0)() response_mocker.add( url="https://github.com/login/oauth/access_token", response=MockedResponse( json=json, headers={"Content-Type": "application/json"}, keep=True), ) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER}, ) assert result["step_id"] == "user" assert result["type"] == FlowResultType.FORM result = await hass.config_entries.flow.async_configure( result["flow_id"], user_input={ "acc_logs": True, "acc_addons": True, "acc_untested": True, "acc_disable": True, }, ) assert result["step_id"] == "device" assert result["type"] == FlowResultType.SHOW_PROGRESS time_freezer.tick(10) await hass.config_entries.flow.async_configure(result["flow_id"]) await hass.async_block_till_done() result = await hass.config_entries.flow.async_configure(result["flow_id"]) assert result["type"] == FlowResultType.ABORT snapshots.assert_match( safe_json_dumps(recursive_remove_key( result, ("flow_id", "minor_version"))), "config_flow/test_flow_with_activation_failure.json", ) async def test_already_configured( hass: HomeAssistant, _mock_setup_entry: None, snapshots: SnapshotFixture, check_report_issue: None, ) -> None: """Test we abort if already configured.""" config_entry = create_config_entry() config_entry.add_to_hass(hass) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER}, ) await hass.async_block_till_done() assert result["type"] == FlowResultType.ABORT snapshots.assert_match( safe_json_dumps(recursive_remove_key( result, ("flow_id", "minor_version"))), "config_flow/test_already_configured.json", ) async def test_options_flow(hass: HomeAssistant, setup_integration: Generator) -> None: """Test reconfiguring.""" config_entry = hass.config_entries.async_entries(DOMAIN)[0] result = await hass.config_entries.options.async_init(config_entry.entry_id) assert result["type"] == FlowResultType.FORM assert result["step_id"] == "user" # Test defaults hacs = get_hacs(hass) schema = result["data_schema"].schema for key in schema: assert key.default() == getattr(hacs.configuration, str(key)) result = await hass.config_entries.options.async_configure( result["flow_id"], user_input={ "sidepanel_title": "new_title", }, ) assert result["type"] == FlowResultType.CREATE_ENTRY assert result["data"] == { "appdaemon": True, "country": "ALL", "experimental": True, "sidepanel_icon": "hacs:hacs", "sidepanel_title": "new_title", } assert config_entry.data == {"token": TOKEN} assert config_entry.options == { "appdaemon": True, "country": "ALL", "experimental": True, "sidepanel_icon": "hacs:hacs", "sidepanel_title": "new_title", } # Check config entry is reloaded with new options await hass.async_block_till_done() # Get a new HACS instance after reload hacs = get_hacs(hass) for key, val in config_entry.options.items(): if key == "experimental": assert hasattr(hacs.configuration, str(key)) is False continue assert getattr(hacs.configuration, str(key)) == val ================================================ FILE: tests/test_data_client.py ================================================ """Test the data_client module.""" import asyncio from contextlib import nullcontext as does_not_raise from typing import ContextManager from homeassistant.core import HomeAssistant import pytest from custom_components.hacs.base import HacsBase from custom_components.hacs.exceptions import HacsException, HacsNotModifiedException from tests.common import ( CategoryTestData, MockedResponse, ResponseMocker, category_test_data_parametrized, create_config_entry, get_hacs, recursive_remove_key, safe_json_dumps, ) from tests.conftest import SnapshotFixture @pytest.mark.parametrize("category_test_data", category_test_data_parametrized()) async def test_basic_functionality_data( hacs: HacsBase, category_test_data: CategoryTestData, snapshots: SnapshotFixture, ): """Test the base result.""" result = await hacs.data_client.get_data(category_test_data["category"], validate=True) snapshots.assert_match( safe_json_dumps(recursive_remove_key(result, ("last_fetched",))), f"data_client/base/data/{category_test_data['category']}.json", ) @pytest.mark.parametrize("category_test_data", category_test_data_parametrized()) async def test_basic_functionality_repositories( hacs: HacsBase, category_test_data: CategoryTestData, snapshots: SnapshotFixture, ): """Test the base result.""" result = await hacs.data_client.get_repositories(category_test_data["category"]) snapshots.assert_match( safe_json_dumps(recursive_remove_key(result, ("last_fetched",))), f"data_client/base/repositories/{category_test_data['category']}.json", ) @pytest.mark.parametrize( "exception,expectation", ( pytest.param( Exception("Test"), pytest.raises(HacsException, match="Error fetching data from HACS: Test"), id="Exception-Error fetching data from HACS: Test", ), pytest.param( asyncio.TimeoutError, pytest.raises(HacsException, match="Timeout of 60s reached"), id="TimeoutError-Timeout of 60s reached", ), ), ) async def test_exception_handling( hacs: HacsBase, response_mocker: ResponseMocker, exception: Exception, expectation: ContextManager, ): """Test the base result.""" response_mocker.add( "https://data-v2.hacs.xyz/integration/repositories.json", response=MockedResponse(exception=exception), ) with expectation: await hacs.data_client.get_repositories("integration") @pytest.mark.parametrize( "status,expectation", ( pytest.param(1009, pytest.raises(HacsException), id="1009-HacsException"), pytest.param(200, does_not_raise(), id="200-does_not_raise"), pytest.param(201, does_not_raise(), id="201-does_not_raise"), pytest.param(301, pytest.raises(HacsException), id="301-HacsException"), pytest.param(302, pytest.raises(HacsException), id="302-HacsException"), pytest.param( 304, pytest.raises(HacsNotModifiedException), id="304-HacsNotModifiedException", ), pytest.param(400, pytest.raises(HacsException), id="400-HacsException"), pytest.param(401, pytest.raises(HacsException), id="401-HacsException"), pytest.param(403, pytest.raises(HacsException), id="403-HacsException"), pytest.param(418, pytest.raises(HacsException), id="418-HacsException"), pytest.param(429, pytest.raises(HacsException), id="429-HacsException"), pytest.param(500, pytest.raises(HacsException), id="500-HacsException"), pytest.param(529, pytest.raises(HacsException), id="529-HacsException"), ), ) async def test_status_handling( hacs: HacsBase, response_mocker: ResponseMocker, status: int, expectation: ContextManager, ): """Test the base result.""" response_mocker.add( "https://data-v2.hacs.xyz/integration/repositories.json", response=MockedResponse(status=status), ) with expectation: await hacs.data_client.get_repositories("integration") GOOD_COMMON_DATA = { "description": "abc", "etag_repository": "blah", "full_name": "blah", "last_commit": "abc", "last_fetched": 0, "last_updated": "blah", "manifest": {}, } GOOD_INTEGRATION_DATA = { "description": "abc", "domain": "abc", "etag_repository": "blah", "full_name": "blah", "last_commit": "abc", "last_fetched": 0, "last_updated": "blah", "manifest": {}, "manifest_name": "abc", } def without(d: dict, key: str) -> dict: """Return a copy of d without key.""" d = dict(d) d.pop(key) return d @pytest.mark.parametrize( ("category", "data"), [ ("appdaemon", {"12345": without(GOOD_COMMON_DATA, "description")}), ("integration", {"12345": without(GOOD_INTEGRATION_DATA, "description")}), ("plugin", {"12345": without(GOOD_COMMON_DATA, "description")}), ("python_script", {"12345": without(GOOD_COMMON_DATA, "description")}), ("template", {"12345": without(GOOD_COMMON_DATA, "description")}), ("theme", {"12345": without(GOOD_COMMON_DATA, "description")}), ("critical", [{"repository": "test", "reason": "blah"}]), ("removed", [{"repository": "test"}]), ], ) async def test_basic_functionality_data_validate( hacs: HacsBase, response_mocker: ResponseMocker, snapshots: SnapshotFixture, category: str, data: dict | list, ): """Test invalid repo data is discarded when validation is enabled.""" response_mocker.add( f"https://data-v2.hacs.xyz/{category}/data.json", MockedResponse(content=data), ) validated = await hacs.data_client.get_data(category, validate=True) response_mocker.add( f"https://data-v2.hacs.xyz/{category}/data.json", MockedResponse(content=data), ) unvalidated = await hacs.data_client.get_data(category, validate=False) snapshots.assert_match( safe_json_dumps({"validated": validated, "unvalidated": unvalidated}), f"data_client/base/data_validate/{category}.json", ) @pytest.mark.parametrize( ("category", "data"), [ ("appdaemon", without(GOOD_COMMON_DATA, "description")), ("integration", without(GOOD_INTEGRATION_DATA, "description")), ("plugin", without(GOOD_COMMON_DATA, "description")), ("python_script", without(GOOD_COMMON_DATA, "description")), ("template", without(GOOD_COMMON_DATA, "description")), ("theme", without(GOOD_COMMON_DATA, "description")), ], ) async def test_discard_invalid_repo_data( hass: HomeAssistant, response_mocker: ResponseMocker, snapshots: SnapshotFixture, category: str, data: dict, ): """Test validation is enabled when updating category repositories.""" response_mocker.add( f"https://data-v2.hacs.xyz/{category}/data.json", MockedResponse(content={"12345": data}), ) config_entry = create_config_entry() hass.data.pop("custom_components", None) config_entry.add_to_hass(hass) assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() hacs: HacsBase = get_hacs(hass) assert hacs.repositories assert not hacs.system.disabled assert hacs.stage == "running" repository = f"hacs-test-org/{category}-basic" await snapshots.assert_hacs_data( hacs, f"{repository}/test_discard_invalid_repo_data.json", ) ================================================ FILE: tests/test_diagnostics.py ================================================ """Test the diagnostics module.""" from custom_components.hacs.base import HacsBase from custom_components.hacs.diagnostics import async_get_config_entry_diagnostics from tests.common import ( TOKEN, MockedResponse, ResponseMocker, recursive_remove_key, safe_json_dumps, ) from tests.conftest import SnapshotFixture REMOVE_KEYS = ("entry_id", "last_updated", "local", "minor_version", "created_at", "modified_at", "discovery_keys", "subentries_data", "subentries") async def test_diagnostics(hacs: HacsBase, snapshots: SnapshotFixture): """Test the base result.""" diagnostics = await async_get_config_entry_diagnostics( hacs.hass, hacs.configuration.config_entry, ) assert TOKEN not in str(diagnostics) snapshots.assert_match( safe_json_dumps(recursive_remove_key( diagnostics, REMOVE_KEYS)), "diagnostics/base.json" ) async def test_diagnostics_with_exception( hacs: HacsBase, snapshots: SnapshotFixture, response_mocker: ResponseMocker, ): """Test the result with issues getting the ratelimit.""" response_mocker.add( "https://api.github.com/rate_limit", MockedResponse(status=400, content="Something went wrong"), ) diagnostics = await async_get_config_entry_diagnostics( hacs.hass, hacs.configuration.config_entry, ) snapshots.assert_match( safe_json_dumps(recursive_remove_key(diagnostics, REMOVE_KEYS)), "diagnostics/exception.json", ) ================================================ FILE: tests/test_emuns.py ================================================ """"Test enums.""" from custom_components.hacs.enums import RepositoryFile def test_enum_value(): """Test enum value.""" assert RepositoryFile.HACS_JSON == "hacs.json" assert RepositoryFile.HACS_JSON.value == "hacs.json" assert str(RepositoryFile.HACS_JSON) == "hacs.json" ================================================ FILE: tests/test_sensor_cleanup.py ================================================ """Test the sensor cleanup.""" from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er from custom_components.hacs.const import DOMAIN, HACS_SYSTEM_ID from tests.common import create_config_entry, setup_integration async def test_sensor_cleanup(hass: HomeAssistant) -> None: """Test the sensor cleanup.""" entity_registry = er.async_get(hass) assert len(entity_registry.entities) == 0 entry = entity_registry.async_get_or_create( domain="sensor", platform=DOMAIN, unique_id=HACS_SYSTEM_ID, ) assert entity_registry.async_get(entry.entity_id) is not None await setup_integration( hass, create_config_entry( options={ "appdaemon": True, }, ), ) assert entity_registry.async_get(entry.entity_id) is None ================================================ FILE: tests/test_switch.py ================================================ """Test switch entity.""" from collections.abc import Generator import json as json_func import os from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_registry import async_get as async_get_entity_registry import pytest from custom_components.hacs import PLATFORMS from custom_components.hacs.const import DOMAIN from tests.common import ( CategoryTestData, MockedResponse, ResponseMocker, category_test_data_parametrized, get_hacs, recursive_remove_key, safe_json_dumps, ) from tests.conftest import SnapshotFixture @pytest.mark.parametrize("category_test_data", category_test_data_parametrized()) async def test_switch_entity_state( hass: HomeAssistant, setup_integration: Generator, response_mocker: ResponseMocker, category_test_data: CategoryTestData, snapshots: SnapshotFixture, ): hacs = get_hacs(hass) repo = hacs.repositories.get_by_full_name(category_test_data["repository"]) states = {key: {} for key in PLATFORMS} assert repo is not None repo.data.installed = True repo.data.installed_version = category_test_data["version_base"] er = async_get_entity_registry(hass) await hass.config_entries.async_reload(hacs.configuration.config_entry.entry_id) await hass.async_block_till_done() fixture_file = f"fixtures/proxy/data-v2.hacs.xyz/{ category_test_data['category']}/data.json" fp = os.path.join( os.path.dirname(__file__), fixture_file, ) with open(fp, encoding="utf-8") as fptr: data = json_func.loads(fptr.read()) for repo_data in data.values(): repo_data["last_fetched"] += 1 repo_data["last_version"] = category_test_data["version_update"] repo_data["prerelease"] = category_test_data["prerelease"] response_mocker.add( f"https://data-v2.hacs.xyz/{category_test_data['category']}/data.json", MockedResponse(content=data), ) er.async_update_entity(er.async_get_entity_id( "switch", DOMAIN, repo.data.id), disabled_by=None) await hass.config_entries.async_reload(hacs.configuration.config_entry.entry_id) await hass.async_block_till_done() # Get a new HACS instance after reload hacs = get_hacs(hass) for platform in PLATFORMS: entity_id = er.async_get_entity_id(platform, DOMAIN, repo.data.id) assert entity_id is not None states[platform]["initial"] = recursive_remove_key( hass.states.get(entity_id).as_dict(), ("id", "last_changed", "last_reported", "last_updated", "display_precision", "update_percentage"), ) await hass.services.async_call( domain="switch", service="turn_on", service_data={"entity_id": er.async_get_entity_id( "switch", DOMAIN, repo.data.id)}, blocking=True, ) for platform in PLATFORMS: entity_id = er.async_get_entity_id(platform, DOMAIN, repo.data.id) assert entity_id is not None states[platform]["updated"] = recursive_remove_key( hass.states.get(entity_id).as_dict(), ("id", "last_changed", "last_reported", "last_updated", "display_precision", "update_percentage"), ) snapshots.assert_match( safe_json_dumps(states), f"{category_test_data['repository']}/test_switch/entity_states.json", ) ================================================ FILE: tests/test_system_health.py ================================================ """Test system health.""" import asyncio from collections.abc import Generator from typing import Any from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component import pytest from custom_components.hacs.base import HacsBase from tests.common import MockedResponse, ResponseMocker, safe_json_dumps from tests.conftest import SnapshotFixture HACS_SYSTEM_HEALTH_DOMAIN = "Home Assistant Community Store" async def get_system_health_info(hass: HomeAssistant, domain: str) -> dict[str, Any]: """Get system health info.""" return await hass.data["system_health"][domain].info_callback(hass) async def test_system_health( setup_integration: Generator, hass: HomeAssistant, response_mocker: ResponseMocker, snapshots: SnapshotFixture, ) -> None: """Test HACS system health.""" response_mocker.add( url="https://api.github.com", response=MockedResponse( content={}, headers={"Content-Type": "application/json"}, ), ) response_mocker.add( url="https://raw.githubusercontent.com/hacs/integration/main/hacs.json", response=MockedResponse( content={}, headers={"Content-Type": "application/json"}, ), ) response_mocker.add( url="https://data-v2.hacs.xyz/data.json", response=MockedResponse( content={}, headers={"Content-Type": "application/json"}, ), ) assert await async_setup_component(hass, "system_health", {}) await hass.async_block_till_done() info = await get_system_health_info(hass, HACS_SYSTEM_HEALTH_DOMAIN) for key, val in info.items(): if asyncio.iscoroutine(val): info[key] = await val snapshots.assert_match(safe_json_dumps(info), "system_health/system_health.json") async def test_system_health_after_unload( hacs: HacsBase, hass: HomeAssistant, snapshots: SnapshotFixture, ) -> None: """Test HACS system health.""" await hass.config_entries.async_unload(hacs.configuration.config_entry.entry_id) assert await async_setup_component(hass, "system_health", {}) await hass.async_block_till_done() info = await get_system_health_info(hass, HACS_SYSTEM_HEALTH_DOMAIN) snapshots.assert_match(safe_json_dumps(info), "system_health/system_health_after_unload.json") async def test_system_health_no_hacs( hass: HomeAssistant, ) -> None: """Test HACS system health.""" assert await async_setup_component(hass, "system_health", {}) await hass.async_block_till_done() with pytest.raises(KeyError, match=HACS_SYSTEM_HEALTH_DOMAIN): await get_system_health_info(hass, HACS_SYSTEM_HEALTH_DOMAIN) ================================================ FILE: tests/test_update.py ================================================ """Test update entity.""" from collections.abc import Generator import json as json_func import os from freezegun.api import FrozenDateTimeFactory from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_registry import async_get as async_get_entity_registry import pytest from custom_components.hacs.const import DOMAIN from tests.common import ( CategoryTestData, MockedResponse, ResponseMocker, category_test_data_parametrized, get_hacs, recursive_remove_key, safe_json_dumps, ) from tests.conftest import SnapshotFixture @pytest.mark.parametrize("category_test_data", category_test_data_parametrized()) async def test_update_entity_state( time_freezer: FrozenDateTimeFactory, hass: HomeAssistant, response_mocker: ResponseMocker, setup_integration: Generator, category_test_data: CategoryTestData, snapshots: SnapshotFixture, ): hacs = get_hacs(hass) repo = hacs.repositories.get_by_full_name(category_test_data["repository"]) assert repo is not None repo.data.installed = True repo.data.installed_version = category_test_data["version_base"] await hass.config_entries.async_reload(hacs.configuration.config_entry.entry_id) await hass.async_block_till_done() # Get a new HACS instance after reload hacs = get_hacs(hass) er = async_get_entity_registry(hacs.hass) entity_id = er.async_get_entity_id("update", DOMAIN, repo.data.id) # Get initial state state = hass.states.get(entity_id) initial_state = recursive_remove_key( state.as_dict(), ("id", "last_changed", "last_reported", "last_updated", "display_precision", "update_percentage"), ) # Bump version fixture_file = f"fixtures/proxy/data-v2.hacs.xyz/{ category_test_data['category']}/data.json" fp = os.path.join( os.path.dirname(__file__), fixture_file, ) with open(fp, encoding="utf-8") as fptr: data = json_func.loads(fptr.read()) for repo_data in data.values(): repo_data["last_fetched"] += 1 repo_data["last_version"] = "2.0.0" response_mocker.add( f"https://data-v2.hacs.xyz/{category_test_data['category']}/data.json", MockedResponse(content=data), ) repo = hacs.repositories.get_by_full_name(category_test_data["repository"]) time_freezer.tick(3600 * 48 + 1) await hass.async_block_till_done() await hass.async_block_till_done() # Get updated state state = hass.states.get(entity_id) updated_state = recursive_remove_key( state.as_dict(), ("id", "last_changed", "last_reported", "last_updated", "display_precision", "update_percentage"), ) snapshots.assert_match( safe_json_dumps({"initial_state": initial_state, "updated_state": updated_state}), f"{category_test_data['repository']}/test_update_entity_state.json", ) ================================================ FILE: tests/utils/test_decorator.py ================================================ """Test HACS decorators.""" import pytest from custom_components.hacs.utils.decorator import return_none_on_exception def test_sync_function_no_exception(): """Test that a synchronous function returning a value works normally.""" @return_none_on_exception def test_func(): return "test_value" assert test_func() == "test_value" def test_sync_function_with_exception(): """Test that a synchronous function raising an exception returns None.""" @return_none_on_exception def test_func(): raise ValueError("Test exception") assert test_func() is None def test_sync_method_no_exception(): """Test that a synchronous method returning a value works normally.""" class TestClass: @return_none_on_exception def test_method(self): return "test_value" instance = TestClass() assert instance.test_method() == "test_value" def test_sync_method_with_exception(): """Test that a synchronous method raising an exception returns None.""" class TestClass: @return_none_on_exception def test_method(self): raise ValueError("Test exception") instance = TestClass() assert instance.test_method() is None @pytest.mark.asyncio async def test_async_function_no_exception(): """Test that an async function returning a value works normally.""" @return_none_on_exception async def test_func(): return "test_value" assert await test_func() == "test_value" @pytest.mark.asyncio async def test_async_function_with_exception(): """Test that an async function raising an exception returns None.""" @return_none_on_exception async def test_func(): raise ValueError("Test exception") assert await test_func() is None @pytest.mark.asyncio async def test_async_method_no_exception(): """Test that an async method returning a value works normally.""" class TestClass: @return_none_on_exception async def test_method(self): return "test_value" instance = TestClass() assert await instance.test_method() == "test_value" @pytest.mark.asyncio async def test_async_method_with_exception(): """Test that an async method raising an exception returns None.""" class TestClass: @return_none_on_exception async def test_method(self): raise ValueError("Test exception") instance = TestClass() assert await instance.test_method() is None @pytest.mark.asyncio async def test_async_method_with_args(): """Test that an async method with arguments works normally.""" class TestClass: @return_none_on_exception async def test_method(self, arg1, arg2=None): if arg2 is None: return arg1 return f"{arg1}_{arg2}" instance = TestClass() assert await instance.test_method("test") == "test" assert await instance.test_method("test", "value") == "test_value" @pytest.mark.asyncio async def test_async_method_with_args_exception(): """Test that an async method with arguments that raises an exception returns None.""" class TestClass: @return_none_on_exception async def test_method(self, arg1, arg2=None): if arg2 is None: raise ValueError("Test exception") return f"{arg1}_{arg2}" instance = TestClass() assert await instance.test_method("test") is None assert await instance.test_method("test", "value") == "test_value" ================================================ FILE: tests/utils/test_fs_util.py ================================================ """Test fs_util.""" import pytest from custom_components.hacs.utils.file_system import ( async_exists, async_remove, async_remove_directory, ) async def test_async_exists(hass, tmpdir): """Test async_exists.""" assert not await async_exists(hass, tmpdir / "tmptmp") open(tmpdir / "tmptmp", "w").close() assert await async_exists(hass, tmpdir / "tmptmp") async def test_async_remove(hass, tmpdir): """Test async_remove.""" assert not await async_exists(hass, tmpdir / "tmptmp") with pytest.raises(FileNotFoundError): await async_remove(hass, tmpdir / "tmptmp") with pytest.raises(FileNotFoundError): await async_remove(hass, tmpdir / "tmptmp", missing_ok=False) await async_remove(hass, tmpdir / "tmptmp", missing_ok=True) open(tmpdir / "tmptmp", "w").close() await async_remove(hass, tmpdir / "tmptmp") assert not await async_exists(hass, tmpdir / "tmptmp") open(tmpdir / "tmptmp", "w").close() await async_remove(hass, tmpdir / "tmptmp", missing_ok=False) assert not await async_exists(hass, tmpdir / "tmptmp") open(tmpdir / "tmptmp", "w").close() await async_remove(hass, tmpdir / "tmptmp", missing_ok=True) assert not await async_exists(hass, tmpdir / "tmptmp") async def test_async_remove_directory(hass, tmpdir): """Test async_remove_directory.""" assert not await async_exists(hass, tmpdir / "tmptmp") with pytest.raises(FileNotFoundError): await async_remove_directory(hass, tmpdir / "tmptmp") with pytest.raises(FileNotFoundError): await async_remove_directory(hass, tmpdir / "tmptmp", missing_ok=False) assert not await async_exists(hass, tmpdir / "tmptmp") await async_remove_directory(hass, tmpdir / "tmptmp", missing_ok=True) (tmpdir / "tmptmp").mkdir() assert await async_exists(hass, tmpdir / "tmptmp") await async_remove_directory(hass, tmpdir / "tmptmp") assert not await async_exists(hass, tmpdir / "tmptmp") (tmpdir / "tmptmp").mkdir() assert await async_exists(hass, tmpdir / "tmptmp") await async_remove_directory(hass, tmpdir / "tmptmp", missing_ok=False) assert not await async_exists(hass, tmpdir / "tmptmp") (tmpdir / "tmptmp").mkdir() assert await async_exists(hass, tmpdir / "tmptmp") await async_remove_directory(hass, tmpdir / "tmptmp", missing_ok=True) assert not await async_exists(hass, tmpdir / "tmptmp") ================================================ FILE: tests/utils/test_path.py ================================================ from custom_components.hacs.base import HacsBase from custom_components.hacs.utils import path def test_is_safe(hacs: HacsBase) -> None: assert path.is_safe(hacs, "/test") assert not path.is_safe(hacs, f"{hacs.core.config_path}/{hacs.configuration.theme_path}/") assert not path.is_safe(hacs, f"{hacs.core.config_path}/custom_components/") assert not path.is_safe(hacs, f"{hacs.core.config_path}/custom_components") ================================================ FILE: tests/utils/test_queue_manager.py ================================================ """Queue tests.""" from unittest.mock import AsyncMock import pytest from custom_components.hacs.base import HacsBase from custom_components.hacs.exceptions import HacsExecutionStillInProgress from custom_components.hacs.utils.queue_manager import QueueManager dummy_task = AsyncMock() async def test_queue_manager(hacs: HacsBase, caplog: pytest.LogCaptureFixture) -> None: """Test the queue manager.""" queue_manager = QueueManager(hass=hacs.hass) assert not queue_manager.running assert not queue_manager.has_pending_tasks assert queue_manager.pending_tasks == 0 assert queue_manager.queue == [] queue_manager.add(dummy_task()) assert queue_manager.has_pending_tasks assert queue_manager.pending_tasks == 1 for _ in range(1, 5): queue_manager.add(dummy_task()) assert queue_manager.has_pending_tasks assert queue_manager.pending_tasks == 5 await queue_manager.execute(1) assert queue_manager.has_pending_tasks assert queue_manager.pending_tasks == 4 queue_manager.running = True with pytest.raises(HacsExecutionStillInProgress): await queue_manager.execute() queue_manager.running = False await queue_manager.execute() await queue_manager.execute() assert not queue_manager.running assert not queue_manager.has_pending_tasks assert queue_manager.pending_tasks == 0 assert queue_manager.queue == [] assert "The queue is empty" in caplog.text ================================================ FILE: tests/utils/test_store.py ================================================ """Queue tests.""" from unittest.mock import AsyncMock, patch from homeassistant.core import HomeAssistant import pytest from custom_components.hacs.const import VERSION_STORAGE from custom_components.hacs.exceptions import HacsException from custom_components.hacs.utils.store import ( async_load_from_store, async_remove_store, async_save_to_store, get_store_for_key, ) async def test_store_load(hass: HomeAssistant) -> None: """Test the store load.""" store = get_store_for_key(hass, "test") with patch( "custom_components.hacs.utils.store.json_util.load_json", return_value={"version": VERSION_STORAGE, "data": {"test": "test"}}, ): assert store.load() == {"test": "test"} assert await async_load_from_store(hass, "test") == {"test": "test"} with patch("custom_components.hacs.utils.store.json_util.load_json", return_value={}): assert store.load() is None with pytest.raises(HacsException): with patch( "custom_components.hacs.utils.store.json_util.load_json", side_effect=OSError("No file"), ): assert store.load() == {"test": "test"} async def test_store_remove(hass: HomeAssistant) -> None: """Test the store remove.""" with patch( "custom_components.hacs.utils.store.HACSStore.async_remove", return_value=AsyncMock(), ) as async_remove_mock: await async_remove_store(hass, "test") assert not async_remove_mock.called await async_remove_store(hass, "test/test") assert async_remove_mock.called async def test_store_store(hass: HomeAssistant, caplog: pytest.LogCaptureFixture) -> None: """Test the store store.""" with patch( "custom_components.hacs.utils.store.HACSStore.async_save", return_value=AsyncMock(), ) as async_save_mock, patch( "custom_components.hacs.utils.store.json_util.load_json", return_value={"version": VERSION_STORAGE, "data": {}}, ): await async_save_to_store(hass, "test", {}) assert not async_save_mock.called assert ( " Did not store data for 'hacs.test'. Content did not change" in caplog.text ) await async_save_to_store(hass, "test", {"test": "test"}) assert async_save_mock.call_count == 1 ================================================ FILE: tests/utils/test_url.py ================================================ """Tests for the utils.url module.""" import pytest from custom_components.hacs.utils.url import github_archive, github_release_asset @pytest.mark.parametrize( "arguments,url", ( ( {"repository": "owner/repo", "version": "1.0.0", "filename": "example.zip"}, "https://github.com/owner/repo/releases/download/1.0.0/example.zip", ), ), ) def test_github_release_asset(arguments: dict[str, str], url: str) -> None: """Test github_release_asset.""" assert github_release_asset(**arguments) == url @pytest.mark.parametrize( "arguments,url", ( ( {"repository": "owner/repo", "version": "1.0.0", "variant": "heads"}, "https://github.com/owner/repo/archive/refs/heads/1.0.0.zip", ), ( {"repository": "owner/repo", "version": "1.0.0", "variant": "tags"}, "https://github.com/owner/repo/archive/refs/tags/1.0.0.zip", ), ( { "repository": "owner/repo", "version": "1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b", "variant": "heads", }, "https://github.com/owner/repo/archive/1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b.zip", ), ( { "repository": "owner/repo", "version": "1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b", "variant": "tags", }, "https://github.com/owner/repo/archive/1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b.zip", ), ), ) def test_github_archive(arguments: dict[str, str], url: str) -> None: """Test github_archive.""" assert github_archive(**arguments) == url ================================================ FILE: tests/utils/test_validate.py ================================================ from contextlib import nullcontext as does_not_raise import re from awesomeversion import AwesomeVersion import pytest from voluptuous.error import Invalid, MultipleInvalid from custom_components.hacs.utils.validate import ( HACS_MANIFEST_JSON_SCHEMA as hacs_json_schema, INTEGRATION_MANIFEST_JSON_SCHEMA as integration_json_schema, VALIDATE_FETCHED_V2_CRITICAL_REPO_SCHEMA, VALIDATE_FETCHED_V2_REMOVED_REPO_SCHEMA, VALIDATE_FETCHED_V2_REPO_DATA, VALIDATE_GENERATED_V2_CRITICAL_REPO_SCHEMA, VALIDATE_GENERATED_V2_REMOVED_REPO_SCHEMA, VALIDATE_GENERATED_V2_REPO_DATA, ) from tests.common import fixture def test_hacs_manifest_json_schema(): """Test HACS validator.""" assert hacs_json_schema({"name": "My awesome thing", "homeassistant": "1.2"}) == { "name": "My awesome thing", "homeassistant": AwesomeVersion(1.2), } assert hacs_json_schema({"name": "My awesome thing", "hacs": "1.2"}) == { "name": "My awesome thing", "hacs": AwesomeVersion(1.2), } assert hacs_json_schema({"name": "My awesome thing", "country": ["NO"]}) == { "name": "My awesome thing", "country": ["NO"], } assert hacs_json_schema({"name": "My awesome thing", "country": "NO"}) == { "name": "My awesome thing", "country": ["NO"], } assert hacs_json_schema({"name": "My awesome thing", "country": "no"}) == { "name": "My awesome thing", "country": ["NO"], } assert hacs_json_schema( { "name": "My awesome thing", "content_in_root": True, "filename": "my_super_awesome_thing.js", "country": ["NO", "SE", "DK"], }, ) assert hacs_json_schema( { "name": "My awesome thing", "country": "NO", "homeassistant": "0.99.9", "persistent_directory": "userfiles", }, ) assert hacs_json_schema( { "name": "My awesome thing", "content_in_root": True, "zip_release": True, "filename": "my_super_awesome_thing.js", "render_readme": True, "country": "NO", "homeassistant": "0.99.9", "persistent_directory": "userfiles", }, ) assert hacs_json_schema( { "name": "My awesome thing", }, ) with pytest.raises(Invalid, match="extra keys not allowed"): hacs_json_schema({"name": "My awesome thing", "not": "valid"}) with pytest.raises(Invalid, match="Value 'NOT_VALID' is not in"): hacs_json_schema({"name": "My awesome thing", "country": "not_valid"}) with pytest.raises(Invalid, match=re.escape("Value 'False' is not a string or list.")): hacs_json_schema({"name": "My awesome thing", "country": False}) def test_integration_json_schema(): """Test integration manifest.""" base_data = { "issue_tracker": "https://hacs.xyz/", "name": "My awesome thing", "version": "1.2", "domain": "myawesomething", "codeowners": ["test"], "documentation": "https://hacs.xyz/", } assert integration_json_schema(base_data)["version"] == AwesomeVersion(1.2) assert integration_json_schema(base_data) == base_data with pytest.raises(Invalid, match="expected str for dictionary value"): integration_json_schema({**base_data, "domain": None}) def test_critical_repo_data_json_schema(): """Test validating https://data-v2.hacs.xyz/critical/data.json.""" data = fixture("v2-critical-data.json") for repo in data: VALIDATE_FETCHED_V2_CRITICAL_REPO_SCHEMA(repo) VALIDATE_GENERATED_V2_CRITICAL_REPO_SCHEMA(data) @pytest.mark.parametrize( ("data", "expectation_1", "expectation_2"), [ # Good data ( {"repository": "test", "reason": "blah", "link": "https://blah"}, does_not_raise(), does_not_raise(), ), # Missing required key ( {}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( {"repository": "test", "reason": "blah"}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( {"repository": "test", "link": "https://blah"}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( {"reason": "blah", "link": "https://blah"}, pytest.raises(Invalid), pytest.raises(Invalid), ), # Wrong data type ( {"repository": 123, "reason": "blah", "link": "https://blah"}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( {"repository": "test", "reason": 123, "link": "https://blah"}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( {"repository": "test", "reason": "blah", "link": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), # Extra key ( {"repository": "test", "reason": "blah", "link": "https://blah", "extra": "key"}, does_not_raise(), pytest.raises(Invalid), ), ], ) def test_critical_repo_data_json_schema_bad_data(data: dict, expectation_1, expectation_2): """Test validating https://data-v2.hacs.xyz/critical/data.json.""" with expectation_1: VALIDATE_FETCHED_V2_CRITICAL_REPO_SCHEMA(data) with expectation_2: VALIDATE_GENERATED_V2_CRITICAL_REPO_SCHEMA([data]) @pytest.mark.parametrize( "category", [ "appdaemon", "integration", "plugin", "python_script", "template", "theme", ], ) def test_repo_data_json_schema(category: str): """Test validating https://data-v2.hacs.xyz//data.json.""" data = fixture(f"v2-{category}-data.json") for repo in data.values(): VALIDATE_FETCHED_V2_REPO_DATA[category](repo) VALIDATE_GENERATED_V2_REPO_DATA[category](data) GOOD_COMMON_DATA = { "description": "abc", "etag_repository": "blah", "full_name": "blah", "last_commit": "abc", "last_fetched": 0, "last_updated": "blah", "manifest": {}, } GOOD_INTEGRATION_DATA = { "description": "abc", "domain": "abc", "etag_repository": "blah", "full_name": "blah", "last_commit": "abc", "last_fetched": 0, "last_updated": "blah", "manifest": {}, "manifest_name": "abc", } def without(d: dict, key: str) -> dict: """Return a copy of d without key.""" d = dict(d) d.pop(key) return d @pytest.mark.parametrize( ("categories", "data", "expectation_1", "expectation_2"), [ # Good data ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA, does_not_raise(), does_not_raise(), ), # Test we allow at least one of last_commit or last_version ( ["appdaemon", "plugin", "python_script", "template", "theme"], without(GOOD_COMMON_DATA, "last_commit") | {"last_version": "123"}, does_not_raise(), does_not_raise(), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"last_version": "123"}, does_not_raise(), does_not_raise(), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"last_version": "123", "prerelease": "1.2.3"}, does_not_raise(), does_not_raise(), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"last_version": "123", "prerelease": None}, pytest.raises(Invalid), pytest.raises(Invalid), ), # Missing required key ( ["appdaemon", "plugin", "python_script", "template", "theme"], without(GOOD_COMMON_DATA, "description"), pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], without(GOOD_COMMON_DATA, "etag_repository"), pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], without(GOOD_COMMON_DATA, "full_name"), pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], without(GOOD_COMMON_DATA, "last_commit"), pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], without(GOOD_COMMON_DATA, "last_fetched"), pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], without(GOOD_COMMON_DATA, "last_updated"), pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], without(GOOD_COMMON_DATA, "manifest"), pytest.raises(Invalid), pytest.raises(Invalid), ), # Wrong data type in required keys ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"description": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"etag_repository": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"full_name": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"last_commit": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"last_fetched": "blah"}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"last_updated": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"manifest": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), # Wrong data type in optional keys ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"downloads": "many"}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"etag_releases": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"last_commit": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"last_version": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"open_issues": "many"}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"stargazers_count": "many"}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"topics": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), # Extra key ( ["appdaemon", "plugin", "python_script", "template", "theme"], GOOD_COMMON_DATA | {"extra": "key"}, does_not_raise(), pytest.raises(Invalid), ), # Good data ( ["integration"], GOOD_INTEGRATION_DATA, does_not_raise(), does_not_raise(), ), # Test we allow at least one of last_commit or last_version ( ["integration"], without(GOOD_INTEGRATION_DATA, "last_commit") | { "last_version": "123"}, does_not_raise(), does_not_raise(), ), ( ["integration"], GOOD_INTEGRATION_DATA | {"last_version": "123"}, does_not_raise(), does_not_raise(), ), ( ["integration"], GOOD_INTEGRATION_DATA | { "last_version": "123", "prerelease": "1.2.3"}, does_not_raise(), does_not_raise(), ), # Missing required key ( ["integration"], without(GOOD_INTEGRATION_DATA, "description"), pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], without(GOOD_INTEGRATION_DATA, "domain"), pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], without(GOOD_INTEGRATION_DATA, "etag_repository"), pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], without(GOOD_INTEGRATION_DATA, "full_name"), pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], without(GOOD_INTEGRATION_DATA, "last_commit"), pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], without(GOOD_INTEGRATION_DATA, "last_fetched"), pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], without(GOOD_INTEGRATION_DATA, "last_updated"), pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], without(GOOD_INTEGRATION_DATA, "manifest"), pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], without(GOOD_INTEGRATION_DATA, "manifest_name"), pytest.raises(Invalid), pytest.raises(Invalid), ), # Wrong data type in required keys ( ["integration"], GOOD_INTEGRATION_DATA | {"domain": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], GOOD_INTEGRATION_DATA | {"description": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], GOOD_INTEGRATION_DATA | {"etag_repository": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], GOOD_INTEGRATION_DATA | {"full_name": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], GOOD_INTEGRATION_DATA | {"last_commit": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], GOOD_INTEGRATION_DATA | {"last_fetched": "blah"}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], GOOD_INTEGRATION_DATA | {"last_updated": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], GOOD_INTEGRATION_DATA | {"manifest": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], GOOD_INTEGRATION_DATA | {"manifest_name": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), # Wrong data type in optional keys ( ["integration"], GOOD_INTEGRATION_DATA | {"downloads": "many"}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], GOOD_INTEGRATION_DATA | {"etag_releases": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], GOOD_INTEGRATION_DATA | {"last_commit": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], GOOD_INTEGRATION_DATA | {"last_version": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], GOOD_INTEGRATION_DATA | {"open_issues": "many"}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], GOOD_INTEGRATION_DATA | {"stargazers_count": "many"}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( ["integration"], GOOD_INTEGRATION_DATA | {"topics": 123}, pytest.raises(Invalid), pytest.raises(Invalid), ), # Extra key ( ["integration"], GOOD_INTEGRATION_DATA | {"extra": "key"}, does_not_raise(), pytest.raises(Invalid), ), ], ) def test_repo_data_json_schema_bad_data( categories: list[str], data: dict, expectation_1, expectation_2, ): """Test validating https://data-v2.hacs.xyz/xxx/data.json.""" for category in categories: with expectation_1: VALIDATE_FETCHED_V2_REPO_DATA[category](data) with expectation_2: VALIDATE_GENERATED_V2_REPO_DATA[category]({"test_repo": data}) @pytest.mark.parametrize( ("categories", "data"), [ # This has multiple errors: # - No last_commit or last_version # - No description # - full_name is wrong type ( ["appdaemon", "plugin", "python_script", "template", "theme"], { "etag_repository": "blah", "full_name": 123, "last_fetched": 0, "last_updated": "blah", "manifest": {}, }, ), ( ["integration"], { "domain": "abc", "etag_repository": "blah", "full_name": 123, "last_fetched": 0, "last_updated": "blah", "manifest": {}, "manifest_name": "abc", }, ), ], ) def test_repo_data_json_schema_multiple_bad_data(categories: list[str], data): """Test validating https://data-v2.hacs.xyz/xxx/data.json with multiple errors. This tests we get both dict-based schema errors and custom validation errors. """ expected_errors_1 = { ("expected str", ("full_name",)), ("required key not provided", ("description",)), ("Expected at least one of [`last_commit`, `last_version`], got none", ()), } expected_errors_2 = { ("expected str", ("test_repo", "full_name")), ("required key not provided", ("test_repo", "description")), ("Expected at least one of [`last_commit`, `last_version`], got none", ( "test_repo",)), } for category in categories: with pytest.raises(MultipleInvalid) as exc_info: VALIDATE_FETCHED_V2_REPO_DATA[category](data) msgs = [(err.msg, tuple(err.path)) for err in exc_info.value.errors] assert len(msgs) == 3 assert set(msgs) == expected_errors_1 with pytest.raises(MultipleInvalid) as exc_info: VALIDATE_GENERATED_V2_REPO_DATA[category]({"test_repo": data}) msgs = [(err.msg, tuple(err.path)) for err in exc_info.value.errors] assert len(msgs) == 3 assert set(msgs) == expected_errors_2 def test_removed_repo_data_json_schema(): """Test validating https://data-v2.hacs.xyz/removed/data.json.""" data = fixture("v2-removed-data.json") for repo in data: VALIDATE_FETCHED_V2_REMOVED_REPO_SCHEMA(repo) VALIDATE_GENERATED_V2_REMOVED_REPO_SCHEMA(data) @pytest.mark.parametrize( ("data", "expectation_1", "expectation_2"), [ # Good data ({"removal_type": "critical", "repository": "test"}, does_not_raise(), does_not_raise()), # Missing required key ({}, pytest.raises(Invalid), pytest.raises(Invalid)), ({"repository": "test"}, pytest.raises(Invalid), pytest.raises(Invalid)), ({"removal_type": "critical"}, pytest.raises( Invalid), pytest.raises(Invalid)), # Wrong data type ( {"link": 123, "reason": "blah", "removal_type": "critical", "repository": "test"}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( { "link": "https://blah", "reason": 123, "removal_type": "critical", "repository": "test", }, pytest.raises(Invalid), pytest.raises(Invalid), ), ( {"link": "https://blah", "reason": "blah", "removal_type": 123, "repository": "test"}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( {"link": "https://blah", "reason": "blah", "removal_type": "bad", "repository": "test"}, pytest.raises(Invalid), pytest.raises(Invalid), ), ( { "link": "https://blah", "reason": "blah", "removal_type": "critical", "repository": 123, }, pytest.raises(Invalid), pytest.raises(Invalid), ), # Extra key ( { "link": "https://blah", "reason": "blah", "removal_type": "critical", "repository": "test", "extra": "key", }, does_not_raise(), pytest.raises(Invalid), ), ], ) def test_removed_repo_data_json_schema_bad_data(data: dict, expectation_1, expectation_2): """Test validating https://data-v2.hacs.xyz/critical/data.json.""" with expectation_1: VALIDATE_FETCHED_V2_REMOVED_REPO_SCHEMA(data) with expectation_2: VALIDATE_GENERATED_V2_REMOVED_REPO_SCHEMA([data]) ================================================ FILE: tests/utils/test_version.py ================================================ """Tests for the version util functions.""" import pytest from custom_components.hacs.utils import version def test_version_to_download(repository): """Test version_to_download.""" repository.data.selected_tag = "main" assert repository.version_to_download() == "main" repository.data.default_branch = None repository.data.last_version = None repository.data.selected_tag = None assert repository.version_to_download() == "main" repository.data.selected_tag = "2" assert repository.version_to_download() == "2" repository.data.selected_tag = None repository.data.last_version = "3" assert repository.version_to_download() == "3" repository.data.selected_tag = None repository.data.last_version = None assert repository.version_to_download() == "main" repository.data.selected_tag = "2" repository.data.last_version = None assert repository.version_to_download() == "2" repository.data.selected_tag = "main" repository.data.last_version = None assert repository.version_to_download() == "main" repository.data.selected_tag = "3" repository.data.last_version = "3" repository.version_to_download() assert repository.data.selected_tag is None repository.data.default_branch = "dev" repository.data.last_version = None repository.data.selected_tag = None assert repository.version_to_download() == "dev" repository.data.default_branch = "main" repository.data.last_version = "2" assert repository.version_to_download() == "2" repository.data.default_branch = "main" repository.data.selected_tag = "main" repository.data.last_version = None assert repository.version_to_download() == "main" repository.ref = "my-ref" assert repository.version_to_download() == "main" repository.ref = "my-ref" repository.force_branch = True assert repository.version_to_download() == "my-ref" @pytest.mark.parametrize( "left, right, expected", [ ("1.0.0", "0.9.9", True), ("1", "0.9.9", True), ("1.1", "0.9.9", True), ("0.10.0", "0.9.9", True), ("0.0.10", "0.9.9", False), ("0.9.0", "0.9.9", False), ("1.0.0", "1.0.0", True), ("1.0.0b1", "1.0.0b0", True), ("1.0.0b1", "1.0.0", False), ("1.0.0", "1.0.0b1", True), ("1.0.0rc1", "1.0.0b1", True), ("1.0.0a1", "1.0.0b1", False), ("1.0.0", "1.0.0a0", True), ("1.0.0", "1.0.0b0", True), ("1.0.0", "1.0.0rc0", True), ("0", "1.0.0rc0", False), ("", "1.0", None), ], ) def test_version_left_higher_or_equal_then_right(left: str, right: str, expected: bool): """Test version_left_higher_or_equal_then_right.""" assert version.version_left_higher_or_equal_then_right( left, right) == expected ================================================ FILE: tests/utils/test_workarounds.py ================================================ from custom_components.hacs.utils.workarounds import DOMAIN_OVERRIDES def test_domain_ovverides() -> None: assert DOMAIN_OVERRIDES.get("custom-components/sensor.custom_aftership") == "custom_aftership" assert DOMAIN_OVERRIDES.get("awesome/repo") is None ================================================ FILE: tests/validate/test_async_run_repository_checks.py ================================================ from unittest.mock import patch import pytest from custom_components.hacs.base import HacsBase from custom_components.hacs.repositories.integration import HacsIntegrationRepository from custom_components.hacs.validate.manager import ValidationManager async def test_async_run_repository_checks( hacs: HacsBase, repository_integration: HacsIntegrationRepository, ): hacs.validation = ValidationManager(hacs=hacs, hass=hacs.hass) hacs.system.action = False await hacs.validation.async_run_repository_checks(repository_integration) hacs.system.action = True repository_integration.tree = [] with pytest.raises(SystemExit): await hacs.validation.async_run_repository_checks(repository_integration) with patch( "custom_components.hacs.validate.manager.ValidationManager.validators", return_value=[], ): await hacs.validation.async_run_repository_checks(repository_integration) ================================================ FILE: tests/validate/test_brands_check.py ================================================ from custom_components.hacs.repositories.base import HacsManifest from custom_components.hacs.validate.brands import ASSET_FILENAME, Validator from tests.common import MockedResponse, ResponseMocker async def test_added_to_brands(repository, response_mocker: ResponseMocker): response_mocker.add( "https://brands.home-assistant.io/domains.json", MockedResponse(content={"custom": ["test"]}), ) repository.data.domain = "test" check = Validator(repository) await check.execute_validation() assert not check.failed async def test_not_added_to_brands(repository, response_mocker: ResponseMocker): response_mocker.add( "https://brands.home-assistant.io/domains.json", MockedResponse(content={"custom": []}), ) repository.data.domain = "test" check = Validator(repository) await check.execute_validation() assert check.failed async def test_local_brands_asset_content_in_root(repository): """Test that validation passes when the brands asset exists locally with content_in_root.""" repository.repository_manifest = HacsManifest.from_dict({"content_in_root": True}) repository.treefiles = [f"brand/{ASSET_FILENAME}"] repository.data.domain = "test" check = Validator(repository) await check.execute_validation() assert not check.failed async def test_local_brands_asset_not_in_root(repository): """Test that validation passes when the brands asset exists locally in a subdirectory.""" repository.repository_manifest = HacsManifest.from_dict({"content_in_root": False}) repository.content.path.remote = "custom_components/test" repository.treefiles = [f"custom_components/test/brand/{ASSET_FILENAME}"] repository.data.domain = "test" check = Validator(repository) await check.execute_validation() assert not check.failed async def test_local_brands_asset_missing_falls_back_to_remote( repository, response_mocker: ResponseMocker ): """Test that when local asset is missing, it falls back to checking the brands repo.""" repository.repository_manifest = HacsManifest.from_dict({"content_in_root": True}) repository.treefiles = [] repository.data.domain = "test" response_mocker.add( "https://brands.home-assistant.io/domains.json", MockedResponse(content={"custom": ["test"]}), ) check = Validator(repository) await check.execute_validation() assert not check.failed ================================================ FILE: tests/validate/test_hacsjson_check.py ================================================ from aiogithubapi.objects.repository.content import AIOGitHubAPIRepositoryTreeContent from custom_components.hacs.validate.hacsjson import Validator test_tree = [ AIOGitHubAPIRepositoryTreeContent( attributes={"path": "hacs.json", "type": "file"}, repository="test/test", ref="main"), AIOGitHubAPIRepositoryTreeContent( attributes={"path": "README.md", "type": "file"}, repository="test/test", ref="main"), ] async def test_hacs_manifest_no_manifest(repository, caplog): check = Validator(repository) await check.execute_validation() assert check.failed assert "no 'hacs.json'" in caplog.text async def test_hacs_manifest_with_valid_manifest(repository): repository.tree = test_tree repository.data.category = "integration" async def _async_get_hacs_json_raw(**_): return {"name": "test"} repository.get_hacs_json_raw = _async_get_hacs_json_raw check = Validator(repository) await check.execute_validation() assert not check.failed async def test_hacs_manifest_with_invalid_manifest(repository): repository.tree = test_tree async def _async_get_hacs_json_raw(**_): return {"not": "valid"} repository.get_hacs_json_raw = _async_get_hacs_json_raw check = Validator(repository) await check.execute_validation() assert check.failed async def test_hacs_manifest_with_missing_filename(repository, caplog): repository.tree = test_tree repository.data.category = "integration" async def _async_get_hacs_json_raw(**_): return {"name": "test", "zip_release": True, "hacs": "0.0.0"} repository.get_hacs_json_raw = _async_get_hacs_json_raw check = Validator(repository) await check.execute_validation() assert check.failed assert ( " failed: zip_release is True, but filename is not set (More info: https://hacs.xyz/docs/publish/include#check-hacs-manifest )" in caplog.text ) async def test_hacs_manifest_integration_zip_release_with_filename(repository): repository.tree = test_tree repository.data.category = "integration" async def _async_get_hacs_json_raw(**_): return {"name": "test", "zip_release": True, "filename": "file.zip"} repository.get_hacs_json_raw = _async_get_hacs_json_raw check = Validator(repository) await check.execute_validation() assert not check.failed ================================================ FILE: tests/validate/test_images_check.py ================================================ from custom_components.hacs.validate.images import Validator async def test_repository_has_images(repository): repository.data.has_issues = True check = Validator(repository) async def _async_get_info_file_contents(*_, **__): return """ ![-shielded ![valid] """ repository.async_get_info_file_contents = _async_get_info_file_contents await check.execute_validation() assert not check.failed async def test_repository_has_not_images(repository): repository.data.has_issues = False check = Validator(repository) async def _async_get_info_file_contents(*_, **__): return """ ![-shielded """ repository.async_get_info_file_contents = _async_get_info_file_contents await check.execute_validation() assert check.failed ================================================ FILE: tests/validate/test_integration_manifest_check.py ================================================ from aiogithubapi.objects.repository.content import AIOGitHubAPIRepositoryTreeContent from custom_components.hacs.validate.integration_manifest import Validator async def test_integration_no_manifest(repository_integration): check = Validator(repository_integration) await check.execute_validation() assert check.failed async def test_integration_manifest_with_valid_manifest(repository_integration): repository_integration.tree = [ AIOGitHubAPIRepositoryTreeContent( {"path": "manifest.json", "type": "file"}, "test/test", "main", ), ] async def _async_get_integration_manifest(**__): return { "domain": "test", "documentation": "https://hacs.xyz", "issue_tracker": "https://hacs.xyz", "codeowners": ["test"], "name": "test", "version": "1.0.0", } repository_integration.get_integration_manifest = _async_get_integration_manifest check = Validator(repository_integration) await check.execute_validation() assert not check.failed async def test_hacs_manifest_with_invalid_manifest(repository_integration): repository_integration.tree = [ AIOGitHubAPIRepositoryTreeContent( {"path": "manifest.json", "type": "file"}, "test/test", "main", ), ] async def _async_get_integration_manifest(**__): return {"not": "valid"} repository_integration.get_integration_manifest = _async_get_integration_manifest check = Validator(repository_integration) await check.execute_validation() assert check.failed ================================================ FILE: tests/validate/test_repository_archived_check.py ================================================ from custom_components.hacs.validate.archived import Validator async def test_repository_archived(repository): repository.data.archived = True check = Validator(repository) await check.execute_validation() assert check.failed async def test_repository_not_archived(repository): repository.data.archived = False check = Validator(repository) await check.execute_validation() assert not check.failed ================================================ FILE: tests/validate/test_repository_description_check.py ================================================ from custom_components.hacs.validate.description import Validator async def test_repository_no_description(repository): repository.data.description = "" check = Validator(repository) await check.execute_validation() assert check.failed async def test_repository_hacs_description(repository): check = Validator(repository) await check.execute_validation() assert not check.failed ================================================ FILE: tests/validate/test_repository_information_file_check.py ================================================ from aiogithubapi.objects.repository.content import AIOGitHubAPIRepositoryTreeContent from custom_components.hacs.validate.information import Validator async def test_no_info_file(repository): check = Validator(repository) await check.execute_validation() assert check.failed async def test_no_readme_file(repository): check = Validator(repository) await check.execute_validation() assert check.failed async def test_has_info_file(repository): repository.tree = [ AIOGitHubAPIRepositoryTreeContent({"path": "info", "type": "file"}, "test/test", "main"), ] check = Validator(repository) await check.execute_validation() assert not check.failed async def test_has_info_md_file(repository): repository.tree = [ AIOGitHubAPIRepositoryTreeContent({"path": "info.md", "type": "file"}, "test/test", "main"), ] check = Validator(repository) await check.execute_validation() assert not check.failed async def test_has_readme_file(repository): repository.repository_manifest.render_readme = True repository.tree = [ AIOGitHubAPIRepositoryTreeContent({"path": "readme", "type": "file"}, "test/test", "main"), ] check = Validator(repository) await check.execute_validation() assert not check.failed async def test_has_readme_md_file(repository): repository.repository_manifest.render_readme = True repository.tree = [ AIOGitHubAPIRepositoryTreeContent( {"path": "readme.md", "type": "file"}, "test/test", "main", ), ] check = Validator(repository) await check.execute_validation() assert not check.failed ================================================ FILE: tests/validate/test_repository_issues_check.py ================================================ from custom_components.hacs.validate.issues import Validator async def test_repository_issues_enabled(repository): repository.data.has_issues = True check = Validator(repository) await check.execute_validation() assert not check.failed async def test_repository_issues_not_enabled(repository): repository.data.has_issues = False check = Validator(repository) await check.execute_validation() assert check.failed ================================================ FILE: tests/validate/test_repository_topics_check.py ================================================ from custom_components.hacs.validate.topics import Validator async def test_repository_no_topics(repository): repository.data.topics = [] check = Validator(repository) await check.execute_validation() assert check.failed async def test_repository_hacs_topics(repository): repository.data.topics = ["test"] check = Validator(repository) await check.execute_validation() assert not check.failed