updates2mqtt 1.4.1__tar.gz → 1.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- updates2mqtt-1.5.0/.github/workflows/auto_assign_issue.yml +18 -0
- updates2mqtt-1.5.0/.github/workflows/auto_assign_pr.yml +18 -0
- updates2mqtt-1.5.0/.github/workflows/main.yml +18 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/.pre-commit-config.yaml +2 -2
- updates2mqtt-1.5.0/CHANGELOG.md +36 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/PKG-INFO +13 -6
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/README.md +12 -5
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/common_packages.yaml +38 -3
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/conftest.py +1 -1
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/docs/examples/config_maximal.md +1 -1
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/docs/examples/config_minimal.md +1 -1
- updates2mqtt-1.5.0/docs/examples/docker_compose.md +9 -0
- updates2mqtt-1.5.0/docs/examples/env.md +7 -0
- updates2mqtt-1.5.0/docs/examples/index.md +5 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/docs/home_assistant.md +20 -3
- updates2mqtt-1.5.0/docs/images/updates2mqtt-dark-256x256.png +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/docs/installation.md +6 -5
- updates2mqtt-1.5.0/docs/robots.txt +4 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/docs/troubleshooting.md +8 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/examples/config.yaml.maximal +3 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/examples/docker-compose.yaml +1 -1
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/mkdocs.yml +21 -3
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/pyproject.toml +4 -2
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/scripts/healthcheck.sh +5 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/src/updates2mqtt/app.py +16 -9
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/src/updates2mqtt/config.py +26 -6
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/src/updates2mqtt/hass_formatter.py +34 -11
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/src/updates2mqtt/integrations/docker.py +54 -19
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/src/updates2mqtt/mqtt.py +26 -18
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/tests/test_config.py +9 -3
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/tests/test_docker.py +4 -4
- updates2mqtt-1.5.0/tests/test_hass_formatter.py +85 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/tests/test_mqtt.py +4 -4
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/uv.lock +144 -45
- updates2mqtt-1.4.1/CHANGELOG.md +0 -22
- updates2mqtt-1.4.1/docs/examples/docker_compose.md +0 -7
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/.dockerignore +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/.github/dependabot.yml +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/.github/workflows/docker-publish.yml +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/.github/workflows/pypi-publish.yml +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/.github/workflows/python-package.yml +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/.gitignore +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/.hintrc +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/.python-version +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/.safety-project.ini +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/Dockerfile +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/LICENSE +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/SECURITY.md +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/docs/configuration.md +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/docs/images/ha_entities.png +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/docs/images/ha_mqtt_discovery.png +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/docs/images/ha_update_detail.png +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/docs/images/ha_update_dialog.png +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/docs/images/ha_update_page.png +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/docs/images/logo-blank-256x256.png +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/docs/index.md +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/docs/local_builds.md +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/examples/config.yaml.minimal +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/no_config.yaml +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/refresh-deps.sh +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/src/updates2mqtt/__init__.py +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/src/updates2mqtt/__main__.py +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/src/updates2mqtt/integrations/__init__.py +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/src/updates2mqtt/integrations/git_utils.py +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/src/updates2mqtt/model.py +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/src/updates2mqtt/py.typed +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/tests/__init__.py +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/tests/test_app.py +0 -0
- {updates2mqtt-1.4.1 → updates2mqtt-1.5.0}/tests/test_git_utils.py +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: Issue assignment
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issues:
|
|
5
|
+
types: [opened]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
auto-assign:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
issues: write
|
|
12
|
+
steps:
|
|
13
|
+
- name: 'Auto-assign issue'
|
|
14
|
+
uses: pozil/auto-assign-issue@39c06395cbac76e79afc4ad4e5c5c6db6ecfdd2e
|
|
15
|
+
with:
|
|
16
|
+
assignees: jeyrb
|
|
17
|
+
numOfAssignee: 1
|
|
18
|
+
allowSelfAssign: true
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: PR assignment
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, edited, synchronize, reopened]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
auto-assign:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
pull-requests: write
|
|
12
|
+
steps:
|
|
13
|
+
- name: 'Auto-assign PR'
|
|
14
|
+
uses: pozil/auto-assign-issue@39c06395cbac76e79afc4ad4e5c5c6db6ecfdd2e
|
|
15
|
+
with:
|
|
16
|
+
repo-token: ${{ secrets.MY_PERSONAL_ACCESS_TOKEN }}
|
|
17
|
+
assignees: jeyrb
|
|
18
|
+
numOfAssignee: 1
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
name: Issue assignment
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issues:
|
|
5
|
+
types: [opened]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
auto-assign:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
issues: write
|
|
12
|
+
steps:
|
|
13
|
+
- name: 'Auto-assign issue'
|
|
14
|
+
uses: pozil/auto-assign-issue@v2
|
|
15
|
+
with:
|
|
16
|
+
assignees: jeyrb
|
|
17
|
+
numOfAssignee: 1
|
|
18
|
+
allowSelfAssign: true
|
|
@@ -17,11 +17,11 @@ repos:
|
|
|
17
17
|
- id: check-shebang-scripts-are-executable
|
|
18
18
|
name: Check shell scripts are executable
|
|
19
19
|
- repo: https://github.com/astral-sh/uv-pre-commit
|
|
20
|
-
rev: 0.9.
|
|
20
|
+
rev: 0.9.16
|
|
21
21
|
hooks:
|
|
22
22
|
- id: uv-lock
|
|
23
23
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
24
|
-
rev: v0.14.
|
|
24
|
+
rev: v0.14.8
|
|
25
25
|
hooks:
|
|
26
26
|
# Run the linter.
|
|
27
27
|
- id: ruff-check
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# CHANGELOG
|
|
2
|
+
|
|
3
|
+
## 1.5.0
|
|
4
|
+
- Target specific service on docker compose commands, where available from `com.docker.compose.service` label
|
|
5
|
+
- Log level in config is now an enum, and forced to be upper case
|
|
6
|
+
- Removed unnecessary latest_version fields from config message, which also saves a redundant MQTT subscription
|
|
7
|
+
- Publication of `command_topic` for each discovery can now be forced with `force_command_topic` option
|
|
8
|
+
- More common packages: docker:cli
|
|
9
|
+
- Common packages can now match on the image ref rather than base name, for example `docker:cli`
|
|
10
|
+
- Reduced log noise in INFO and increased logging detail for DEBUG
|
|
11
|
+
- Common Packages now allow entries without all the values, initially `rtl_433` which lacks a logo
|
|
12
|
+
## 1.4.2
|
|
13
|
+
- Replace `origin` in config MQTT message with `device` for better HomeAssistant compatibility
|
|
14
|
+
- An `area` can be defined in the Home Assistant section of config and this will then be used as `suggested_area` for device
|
|
15
|
+
- Icon and release note info added for Owntone, Nextcloud, n8n, and Homarr
|
|
16
|
+
- More testcases
|
|
17
|
+
## 1.4.1
|
|
18
|
+
- More logging for Docker discovery on why Home Assistant doesn't show an update button
|
|
19
|
+
- More test cases
|
|
20
|
+
- `MqttClient` is now `MqttPublisher` to avoid confusion with actual MQTT client
|
|
21
|
+
- Task cleanup now only interrupts explicit list of tasks - healthcheck and discovery tasks
|
|
22
|
+
## 1.4.0
|
|
23
|
+
- MQTT protocol can now be set, to one of `3.1`,`3.11` or `5`
|
|
24
|
+
- Debug messages now provided for `on_subscribe` and `on_unsubscribe` callbacks
|
|
25
|
+
- Troubleshooting, installation, configuration docs updated, images optimized
|
|
26
|
+
|
|
27
|
+
## 1.3.7
|
|
28
|
+
- Improved initial setup when run without config or env vars for MQTT
|
|
29
|
+
- Minor test deps update and pyproject docs
|
|
30
|
+
|
|
31
|
+
## 1.3.6
|
|
32
|
+
- Changed exit code on graceful shutdown to 143
|
|
33
|
+
- App now exits if the MQTT username / password is not authorized
|
|
34
|
+
- Improved handling of env vars, default config now assumes MQTT_HOST etc unless overridden
|
|
35
|
+
- Will now run without a config if correct `MQTT_HOST`,`MQTT_USER`,`MQTT_PASS`,`MQTT_PORT` env vars set or match the defaults (`127.0.0.1:1883`)
|
|
36
|
+
- Deps update
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: updates2mqtt
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.0
|
|
4
4
|
Summary: System update and docker image notification and execution over MQTT
|
|
5
5
|
Project-URL: Homepage, https://updates2mqtt.rhizomatics.org.uk
|
|
6
6
|
Project-URL: Repository, https://github.com/rhizomatics/updates2mqtt
|
|
@@ -35,7 +35,7 @@ Requires-Dist: structlog>=25.4.0
|
|
|
35
35
|
Requires-Dist: usingversion>=0.1.2
|
|
36
36
|
Description-Content-Type: text/markdown
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
{ align=left }
|
|
39
39
|
|
|
40
40
|
# updates2mqtt
|
|
41
41
|
|
|
@@ -43,14 +43,19 @@ Description-Content-Type: text/markdown
|
|
|
43
43
|
|
|
44
44
|
[](https://pypi.org/project/updates2mqtt/)
|
|
45
45
|
[](https://github.com/rhizomatics/supernotify)
|
|
46
|
-
](https://updates2mqtt.rhizomatics.org.uk/developer/coverage/)
|
|
47
|
+

|
|
48
48
|
[](https://results.pre-commit.ci/latest/github/rhizomatics/updates2mqtt/main)
|
|
49
49
|
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/pypi-publish.yml)
|
|
50
50
|
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/python-package.yml)
|
|
51
51
|
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/github-code-scanning/codeql)
|
|
52
52
|
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/dependabot/dependabot-updates)
|
|
53
53
|
|
|
54
|
+
|
|
55
|
+
<br/>
|
|
56
|
+
<br/>
|
|
57
|
+
|
|
58
|
+
|
|
54
59
|
## Summary
|
|
55
60
|
|
|
56
61
|
Let Home Assistant tell you about new updates to Docker images for your containers.
|
|
@@ -86,15 +91,17 @@ Presently only Docker containers are supported, although others are planned, pro
|
|
|
86
91
|
|-----------|-------------|----------------------------------------------------------------------------------------------------|
|
|
87
92
|
| Docker | Scan. Fetch | Fetch is ``docker pull`` only. Restart support only for ``docker-compose`` image based containers. |
|
|
88
93
|
|
|
89
|
-
##
|
|
94
|
+
## Heartbeat
|
|
90
95
|
|
|
91
96
|
A heartbeat JSON payload is optionally published periodically to a configurable MQTT topic, defaulting to `healthcheck/{node_name}/updates2mqtt`. It contains the current version of updates2mqtt, the node name, a timestamp, and some basic stats.
|
|
92
97
|
|
|
98
|
+
## Healthcheck
|
|
99
|
+
|
|
93
100
|
A `healthcheck.sh` script is included in the Docker image, and can be used as a Docker healthcheck, if the container environment variables are set for `MQTT_HOST`, `MQTT_PORT`, `MQTT_USER` and `MQTT_PASS`. It uses the `mosquitto-clients` Linux package which provides `mosquitto_sub` command to subscribe to topics.
|
|
94
101
|
|
|
95
102
|
!!! tip
|
|
96
103
|
|
|
97
|
-
Check healthcheck is working using `docker inspect --format "{{json .State.Health }}" updates2mqtt | jq`
|
|
104
|
+
Check healthcheck is working using `docker inspect --format "{{json .State.Health }}" updates2mqtt | jq` (can omit `| jq` if you don't have jsonquery installed, but much easier to read with it)
|
|
98
105
|
|
|
99
106
|
Another approach is using a restarter service directly in Docker Compose to force a restart, in this case once a day:
|
|
100
107
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
{ align=left }
|
|
2
2
|
|
|
3
3
|
# updates2mqtt
|
|
4
4
|
|
|
@@ -6,14 +6,19 @@
|
|
|
6
6
|
|
|
7
7
|
[](https://pypi.org/project/updates2mqtt/)
|
|
8
8
|
[](https://github.com/rhizomatics/supernotify)
|
|
9
|
-
](https://updates2mqtt.rhizomatics.org.uk/developer/coverage/)
|
|
10
|
+

|
|
11
11
|
[](https://results.pre-commit.ci/latest/github/rhizomatics/updates2mqtt/main)
|
|
12
12
|
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/pypi-publish.yml)
|
|
13
13
|
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/python-package.yml)
|
|
14
14
|
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/github-code-scanning/codeql)
|
|
15
15
|
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/dependabot/dependabot-updates)
|
|
16
16
|
|
|
17
|
+
|
|
18
|
+
<br/>
|
|
19
|
+
<br/>
|
|
20
|
+
|
|
21
|
+
|
|
17
22
|
## Summary
|
|
18
23
|
|
|
19
24
|
Let Home Assistant tell you about new updates to Docker images for your containers.
|
|
@@ -49,15 +54,17 @@ Presently only Docker containers are supported, although others are planned, pro
|
|
|
49
54
|
|-----------|-------------|----------------------------------------------------------------------------------------------------|
|
|
50
55
|
| Docker | Scan. Fetch | Fetch is ``docker pull`` only. Restart support only for ``docker-compose`` image based containers. |
|
|
51
56
|
|
|
52
|
-
##
|
|
57
|
+
## Heartbeat
|
|
53
58
|
|
|
54
59
|
A heartbeat JSON payload is optionally published periodically to a configurable MQTT topic, defaulting to `healthcheck/{node_name}/updates2mqtt`. It contains the current version of updates2mqtt, the node name, a timestamp, and some basic stats.
|
|
55
60
|
|
|
61
|
+
## Healthcheck
|
|
62
|
+
|
|
56
63
|
A `healthcheck.sh` script is included in the Docker image, and can be used as a Docker healthcheck, if the container environment variables are set for `MQTT_HOST`, `MQTT_PORT`, `MQTT_USER` and `MQTT_PASS`. It uses the `mosquitto-clients` Linux package which provides `mosquitto_sub` command to subscribe to topics.
|
|
57
64
|
|
|
58
65
|
!!! tip
|
|
59
66
|
|
|
60
|
-
Check healthcheck is working using `docker inspect --format "{{json .State.Health }}" updates2mqtt | jq`
|
|
67
|
+
Check healthcheck is working using `docker inspect --format "{{json .State.Health }}" updates2mqtt | jq` (can omit `| jq` if you don't have jsonquery installed, but much easier to read with it)
|
|
61
68
|
|
|
62
69
|
Another approach is using a restarter service directly in Docker Compose to force a restart, in this case once a day:
|
|
63
70
|
|
|
@@ -3,7 +3,7 @@ common_packages:
|
|
|
3
3
|
docker:
|
|
4
4
|
image_name: ghcr.io/rhizomatics/updates2mqtt
|
|
5
5
|
logo_url: https://avatars.githubusercontent.com/u/162821163?s=48&v=4
|
|
6
|
-
release_notes_url: https://github.com/rhizomatics/updates2mqtt/
|
|
6
|
+
release_notes_url: https://github.com/rhizomatics/updates2mqtt/releases
|
|
7
7
|
|
|
8
8
|
frigate:
|
|
9
9
|
docker:
|
|
@@ -26,7 +26,7 @@ common_packages:
|
|
|
26
26
|
caddy:
|
|
27
27
|
docker:
|
|
28
28
|
image_name: caddy
|
|
29
|
-
logo_url: https://
|
|
29
|
+
logo_url: https://avatars.githubusercontent.com/u/12955528?s=48&v=4
|
|
30
30
|
release_notes_url: https://github.com/caddyserver/caddy/releases
|
|
31
31
|
|
|
32
32
|
uptime-kuma:
|
|
@@ -81,4 +81,39 @@ common_packages:
|
|
|
81
81
|
docker:
|
|
82
82
|
image_name: jellyfin/jellyfin
|
|
83
83
|
logo_url: https://avatars.githubusercontent.com/u/45698031?s=48&v=4
|
|
84
|
-
release_notes_url: https://github.com/jellyfin/jellyfin/releases
|
|
84
|
+
release_notes_url: https://github.com/jellyfin/jellyfin/releases
|
|
85
|
+
|
|
86
|
+
owntone:
|
|
87
|
+
docker:
|
|
88
|
+
image_name: owntone/owntone
|
|
89
|
+
logo_url: https://raw.githubusercontent.com/owntone/owntone-server/443fb684871e005a7e442a08cc4d610208abbe6c/docs/assets/logo.svg
|
|
90
|
+
release_notes_url: https://github.com/owntone/owntone-server/releases
|
|
91
|
+
|
|
92
|
+
homarr:
|
|
93
|
+
docker:
|
|
94
|
+
image_name: ghcr.io/homarr-labs/homarr
|
|
95
|
+
logo_url: https://github.com/homarr-labs/homarr/blob/dev/docs/img/logo/2340450-2-title.png?raw=true
|
|
96
|
+
release_notes_url: https://github.com/homarr-labs/homarr/releases
|
|
97
|
+
|
|
98
|
+
nextcloud:
|
|
99
|
+
docker:
|
|
100
|
+
image_name: nextcloud
|
|
101
|
+
logo_url: https://avatars.githubusercontent.com/u/19211038?s=48&v=4
|
|
102
|
+
release_notes_url: https://github.com/nextcloud/docker/releases
|
|
103
|
+
|
|
104
|
+
n8n:
|
|
105
|
+
docker:
|
|
106
|
+
image_name: docker.n8n.io/n8nio/n8n
|
|
107
|
+
logo_url: https://avatars.githubusercontent.com/u/45487711?s=48&v=4
|
|
108
|
+
release_notes_url: https://github.com/n8n-io/n8n/releases
|
|
109
|
+
|
|
110
|
+
docker_cli:
|
|
111
|
+
docker:
|
|
112
|
+
image_name: docker:cli
|
|
113
|
+
logo_url: https://www.docker.com/app/uploads/2023/05/cli_1@2x.png
|
|
114
|
+
release_notes_url: https://github.com/docker-library/docker/commits/master/29/cli
|
|
115
|
+
|
|
116
|
+
rtl_433:
|
|
117
|
+
docker:
|
|
118
|
+
image_name: hertzg/rtl_433
|
|
119
|
+
release_notes_url: https://github.com/merbanan/rtl_433/releases
|
|
@@ -35,7 +35,7 @@ def app_with_mocked_external_dependencies(
|
|
|
35
35
|
|
|
36
36
|
@pytest.fixture
|
|
37
37
|
def mock_discoveries(mock_provider: ReleaseProvider) -> list[Discovery]:
|
|
38
|
-
return [Discovery(mock_provider, "thing-1", "test001")]
|
|
38
|
+
return [Discovery(mock_provider, "thing-1", "test001", can_update=True)]
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
@pytest.fixture
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Docker Compose
|
|
2
|
+
|
|
3
|
+
Example Docker Compose configuration to run *updates2mqtt* as a container. This also
|
|
4
|
+
requires a [.env](env.md), or alternatively adding the environment variables directly into the
|
|
5
|
+
compose file.
|
|
6
|
+
|
|
7
|
+
``` yaml
|
|
8
|
+
--8<-- "examples/docker-compose.yaml"
|
|
9
|
+
```
|
|
@@ -16,16 +16,33 @@ The `homeassistant` default topic prefix matches the default updates2mqtt config
|
|
|
16
16
|
|
|
17
17
|

|
|
18
18
|
|
|
19
|
+
## Device Creation
|
|
20
|
+
|
|
21
|
+
A Home Assistant device will be created for each Updates2MQTT agent on each server, and Home Assistant
|
|
22
|
+
will then group all the relevant entities together on this device page. Use `device_creation: false` in the
|
|
23
|
+
`homeassistant` config block if you want to switch off this behaviour, and `area` if you want to provide
|
|
24
|
+
a `suggested_area` for the device.
|
|
25
|
+
|
|
19
26
|
## MQTT Topics
|
|
20
27
|
|
|
21
28
|
There are 3 separate types of MQTT topic used for HomeAssisstant integration:
|
|
22
29
|
|
|
23
|
-
- *Config* to support auto discovery.
|
|
24
|
-
-
|
|
25
|
-
-
|
|
30
|
+
- *Config* to support auto discovery.
|
|
31
|
+
- A topic is created per component, with a name like `homeassistant/update/dockernuc_docker_jellyfin/update/config`.
|
|
32
|
+
- This can be disabled in the config file, and the `homeassistant` topic prefix can also be configured.
|
|
33
|
+
- *State* to report the current version and the latest version available
|
|
34
|
+
- One topic per component, like `updates2mqtt/dockernuc/docker/jellyfin`.
|
|
35
|
+
- *Command* to support triggering an update.
|
|
36
|
+
- These will be created on the fly by HomeAssistant when an update is requested
|
|
37
|
+
- Updates2mqtt subscribes to pick up the changes, so you won't typically see these if browsing MQTT topics.
|
|
38
|
+
- Only one is needed per updates2mqtt agent, with a name like `updates2mqtt/dockernuc/docker`
|
|
26
39
|
|
|
27
40
|
If the package supports automated update, then *Skip* and *Install* buttons will appear on the Home Assistant interface, and the package can be remotely fetched and the component restarted.
|
|
28
41
|
|
|
42
|
+
If it doesn't support automated update, the `command_topic` won't be published with the configuration
|
|
43
|
+
message, unless `force_command_topic` is set to `true` in the `homeassistant` configuration section,
|
|
44
|
+
this will force the Home Assistant app to show the update, but with a do-nothing Update button.
|
|
45
|
+
|
|
29
46
|
## More Home Assistant information
|
|
30
47
|
|
|
31
48
|
- [MQTT Integration](https://www.home-assistant.io/integrations/mqtt/)
|
|
Binary file
|
|
@@ -20,13 +20,14 @@ volumes:
|
|
|
20
20
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
21
21
|
# This list of paths is only needed when containers are to be updated
|
|
22
22
|
# The paths here are completely dependent on where your docker-compose files live
|
|
23
|
-
|
|
24
|
-
- /
|
|
25
|
-
- /containers:/containers
|
|
23
|
+
# and the internal/external paths must be exactly the same
|
|
24
|
+
- /my/container/home:/my/container/home
|
|
25
|
+
- /more/containers:/more/containers
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
The example `docker-compose.yaml` mounts `/home
|
|
29
|
-
`/home/
|
|
28
|
+
The example `docker-compose.yaml` mounts `/my/container/home` for this purpose, so if your containers are in
|
|
29
|
+
`/my/container/home/app1`, `/my/container/home/app2` etc, then updates2mqtt will be able to find them in
|
|
30
|
+
order to restart them. Map as many root paths as needed.
|
|
30
31
|
|
|
31
32
|
### Without Docker
|
|
32
33
|
|
|
@@ -5,7 +5,7 @@ services:
|
|
|
5
5
|
volumes:
|
|
6
6
|
- ./conf:/app/conf # Config file lives at /app/conf/config.yaml inside the container
|
|
7
7
|
- /var/run/docker.sock:/var/run/docker.sock # Access to Docker daemon for container updates
|
|
8
|
-
- /home/
|
|
8
|
+
- /my/container/home:/my/container/home # Optional, map all root paths for docker compose directories
|
|
9
9
|
restart: always
|
|
10
10
|
env_file: ./.env # Environment variables file
|
|
11
11
|
healthcheck:
|
|
@@ -4,13 +4,18 @@ site_description: Notify and take action on server updates via MQTT, with HomeAs
|
|
|
4
4
|
|
|
5
5
|
repo_name: rhizomatics/updates2mqtt
|
|
6
6
|
repo_url: https://github.com/rhizomatics/updates2mqtt
|
|
7
|
+
edit_uri: edit/main/docs/
|
|
7
8
|
|
|
8
9
|
theme:
|
|
9
10
|
name: material
|
|
10
11
|
highlightjs: true
|
|
11
|
-
logo: images/
|
|
12
|
+
logo: images/updates2mqtt-dark-256x256.png
|
|
12
13
|
language: en
|
|
14
|
+
icon:
|
|
15
|
+
repo: fontawesome/brands/github
|
|
13
16
|
features:
|
|
17
|
+
- content.action.edit
|
|
18
|
+
- content.action.view
|
|
14
19
|
- content.code.copy
|
|
15
20
|
- content.code.select
|
|
16
21
|
- content.code.annotate
|
|
@@ -24,14 +29,24 @@ theme:
|
|
|
24
29
|
- navigation.top
|
|
25
30
|
- toc.follow
|
|
26
31
|
- toc.integrate
|
|
32
|
+
- search.suggest
|
|
33
|
+
- search
|
|
34
|
+
- search.share
|
|
27
35
|
plugins:
|
|
28
36
|
- search
|
|
29
37
|
- autorefs
|
|
30
38
|
- pagetree
|
|
31
39
|
- optimize
|
|
32
|
-
- tags
|
|
40
|
+
- tags:
|
|
41
|
+
tags: false
|
|
42
|
+
- git-revision-date-localized:
|
|
43
|
+
enable_creation_date: true
|
|
44
|
+
- meta-descriptions
|
|
33
45
|
- minify:
|
|
34
46
|
minify_html: true
|
|
47
|
+
- coverage:
|
|
48
|
+
page_path: developer/coverage
|
|
49
|
+
html_report_dir: htmlcov
|
|
35
50
|
- mkdocstrings:
|
|
36
51
|
handlers:
|
|
37
52
|
# See: https://mkdocstrings.github.io/python/usage/
|
|
@@ -40,6 +55,10 @@ plugins:
|
|
|
40
55
|
show_source: false
|
|
41
56
|
show_root_heading: true
|
|
42
57
|
summary: true
|
|
58
|
+
show_inheritance_diagram: false
|
|
59
|
+
overloads_only: true
|
|
60
|
+
show_if_no_docstring: false
|
|
61
|
+
|
|
43
62
|
markdown_extensions:
|
|
44
63
|
- admonition
|
|
45
64
|
- pymdownx.details
|
|
@@ -52,7 +71,6 @@ markdown_extensions:
|
|
|
52
71
|
pygments_lang_class: true
|
|
53
72
|
- pymdownx.inlinehilite
|
|
54
73
|
- pymdownx.superfences
|
|
55
|
-
- admonition
|
|
56
74
|
- smarty
|
|
57
75
|
- toc:
|
|
58
76
|
permalink: true
|
|
@@ -7,7 +7,7 @@ authors = [
|
|
|
7
7
|
]
|
|
8
8
|
|
|
9
9
|
requires-python = ">=3.13"
|
|
10
|
-
version = "1.
|
|
10
|
+
version = "1.5.0"
|
|
11
11
|
license="Apache-2.0"
|
|
12
12
|
keywords=["mqtt", "docker", "updates", "automation","home-assistant","homeassistant","selfhosting"]
|
|
13
13
|
|
|
@@ -60,14 +60,16 @@ dev = [
|
|
|
60
60
|
"genbadge[all]"
|
|
61
61
|
]
|
|
62
62
|
mkdocs=[
|
|
63
|
+
"mkdocs",
|
|
63
64
|
"mkdocs-material",
|
|
64
|
-
"mkdocstrings",
|
|
65
65
|
"mkdocs-minify-plugin",
|
|
66
66
|
"mkdocs-autorefs",
|
|
67
67
|
"mkdocs-pagetree-plugin",
|
|
68
68
|
"mkdocs-coverage",
|
|
69
69
|
"mkdocstrings[python]",
|
|
70
70
|
"pymdown-extensions",
|
|
71
|
+
"mkdocs-git-revision-date-localized-plugin",
|
|
72
|
+
"mkdocs-meta-descriptions-plugin",
|
|
71
73
|
"pngquant"
|
|
72
74
|
]
|
|
73
75
|
|
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
# MQTT Health Check Script
|
|
4
4
|
# Checks if the heartbeat timestamp in MQTT payload is recent enough
|
|
5
|
+
# Requires MQTT connection details to be available as environment variables
|
|
6
|
+
# - MQTT_HOST (defaults to localhost)
|
|
7
|
+
# - MQTT_PORT (defaults to 1883)
|
|
8
|
+
# - MQTT_USER (no default)
|
|
9
|
+
# - MQTT_PASS (no default)
|
|
5
10
|
|
|
6
11
|
# Arguments
|
|
7
12
|
MQTT_TOPIC=$1
|
|
@@ -14,7 +14,7 @@ import structlog
|
|
|
14
14
|
import updates2mqtt
|
|
15
15
|
from updates2mqtt.model import Discovery, ReleaseProvider
|
|
16
16
|
|
|
17
|
-
from .config import Config, load_app_config, load_package_info
|
|
17
|
+
from .config import Config, PackageUpdateInfo, load_app_config, load_package_info
|
|
18
18
|
from .integrations.docker import DockerProvider
|
|
19
19
|
from .mqtt import MqttPublisher
|
|
20
20
|
|
|
@@ -44,9 +44,9 @@ class App:
|
|
|
44
44
|
sys.exit(1)
|
|
45
45
|
self.cfg: Config = app_config
|
|
46
46
|
|
|
47
|
-
structlog.configure(wrapper_class=structlog.make_filtering_bound_logger(getattr(logging, self.cfg.log.level)))
|
|
47
|
+
structlog.configure(wrapper_class=structlog.make_filtering_bound_logger(getattr(logging, str(self.cfg.log.level))))
|
|
48
48
|
log.debug("Logging initialized", level=self.cfg.log.level)
|
|
49
|
-
self.common_pkg = load_package_info(PKG_INFO_FILE)
|
|
49
|
+
self.common_pkg: dict[str, PackageUpdateInfo] = load_package_info(PKG_INFO_FILE)
|
|
50
50
|
|
|
51
51
|
self.publisher = MqttPublisher(self.cfg.mqtt, self.cfg.node, self.cfg.homeassistant)
|
|
52
52
|
|
|
@@ -62,25 +62,29 @@ class App:
|
|
|
62
62
|
"App configured",
|
|
63
63
|
node=self.cfg.node.name,
|
|
64
64
|
scan_interval=self.cfg.scan_interval,
|
|
65
|
+
healthcheck_topic=self.healthcheck_topic,
|
|
65
66
|
)
|
|
66
67
|
|
|
67
68
|
async def scan(self) -> None:
|
|
68
69
|
session = uuid.uuid4().hex
|
|
69
70
|
for scanner in self.scanners:
|
|
70
|
-
log.
|
|
71
|
+
slog = log.bind(source_type=scanner.source_type, session=session)
|
|
72
|
+
slog.info("Cleaning topics before scan")
|
|
71
73
|
if self.scan_count == 0:
|
|
72
74
|
await self.publisher.clean_topics(scanner, None, force=True)
|
|
73
75
|
if self.stopped.is_set():
|
|
74
76
|
break
|
|
75
|
-
|
|
77
|
+
slog.info("Scanning ...")
|
|
76
78
|
async with asyncio.TaskGroup() as tg:
|
|
77
|
-
|
|
79
|
+
# xtype: ignore[attr-defined]
|
|
80
|
+
async for discovery in scanner.scan(session):
|
|
78
81
|
tg.create_task(self.on_discovery(discovery), name=f"discovery-{discovery.name}")
|
|
79
82
|
if self.stopped.is_set():
|
|
83
|
+
slog.debug("Breaking scan loop on stopped event")
|
|
80
84
|
break
|
|
81
85
|
await self.publisher.clean_topics(scanner, session, force=False)
|
|
82
86
|
self.scan_count += 1
|
|
83
|
-
|
|
87
|
+
slog.info(f"Scan #{self.scan_count} complete")
|
|
84
88
|
self.last_scan_timestamp = datetime.now(UTC).isoformat()
|
|
85
89
|
|
|
86
90
|
async def main_loop(self) -> None:
|
|
@@ -170,13 +174,15 @@ class App:
|
|
|
170
174
|
async def healthcheck(self) -> None:
|
|
171
175
|
if not self.publisher.is_available():
|
|
172
176
|
return
|
|
177
|
+
heartbeat_stamp: str = datetime.now(UTC).isoformat()
|
|
178
|
+
log.debug("Publishing health check", heartbeat_stamp=heartbeat_stamp)
|
|
173
179
|
self.publisher.publish(
|
|
174
180
|
topic=self.healthcheck_topic,
|
|
175
181
|
payload={
|
|
176
182
|
"version": updates2mqtt.version, # pyright: ignore[reportAttributeAccessIssue]
|
|
177
183
|
"node": self.cfg.node.name,
|
|
178
184
|
"heartbeat_raw": time.time(),
|
|
179
|
-
"heartbeat_stamp":
|
|
185
|
+
"heartbeat_stamp": heartbeat_stamp,
|
|
180
186
|
"startup_stamp": self.startup_timestamp,
|
|
181
187
|
"last_scan_stamp": self.last_scan_timestamp,
|
|
182
188
|
"scan_count": self.scan_count,
|
|
@@ -191,7 +197,7 @@ async def repeated_call(func: Callable, interval: int = 60, *args: Any, **kwargs
|
|
|
191
197
|
await func(*args, **kwargs)
|
|
192
198
|
await asyncio.sleep(interval)
|
|
193
199
|
except asyncio.CancelledError:
|
|
194
|
-
log.debug("Periodic task cancelled")
|
|
200
|
+
log.debug("Periodic task cancelled", func=func)
|
|
195
201
|
except Exception:
|
|
196
202
|
log.exception("Periodic task failed")
|
|
197
203
|
|
|
@@ -202,6 +208,7 @@ def run() -> None:
|
|
|
202
208
|
|
|
203
209
|
from .app import App
|
|
204
210
|
|
|
211
|
+
# pyright: ignore[reportAttributeAccessIssue]
|
|
205
212
|
log.debug(f"Starting updates2mqtt v{updates2mqtt.version}") # pyright: ignore[reportAttributeAccessIssue]
|
|
206
213
|
app = App()
|
|
207
214
|
|