{"id":35764460,"url":"https://github.com/zigpy/zigpy-ota","last_synced_at":"2026-01-17T22:17:51.131Z","repository":{"id":332412637,"uuid":"1109533473","full_name":"zigpy/zigpy-ota","owner":"zigpy","description":"Zigbee OTA images for zigpy/ZHA","archived":false,"fork":false,"pushed_at":"2026-01-08T16:05:55.000Z","size":914,"stargazers_count":4,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"dev","last_synced_at":"2026-01-13T19:57:28.071Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zigpy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-03T23:56:27.000Z","updated_at":"2026-01-12T03:12:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/zigpy/zigpy-ota","commit_stats":null,"previous_names":["zigpy/zigpy-ota"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/zigpy/zigpy-ota","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zigpy%2Fzigpy-ota","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zigpy%2Fzigpy-ota/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zigpy%2Fzigpy-ota/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zigpy%2Fzigpy-ota/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zigpy","download_url":"https://codeload.github.com/zigpy/zigpy-ota/tar.gz/refs/heads/dev","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zigpy%2Fzigpy-ota/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28519880,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T22:11:28.393Z","status":"ssl_error","status_checked_at":"2026-01-17T22:11:27.841Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-07T00:28:18.389Z","updated_at":"2026-01-17T22:17:51.122Z","avatar_url":"https://github.com/zigpy.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# zigpy-ota\n\nOTA firmware images, metadata, and CLI tools for Zigbee devices, used by [zigpy](https://github.com/zigpy/zigpy)-based applications like Home Assistant's ZHA.\n\n## For End Users\n\n**You don't need to use this repository directly.** OTA updates are automatically available through:\n\n- **Home Assistant ZHA integration** - Updates appear automatically in the UI (requires Home Assistant Core 2026.1.0 or later)\n- **zigpy-based applications** - Any application using zigpy can consume these updates\n\n### Browse available firmware\n\n- [Stable channel](https://github.com/zigpy/zigpy-ota/blob/release/files/stable/markdown_v1.md)\n- [Beta channel](https://github.com/zigpy/zigpy-ota/blob/release/files/beta/markdown_v1.md)\n- [Dev channel](https://github.com/zigpy/zigpy-ota/blob/release/files/dev/markdown_v1.md)\n\n**Note**: Firmware marked as `[disabled]` or `[stale]` is not installable. It's retained for historic and changelog purposes only.\n\n### Using pre-release channels\n\n\u003cdetails\u003e\u003csummary\u003eClick to expand\u003c/summary\u003e\n\nBy default, only stable firmware is available, which is highly recommended for most users.\\\nTo opt into pre-release firmware, add this to your Home Assistant configuration:\n\n```yaml\nzha:\n  zigpy_config:\n    ota:\n      extra_providers:\n        - type: zigpy_ota\n          channel: beta # or 'dev' for bleeding edge (unstable, not recommended)\n          override_previous: true\n```\n\n\u003c/details\u003e\n\n## For Contributors\n\n### Submitting OTA Firmware Images\n\n**Use the GitHub issue form to submit OTA images** - this is the recommended and easiest method:\n\n1. Go to: https://github.com/zigpy/zigpy-ota/issues/new/choose\n2. Select one of two options:\n   - **\"Submit OTA (URL)\"** - Provide a download URL to the OTA file\n   - **\"Submit OTA (File Upload)\"** - Upload the OTA file directly (must be zipped first)\n3. Fill out the form with:\n   - **Title**: Use format `Add Manufacturer Device vX.X.X`\n   - **OTA image URL** or **upload zipped OTA file** (depending on which form)\n   - **How to handle existing images** (required dropdown):\n     - Keep all existing images\n     - Keep existing images and set `min_current_file_version` to highest existing version\n   - Manufacturer name (optional, for display purposes)\n   - Release notes (optional but recommended)\n   - Optional metadata (model names, version constraints, hardware versions, etc.)\n   - Checklist items (at least confirm the file format)\n\n**Important**: Submit **one issue per OTA image**. Multiple versions should be separate issues.\n\n**What happens next:**\n\n- For trusted submitters, an automated PR is created immediately\n- For other submitters, a maintainer will review your issue and add the `ota-create` label to trigger PR creation\n\nIf you need to make changes to your submission, edit the original issue and ask a maintainer to add the `ota-resubmit` label to update the PR.\n\n**Tip**: You can also submit older firmware versions (e.g., factory-installed firmware) so that ZHA displays \"up-to-date\" instead of \"unknown\" for devices already running the latest available firmware.\n\n### Manual YAML Metadata Edits\n\nFor updates to existing images (e.g., adding `min_current_file_version` or `model_names` to an existing image), you can submit a PR directly:\n\n1. Fork the repository\n2. Edit the `.yaml` file in the `images/` directory\n3. Submit a pull request with your changes\n\nSee the [YAML Metadata Format](#yaml-metadata-format) section below.\n\n### Removing or Reverting Firmware Updates\n\nTo disable or revert an existing firmware update, submit a PR using one of these methods:\n\n1. **Disable the image** (preferred) - Add `disabled: true` to the YAML metadata file to exclude it from the index without deleting the files.\n2. **Revert the commit** - If the firmware was recently added, create a PR that reverts the commit which added the update\n3. **Manual deletion** - Delete both the OTA file (`.zigbee` or `.ota`) and its corresponding YAML metadata file (`.yaml`) from the `images/` directory, then submit a PR with those changes\n\nFor options 2 and 3, both the OTA binary and YAML metadata file must be removed together to fully remove a firmware update from the index.\nUse deletion only if the firmware bricks devices.\n\n**Note**: The repository generally retains all firmware images for historic purposes.\nZigpy always prefers newer firmware versions, so older images are only used when they have constraints (like `min_current_file_version` or `model_names`) that make them more specific to certain devices.\nYou can check the [firmware index](#browse-available-firmware) to see if an image is marked as `[stale]` or `[disabled]`. These are not installed by zigpy/ZHA.\n\n## Release Process\n\n1. OTA images are submitted via GitHub issues\n2. Automated PRs are created and reviewed\n3. Once merged to `dev`, the `dev/` folder on the [`release/files`](https://github.com/zigpy/zigpy-ota/tree/release/files) branch is automatically updated with the latest index files\n4. Images are immediately available for testing from the dev channel\n5. For stable/beta releases, maintainers create a GitHub release. Index files are attached as [release assets](https://github.com/zigpy/zigpy-ota/releases) and mirrored to the corresponding folder on the [`release/files`](https://github.com/zigpy/zigpy-ota/tree/release/files) branch\n6. zigpy and Home Assistant automatically consume the index from the appropriate channel\n\n## Release Channels\n\n- **stable** - Production releases for end users\n- **beta** - Pre-release testing versions\n- **dev** - Latest development builds from the `dev` branch\n\nImages are included in channels based on their `channel` YAML field:\n\n- No `channel` field (default): included in stable, beta, and dev\n- `channel: beta`: included in beta and dev only\n- `channel: dev`: included in dev only\n\n**Index file naming (GitHub release assets):**\n\n- Stable releases: `zigpy_v1_ota.json`, `z2m_v1_ota.json`, and `markdown_v1.md`\n- Beta releases: `zigpy_v1_ota_beta.json`, `z2m_v1_ota_beta.json`, and `markdown_v1_beta.md`\n\n### Accessing the index files programmatically\n\n**Recommended**: Discover the URL dynamically via version files on the [`release/version`](https://github.com/zigpy/zigpy-ota/tree/release/version) branch:\\\n`https://raw.githubusercontent.com/zigpy/zigpy-ota/release/version/{stable,beta,dev}.json`\n\nIndex files are also mirrored to the [`release/files`](https://github.com/zigpy/zigpy-ota/tree/release/files) branch organized by channel (`stable/`, `beta/`, `dev/`), where all folders use the same filenames (`zigpy_v1_ota.json`, `z2m_v1_ota.json`, `markdown_v1.md`).\n\nAfter an image is merged to the `dev` branch, the updated index is immediately available for testing at:\\\n`https://raw.githubusercontent.com/zigpy/zigpy-ota/release/files/dev/zigpy_v1_ota.json`\n\n**Direct access** for all channels (not preferred):\\\n`https://raw.githubusercontent.com/zigpy/zigpy-ota/release/files/{stable,beta,dev}/zigpy_v1_ota.json`\n\n\u003c!-- Consider moving the Z2M configuration to the \"For End-Users\" section at some point ---\u003e\n\n**Example**: To use the stable Zigbee2MQTT index, add this to your Z2M configuration:\n\n```yaml\nota:\n  zigbee_ota_override_index_location: https://raw.githubusercontent.com/zigpy/zigpy-ota/release/files/stable/z2m_v1_ota.json\n```\n\n## YAML Metadata Format\n\nThe YAML metadata file must have the same name as the OTA file with `.yaml` appended.\\\n(e.g., `firmware_name.ota` → `firmware_name.ota.yaml`).\n\nOTA files are automatically renamed to a standardized format based on their metadata: `\u003cmanufacturer_id\u003e-\u003cimage_type\u003e-\u003cfile_version\u003e_\u003chash\u003e.ota` (hash is first 6 chars of SHA3-256). The original filename is preserved in the `source_file_name` field.\\\nThis renaming is done automatically when submitting a new OTA image via the issue form. In the future, CLI tools will also be added to rename files locally.\n\n\u003c!-- Third-party section not enabled yet. It's also disabled in issue forms.\nThere are two types of YAML metadata files:\n\n### Regular (Repo-Hosted) Images\n---\u003e\n\nFor images stored in this repository:\n\n```yaml\n# OTA metadata\nfile_name: 100B-010C-01001A02_abc123.ota\nsource_file_name: original_firmware.zigbee\nsource_url: https://manufacturer.com/original_firmware.zigbee\n\n# Optional fields:\nrelease_notes: |-\n  - Bug fixes\n  - New features\nmanufacturer_names: [Manufacturer A, Manufacturer B]\nmodel_names: [Model X, Model Y]\nmin_current_file_version: 100\nmax_current_file_version: 200\nmin_hardware_version: 5\nmax_hardware_version: 10\nspecificity: 3\nchannel: beta\n```\n\n- `file_name`: The standardized filename in the repository (auto-generated from OTA metadata)\n- `source_file_name`: The original filename from the source (preserved for reference)\n\n\u003c!-- Third-party section not enabled yet. It's also disabled in issue forms.\n### Third-Party (Externally-Hosted) Images\n\nFor images hosted externally (not stored in repo):\n\n```yaml\n# OTA metadata\nfile_name: firmware.ota\nsource_url: https://manufacturer.com/firmware.ota\n# OTA image metadata required for third-party hosted images:\nthird_party_download:\n  manufacturer_id: 1234\n  image_type: 789\n  file_version: 123456\n  file_size: 12345678\n  checksum_sha3_256: abc123...\n  checksum_sha512: def456...\n\n# Optional fields are the same as regular images (see above)\n```\n\n**Key differences:**\n\n- Regular YAML: Checksum/file_size/manufacturer_id extracted from binary automatically\n- Third-party YAML: Must provide all fields under the `third_party_download` key (no binary in repo to extract from)\n\n**How to create third-party YAML:**\n\nThere is no dedicated CLI command to generate third-party YAML at the moment. Use one of these methods:\n\n1. **Recommended**: Use the GitHub issue form (URL submission) and check the \"Third-party download\" checkbox - metadata will be generated automatically (this internally uses `zigpy-ota prepare-pr` with the GitHub issue form markdown)\n2. **Manual**: Create the YAML file manually with all required fields listed above\n--\u003e\n\n### Optional Metadata Fields\n\n- `manufacturer_names` - List of manufacturer name strings for device matching\n- `model_names` - List of model name strings for device matching\n- `min_current_file_version` - Minimum current firmware version for update eligibility\n- `max_current_file_version` - Maximum current firmware version for update eligibility\n- `min_hardware_version` - Minimum hardware version compatibility\n- `max_hardware_version` - Maximum hardware version compatibility\n- `specificity` - Priority level when multiple images match (higher = more specific)\n- `channel` - Release channel (omit for stable which appears in all channels; `beta` appears in beta and dev; `dev` appears only in dev)\n\n**Note on multi-step upgrades:** Due to how zigpy's firmware matching algorithm works, it's typically sufficient to set `min_current_file_version` on the newer image to require a previous upgrade first.\n\nZigpy automatically prioritizes and prefers more specific images based on the device's current firmware version, so `max_current_file_version` constraints are usually not needed.\\\nFor the [generated Z2M index](https://raw.githubusercontent.com/zigpy/zigpy-ota/release/files/stable/z2m_v1_ota.json), `maxFileVersion` is automatically computed from `min_current_file_version` constraints of newer images.\n\n## For Developers\n\n\u003cdetails\u003e\u003csummary\u003eClick to expand\u003c/summary\u003e\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/zigpy/zigpy-ota.git\ncd zigpy-ota\n\n# Run setup script (creates venv, installs dependencies, sets up pre-commit)\nscript/setup\n\n# Activate the virtual environment\nsource .venv/bin/activate\n\n# Or manually:\n# uv sync\n# pre-commit install\n```\n\n### Running Tests\n\n```bash\n# Run all tests\npytest\n\n# Update snapshots after intentional changes\npytest --snapshot-update\n\n# Run specific test file\npytest tests/test_prepare_pr.py\n\n# Run with coverage\npytest --cov=zigpy_ota --cov-report=html\n```\n\n### Code Quality\n\n```bash\n# Run all pre-commit hooks\npre-commit run --all-files\n\n# Type checking\nmypy zigpy_ota\n\n# Linting and formatting\nruff check zigpy_ota\nruff format zigpy_ota\n```\n\n### CLI Commands\n\n```bash\n# Generate index from images\nzigpy-ota generate-index --format zigpy     # zigpy JSON (default)\nzigpy-ota generate-index --format z2m       # Zigbee2MQTT JSON\nzigpy-ota generate-index --format markdown  # Human-readable markdown\n\n# Parse a GitHub issue submission\nzigpy-ota parse-issue issue.md\n\n# Prepare PR from issue (download OTA, create YAML, generate PR markdown)\nzigpy-ota prepare-pr issue.md --output-pr-markdown pr.md\n\n# Generate stub YAML metadata for an OTA file\nzigpy-ota generate-stub-metadata firmware.ota\n\n# Rename OTA files to standardized format (updates YAML too)\nzigpy-ota rename-ota-files --dry-run  # preview\nzigpy-ota rename-ota-files            # apply\n\n# Generate fake OTA image for testing\nzigpy-ota generate-fake-ota output.ota --manufacturer-id 0x100B --image-type 0x010C --file-version 0x00000001\n\n# Replace real OTA files with fake ones (for tests)\nzigpy-ota replace-with-fake-ota tests/data/ota_files/*.ota\n```\n\n### Validation Options\n\nThe `generate-index` command has validation flags (all default to strict/fail):\n\n```bash\n# Strict validation (recommended for CI/CD)\nzigpy-ota generate-index\n\n# Development mode flags:\n--allow-missing-yaml        # Allow OTA images without corresponding YAML metadata\n--allow-missing-ota         # Allow YAML files without corresponding OTA binary\n--allow-inconsistent-yaml   # Allow third-party YAML with local OTA files present\n--allow-filename-mismatch   # Allow YAML file_name field not matching filename\n--allow-invalid-yaml        # Allow YAML files that fail to parse\n--allow-collisions          # Allow duplicate images (same ID/type/version)\n\n# Download and validate third-party/remote hosted images (not for CI/CD)\n--validate-third-party\n```\n\nSee [CLAUDE.md](CLAUDE.md) for detailed developer documentation.\n\n\u003c/details\u003e\n\n## License\n\nThe zigpy-ota **software code** is licensed under GPL-3.0 (GNU General Public License v3.0). See [LICENSE](LICENSE) file.\n\n**Important**: Binary firmware image files in this repository are **third-party content** from their respective manufacturers and are **NOT covered by the GPL license**. These firmware files remain under their original copyright and licensing terms as set by their manufacturers. Users must comply with applicable manufacturer terms when using these firmware files.\n\n## Questions\n\nFor questions or discussions, see [GitHub Discussions](https://github.com/zigpy/zigpy-ota/discussions).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzigpy%2Fzigpy-ota","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzigpy%2Fzigpy-ota","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzigpy%2Fzigpy-ota/lists"}