dbus2mqtt 0.2.0__tar.gz → 0.3.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.
Potentially problematic release.
This version of dbus2mqtt might be problematic. Click here for more details.
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/release-drafter.yml +4 -3
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/workflows/ci.yml +9 -6
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/workflows/docker-dev.yml +9 -6
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/workflows/pre-commit.yml +5 -5
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/workflows/publish.yml +6 -5
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.pre-commit-config.yaml +4 -4
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/PKG-INFO +7 -5
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/README.md +5 -3
- dbus2mqtt-0.3.0/docs/examples/dbus2mqtt_internal_state.md +13 -0
- dbus2mqtt-0.3.0/docs/examples/dbus2mqtt_internal_state.yaml +40 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/docs/examples/home_assistant_media_player.md +42 -32
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/docs/examples/home_assistant_media_player.yaml +28 -7
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/docs/examples.md +1 -1
- dbus2mqtt-0.3.0/docs/flows.md +122 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/pyproject.toml +1 -1
- dbus2mqtt-0.2.0/src/dbus2mqtt/config.py → dbus2mqtt-0.3.0/src/dbus2mqtt/config/__init__.py +10 -8
- dbus2mqtt-0.3.0/src/dbus2mqtt/config/jsonarparse.py +31 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/dbus/dbus_client.py +61 -37
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/dbus/dbus_types.py +2 -2
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/dbus/dbus_util.py +2 -2
- dbus2mqtt-0.3.0/src/dbus2mqtt/dbus/introspection_patches/mpris_playerctl.py +151 -0
- dbus2mqtt-0.3.0/src/dbus2mqtt/dbus/introspection_patches/mpris_vlc.py +122 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/event_broker.py +1 -1
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/flow/actions/mqtt_publish.py +12 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/flow/flow_processor.py +28 -26
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/main.py +12 -9
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/mqtt/mqtt_client.py +31 -19
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/template/dbus_template_functions.py +2 -2
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/template/templating.py +3 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/tests/__init__.py +9 -11
- dbus2mqtt-0.3.0/tests/config/fixtures/payload_template_jinja_expressions.yaml +19 -0
- dbus2mqtt-0.3.0/tests/config/fixtures/payload_template_off.yaml +14 -0
- dbus2mqtt-0.3.0/tests/config/fixtures/schedule_cron_trigger.yaml +9 -0
- dbus2mqtt-0.3.0/tests/config/test_config.py +70 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/tests/config/test_examples.py +3 -4
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/tests/dbus/test_dbus_client.py +10 -8
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/tests/flow/triggers/test_dbus_client_triggers.py +14 -6
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/tests/template/test_templating.py +4 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/uv.lock +342 -310
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.dockerignore +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.env.example +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/scripts/release-versions.py +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/workflows/docker-stable.yml +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/workflows/release-drafter.yml +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.gitignore +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.python-version +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.vscode/launch.json +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.vscode/settings.json +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.yamllint.yml +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/LICENSE +0 -0
- /dbus2mqtt-0.2.0/docker/Dockerfile.latest → /dbus2mqtt-0.3.0/docker/Dockerfile.dev +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/docker/Dockerfile.pypi +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/docs/debugging.md +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/docs/examples/linux_desktop.md +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/docs/examples/linux_desktop.yaml +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/renovate.json +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/__init__.py +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/__main__.py +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/flow/__init__.py +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/flow/actions/context_set.py +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/tests/flow/actions/test_context_set.py +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/tests/flow/actions/test_mqtt_publish.py +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/tests/flow/test_flow_processor.py +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/tests/template/test_templating_config.py +0 -0
|
@@ -3,7 +3,7 @@ tag-template: 'v$RESOLVED_VERSION'
|
|
|
3
3
|
exclude-labels:
|
|
4
4
|
- dependencies
|
|
5
5
|
categories:
|
|
6
|
-
- title:
|
|
6
|
+
- title: 🚨 Breaking changes
|
|
7
7
|
labels:
|
|
8
8
|
- breaking-change
|
|
9
9
|
- title: 🚀 Features
|
|
@@ -12,13 +12,14 @@ categories:
|
|
|
12
12
|
- enhancement
|
|
13
13
|
- title: 🐛 Bug Fixes
|
|
14
14
|
labels:
|
|
15
|
-
- fix
|
|
16
15
|
- bugfix
|
|
17
|
-
- bug
|
|
18
16
|
- title: 🧰 Maintenance
|
|
19
17
|
labels:
|
|
20
18
|
- chore
|
|
21
19
|
- documentation
|
|
20
|
+
- title: ⬆️ Dependency updates
|
|
21
|
+
labels:
|
|
22
|
+
- "dependencies"
|
|
22
23
|
exclude-contributors:
|
|
23
24
|
- jwnmulder
|
|
24
25
|
autolabeler:
|
|
@@ -24,14 +24,17 @@ jobs:
|
|
|
24
24
|
- uses: actions/checkout@v4
|
|
25
25
|
|
|
26
26
|
- name: Install uv
|
|
27
|
-
uses: astral-sh/setup-uv@
|
|
27
|
+
uses: astral-sh/setup-uv@v6
|
|
28
28
|
with:
|
|
29
|
+
activate-environment: true
|
|
29
30
|
enable-cache: true
|
|
30
|
-
|
|
31
|
-
- name: "Set up Python"
|
|
32
|
-
uses: actions/setup-python@v5
|
|
33
|
-
with:
|
|
34
31
|
python-version: ${{ matrix.python-version }}
|
|
35
32
|
|
|
33
|
+
# - name: "Set up Python"
|
|
34
|
+
# uses: actions/setup-python@v5
|
|
35
|
+
# with:
|
|
36
|
+
# python-version: ${{ matrix.python-version }}
|
|
37
|
+
|
|
36
38
|
- name: Run tests
|
|
37
|
-
run: uv run
|
|
39
|
+
run: uv run pytest
|
|
40
|
+
# run: uv run --python ${{ matrix.python-version }} pytest
|
|
@@ -4,6 +4,9 @@ name: docker-dev
|
|
|
4
4
|
push:
|
|
5
5
|
branches:
|
|
6
6
|
- main
|
|
7
|
+
paths-ignore:
|
|
8
|
+
- 'docs/**'
|
|
9
|
+
- '.pre-commit-config.yaml'
|
|
7
10
|
workflow_dispatch:
|
|
8
11
|
|
|
9
12
|
jobs:
|
|
@@ -16,14 +19,14 @@ jobs:
|
|
|
16
19
|
uses: actions/checkout@v4
|
|
17
20
|
|
|
18
21
|
- name: Install uv
|
|
19
|
-
uses: astral-sh/setup-uv@
|
|
22
|
+
uses: astral-sh/setup-uv@v6
|
|
20
23
|
with:
|
|
21
24
|
enable-cache: true
|
|
22
25
|
|
|
23
|
-
- name: "Set up Python"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
# - name: "Set up Python"
|
|
27
|
+
# uses: actions/setup-python@v5
|
|
28
|
+
# with:
|
|
29
|
+
# python-version-file: ".python-version"
|
|
27
30
|
|
|
28
31
|
- name: Determine version from hatch
|
|
29
32
|
id: version
|
|
@@ -66,7 +69,7 @@ jobs:
|
|
|
66
69
|
uses: docker/build-push-action@v6
|
|
67
70
|
with:
|
|
68
71
|
context: .
|
|
69
|
-
file: ./docker/Dockerfile.
|
|
72
|
+
file: ./docker/Dockerfile.dev
|
|
70
73
|
push: ${{ github.event_name != 'pull_request' }}
|
|
71
74
|
tags: ${{ steps.meta.outputs.tags }}
|
|
72
75
|
labels: ${{ steps.meta.outputs.labels }}
|
|
@@ -16,12 +16,12 @@ jobs:
|
|
|
16
16
|
- uses: actions/checkout@v4
|
|
17
17
|
|
|
18
18
|
- name: Install uv
|
|
19
|
-
uses: astral-sh/setup-uv@
|
|
19
|
+
uses: astral-sh/setup-uv@v6
|
|
20
20
|
|
|
21
|
-
- name: "Set up Python"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
# - name: "Set up Python"
|
|
22
|
+
# uses: actions/setup-python@v5
|
|
23
|
+
# with:
|
|
24
|
+
# python-version-file: ".python-version"
|
|
25
25
|
|
|
26
26
|
- name: Uv sync
|
|
27
27
|
run: uv sync
|
|
@@ -17,14 +17,15 @@ jobs:
|
|
|
17
17
|
persist-credentials: false
|
|
18
18
|
|
|
19
19
|
- name: Install uv
|
|
20
|
-
uses: astral-sh/setup-uv@
|
|
20
|
+
uses: astral-sh/setup-uv@v6
|
|
21
21
|
with:
|
|
22
|
+
activate-environment: true
|
|
22
23
|
enable-cache: true
|
|
23
24
|
|
|
24
|
-
- name: "Set up Python"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
# - name: "Set up Python"
|
|
26
|
+
# uses: actions/setup-python@v5
|
|
27
|
+
# with:
|
|
28
|
+
# python-version-file: ".python-version"
|
|
28
29
|
|
|
29
30
|
- name: Build
|
|
30
31
|
run: uv build
|
|
@@ -26,14 +26,14 @@ repos:
|
|
|
26
26
|
- id: codespell
|
|
27
27
|
|
|
28
28
|
- repo: https://github.com/adrienverge/yamllint.git
|
|
29
|
-
rev: v1.37.
|
|
29
|
+
rev: v1.37.1
|
|
30
30
|
hooks:
|
|
31
31
|
- id: yamllint
|
|
32
32
|
args:
|
|
33
33
|
- --strict
|
|
34
34
|
|
|
35
35
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
36
|
-
rev: v0.11.
|
|
36
|
+
rev: v0.11.9
|
|
37
37
|
hooks:
|
|
38
38
|
- id: ruff
|
|
39
39
|
args:
|
|
@@ -42,11 +42,11 @@ repos:
|
|
|
42
42
|
- I
|
|
43
43
|
|
|
44
44
|
- repo: https://github.com/astral-sh/uv-pre-commit
|
|
45
|
-
rev: 0.
|
|
45
|
+
rev: 0.7.3
|
|
46
46
|
hooks:
|
|
47
47
|
- id: uv-lock
|
|
48
48
|
|
|
49
49
|
- repo: https://github.com/RobertCraigie/pyright-python
|
|
50
|
-
rev: v1.1.
|
|
50
|
+
rev: v1.1.400
|
|
51
51
|
hooks:
|
|
52
52
|
- id: pyright
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dbus2mqtt
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: A Python tool to expose Linux D-Bus signals, methods and properties over MQTT - featuring templating, payload enrichment and Home Assistant-ready examples
|
|
5
5
|
Project-URL: Repository, https://github.com/jwnmulder/dbus2mqtt.git
|
|
6
6
|
Project-URL: Issues, https://github.com/jwnmulder/dbus2mqtt/issues
|
|
@@ -19,7 +19,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
20
|
Requires-Dist: apscheduler>=3.11.0
|
|
21
21
|
Requires-Dist: colorlog>=6.9.0
|
|
22
|
-
Requires-Dist: dbus-
|
|
22
|
+
Requires-Dist: dbus-fast>=2.44.1
|
|
23
23
|
Requires-Dist: janus>=2.0.0
|
|
24
24
|
Requires-Dist: jinja2-ansible-filters>=1.3.2
|
|
25
25
|
Requires-Dist: jinja2>=3.1.6
|
|
@@ -111,7 +111,7 @@ cp docs/examples/home_assistant_media_player.yaml $HOME/.config/dbus2mqtt/config
|
|
|
111
111
|
cp .env.example $HOME/.config/dbus2mqtt/.env
|
|
112
112
|
|
|
113
113
|
# run image and automatically start on reboot
|
|
114
|
-
|
|
114
|
+
docker pull jwnmulder/dbus2mqtt
|
|
115
115
|
docker run --detach --name dbus2mqtt \
|
|
116
116
|
--volume "$HOME"/.config/dbus2mqtt:"$HOME"/.config/dbus2mqtt \
|
|
117
117
|
--volume /run/user:/run/user \
|
|
@@ -138,7 +138,7 @@ dbus2mqtt leverages [jsonargparse](https://jsonargparse.readthedocs.io/en/stable
|
|
|
138
138
|
### MQTT and D-Bus connection details
|
|
139
139
|
|
|
140
140
|
```bash
|
|
141
|
-
#
|
|
141
|
+
# dbus_fast configuration
|
|
142
142
|
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
|
|
143
143
|
|
|
144
144
|
# dbus2mqtt configuration
|
|
@@ -171,7 +171,9 @@ dbus:
|
|
|
171
171
|
- method: Play
|
|
172
172
|
```
|
|
173
173
|
|
|
174
|
-
This configuration will expose 2 methods. Triggering methods can be done by publishing json messages to the `dbus2mqtt/org.mpris.MediaPlayer2/command` MQTT topic. Arguments can be passed along in `args
|
|
174
|
+
This configuration will expose 2 methods. Triggering methods can be done by publishing json messages to the `dbus2mqtt/org.mpris.MediaPlayer2/command` MQTT topic. Arguments can be passed along in `args`.
|
|
175
|
+
|
|
176
|
+
Note that methods are called on **all** bus_names matching the configured pattern
|
|
175
177
|
|
|
176
178
|
```json
|
|
177
179
|
{
|
|
@@ -79,7 +79,7 @@ cp docs/examples/home_assistant_media_player.yaml $HOME/.config/dbus2mqtt/config
|
|
|
79
79
|
cp .env.example $HOME/.config/dbus2mqtt/.env
|
|
80
80
|
|
|
81
81
|
# run image and automatically start on reboot
|
|
82
|
-
|
|
82
|
+
docker pull jwnmulder/dbus2mqtt
|
|
83
83
|
docker run --detach --name dbus2mqtt \
|
|
84
84
|
--volume "$HOME"/.config/dbus2mqtt:"$HOME"/.config/dbus2mqtt \
|
|
85
85
|
--volume /run/user:/run/user \
|
|
@@ -106,7 +106,7 @@ dbus2mqtt leverages [jsonargparse](https://jsonargparse.readthedocs.io/en/stable
|
|
|
106
106
|
### MQTT and D-Bus connection details
|
|
107
107
|
|
|
108
108
|
```bash
|
|
109
|
-
#
|
|
109
|
+
# dbus_fast configuration
|
|
110
110
|
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
|
|
111
111
|
|
|
112
112
|
# dbus2mqtt configuration
|
|
@@ -139,7 +139,9 @@ dbus:
|
|
|
139
139
|
- method: Play
|
|
140
140
|
```
|
|
141
141
|
|
|
142
|
-
This configuration will expose 2 methods. Triggering methods can be done by publishing json messages to the `dbus2mqtt/org.mpris.MediaPlayer2/command` MQTT topic. Arguments can be passed along in `args
|
|
142
|
+
This configuration will expose 2 methods. Triggering methods can be done by publishing json messages to the `dbus2mqtt/org.mpris.MediaPlayer2/command` MQTT topic. Arguments can be passed along in `args`.
|
|
143
|
+
|
|
144
|
+
Note that methods are called on **all** bus_names matching the configured pattern
|
|
143
145
|
|
|
144
146
|
```json
|
|
145
147
|
{
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# dbus2mqtt internal state example
|
|
2
|
+
|
|
3
|
+
Execute the following command to run dbus2mqtt with the example configuration in this repository.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
dbus2mqtt --config docs/examples/dbus2mqtt_internal_state.yaml
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
This will publish the dbus2mqtt's internal state to the `dbus2mqtt/state` MQTT topic every 5 seconds
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{"now": "2025-04-23T16:01:34.985452", "dbus_list": ["org.freedesktop.systemd1", "org.gnome.SessionManager"]}
|
|
13
|
+
```
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# mqtt:
|
|
2
|
+
# host:
|
|
3
|
+
# port:
|
|
4
|
+
|
|
5
|
+
dbus:
|
|
6
|
+
subscriptions:
|
|
7
|
+
|
|
8
|
+
# https://manpages.ubuntu.com/manpages/lunar/man5/org.freedesktop.systemd1.5.html
|
|
9
|
+
- bus_name: org.freedesktop.systemd1
|
|
10
|
+
path: /org/freedesktop/systemd1
|
|
11
|
+
interfaces:
|
|
12
|
+
- interface: org.freedesktop.DBus.Properties
|
|
13
|
+
signals:
|
|
14
|
+
- signal: PropertiesChanged
|
|
15
|
+
methods:
|
|
16
|
+
- method: GetAll
|
|
17
|
+
|
|
18
|
+
# https://lira.no-ip.org:8443/doc/gnome-session/dbus/gnome-session.html
|
|
19
|
+
- bus_name: org.gnome.SessionManager
|
|
20
|
+
path: /org/gnome/SessionManager
|
|
21
|
+
interfaces:
|
|
22
|
+
- interface: org.freedesktop.DBus.Properties
|
|
23
|
+
signals:
|
|
24
|
+
- signal: PropertiesChanged
|
|
25
|
+
methods:
|
|
26
|
+
- method: GetAll
|
|
27
|
+
|
|
28
|
+
flows:
|
|
29
|
+
- name: "publish internal state"
|
|
30
|
+
triggers:
|
|
31
|
+
- type: bus_name_added
|
|
32
|
+
- type: schedule
|
|
33
|
+
interval: {seconds: 5}
|
|
34
|
+
actions:
|
|
35
|
+
- type: mqtt_publish
|
|
36
|
+
topic: dbus2mqtt/state
|
|
37
|
+
payload_type: json
|
|
38
|
+
payload_template:
|
|
39
|
+
now: "{{ now().isoformat() }}"
|
|
40
|
+
dbus_list: "{{ dbus_list('*') }}"
|
|
@@ -6,8 +6,8 @@ The Media Player Remote Interfacing Specification (MPRIS) is a standard for cont
|
|
|
6
6
|
|
|
7
7
|
Pre-requisites:
|
|
8
8
|
|
|
9
|
-
* Home-Assistant with a working MQTT setup
|
|
10
|
-
|
|
9
|
+
* Home-Assistant with a working MQTT setup
|
|
10
|
+
* The [media_player.template](https://github.com/Sennevds/media_player.template/tree/master) plugin
|
|
11
11
|
|
|
12
12
|
Features:
|
|
13
13
|
|
|
@@ -27,21 +27,23 @@ Execute the following command to run dbus2mqtt with the example configuration in
|
|
|
27
27
|
dbus2mqtt --config docs/examples/home_assistant_media_player.yaml
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
|
|
31
30
|
## Tested configurations
|
|
32
31
|
|
|
33
32
|
The following setup is known to work with Home Assistant.
|
|
34
33
|
|
|
35
|
-
| Application | Play<br />Pause<br /> | Stop | Next<br />Previous | Seek<br />SetPosition | Volume | Quit | Media Info | Media Image |
|
|
36
|
-
|
|
37
|
-
| `Firefox` | ✅ | ✅ | ✅ | ✅ |
|
|
38
|
-
| `VLC`
|
|
34
|
+
| Application | Play<br />Pause<br /> | Stop | Next<br />Previous | Seek<br />SetPosition | Volume | Quit | Media Info | Media Image | Notes
|
|
35
|
+
|--------------|-----------------------|------|--------------------|------|--------|------|------------|-------------|-------------------|
|
|
36
|
+
| `Firefox` | ✅ | ✅ | ✅ | ✅ | | ❌ | ✅ | ✅ | |
|
|
37
|
+
| `VLC` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | |
|
|
38
|
+
| `Chromium` | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✔️ | Not working when running as snap |
|
|
39
|
+
|
|
40
|
+
More players that support MPRIS can be found here: <https://wiki.archlinux.org/title/MPRIS>
|
|
39
41
|
|
|
40
42
|
## Player commands
|
|
41
43
|
|
|
42
44
|
The following table lists player commands, their descriptions, and an example JSON payload for invoking them via MQTT.
|
|
43
45
|
|
|
44
|
-
Dbus methods can be invoked by sendig the JSON payload to MQTT topic `dbus2mqtt/org.mpris.MediaPlayer2/command`. Method calls will be done for all matching players
|
|
46
|
+
Dbus methods can be invoked by sendig the JSON payload to MQTT topic `dbus2mqtt/org.mpris.MediaPlayer2/command`. Method calls will be done for all matching players. The same applies to property updates.
|
|
45
47
|
|
|
46
48
|
| Interface | Method<br />Property | Description | Example MQTT JSON Payload |
|
|
47
49
|
|---------------------------------|---------------|------------------------------------------|------------------------------------------------|
|
|
@@ -52,7 +54,7 @@ Dbus methods can be invoked by sendig the JSON payload to MQTT topic `dbus2mqtt/
|
|
|
52
54
|
| `org.mpris.MediaPlayer2.Player` | `Previous` | Previous | `{ "method": "Previous" }` |
|
|
53
55
|
| `org.mpris.MediaPlayer2.Player` | `Stop` | Stops playback | `{ "method": "Stop" }` |
|
|
54
56
|
| `org.mpris.MediaPlayer2.Player` | `Seek` | Seek forward or backward in micro seconds | `{ "method": "Seek", "args": [60000000] }` |
|
|
55
|
-
| `org.mpris.MediaPlayer2.Player` | `Volume` | Set volume
|
|
57
|
+
| `org.mpris.MediaPlayer2.Player` | `Volume` | Set volume (double between 0 and 1) | `{ "property": "Volume", "value": 1.0 }` |
|
|
56
58
|
| `org.mpris.MediaPlayer2.Player` | `SetPosition` | Set / seek to position in micro seconds. First arguments needs to be trackid which can be determined via Metadata.mpris:trackid | `{ "method": "SetPosition", "args": ["/org/mpris/MediaPlayer2/firefox", 170692139] }` |
|
|
57
59
|
| `org.mpris.MediaPlayer2` | `Quit` | Quits the media player | `{ "method": "Quit" }` |
|
|
58
60
|
|
|
@@ -73,15 +75,11 @@ mqtt:
|
|
|
73
75
|
json_attributes_topic: dbus2mqtt/org.mpris.MediaPlayer2/state
|
|
74
76
|
value_template: >-
|
|
75
77
|
{% set status = value_json.PlaybackStatus %}
|
|
76
|
-
{
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
idle
|
|
82
|
-
{% else %}
|
|
83
|
-
off
|
|
84
|
-
{% endif %}
|
|
78
|
+
{{ {'Playing': 'playing', 'Paused': 'paused', 'Stopped': 'idle'}.get(status, 'off') }}
|
|
79
|
+
|
|
80
|
+
image:
|
|
81
|
+
- name: MPRIS Media Player MQTT image
|
|
82
|
+
image_topic: dbus2mqtt/org.mpris.MediaPlayer2/artUrlImage
|
|
85
83
|
|
|
86
84
|
media_player:
|
|
87
85
|
- platform: media_player_template
|
|
@@ -94,21 +92,31 @@ media_player:
|
|
|
94
92
|
current_volume_template: "{{ state_attr('sensor.mpris_media_player', 'Volume') }}"
|
|
95
93
|
current_is_muted_template: "{{ state_attr('sensor.mpris_media_player', 'Volume') == 0 }}"
|
|
96
94
|
current_position_template: "{{ state_attr('sensor.mpris_media_player', 'Position') }}"
|
|
97
|
-
title_template: "{{ state_attr('sensor.mpris_media_player', 'Metadata')
|
|
95
|
+
title_template: "{{ (state_attr('sensor.mpris_media_player', 'Metadata') or {}).get('xesam:title', '') }}"
|
|
98
96
|
|
|
99
97
|
media_content_type_template: music # needed to show 'artist'
|
|
100
|
-
media_duration_template: "{{ state_attr('sensor.mpris_media_player', 'Metadata')
|
|
101
|
-
album_template: "{{ state_attr('sensor.mpris_media_player', 'Metadata')
|
|
102
|
-
artist_template: "{{ state_attr('sensor.mpris_media_player', 'Metadata')
|
|
98
|
+
media_duration_template: "{{ (state_attr('sensor.mpris_media_player', 'Metadata') or {}).get('mpris:length', 0) }}"
|
|
99
|
+
album_template: "{{ (state_attr('sensor.mpris_media_player', 'Metadata') or {}).get('xesam:album', '') }}"
|
|
100
|
+
artist_template: "{{ (state_attr('sensor.mpris_media_player', 'Metadata') or {}).get('xesam:artist', ['']) | first }}"
|
|
103
101
|
|
|
104
|
-
# mpris:artUrl
|
|
102
|
+
# mpris:artUrl might contain a file:// schema. In these cases we rely on images published via MQTT
|
|
105
103
|
media_image_url_template: >-
|
|
106
|
-
{
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
104
|
+
{% set mpris_metadata = state_attr('sensor.mpris_media_player', 'Metadata') or {} %}
|
|
105
|
+
{% set mpris_art_url = mpris_metadata.get('mpris:artUrl', '') %}
|
|
106
|
+
{% set mpris_url = mpris_metadata.get('xesam:url') %}
|
|
107
|
+
|
|
108
|
+
{% if mpris_art_url.startswith('http') %}
|
|
109
|
+
{{ mpris_art_url }}
|
|
110
|
+
{% elif mpris_art_url.startswith('file://') %}
|
|
111
|
+
http://127.0.0.1:8123{{ state_attr('image.mpris_media_player_mqtt_image', 'entity_picture') }}
|
|
112
|
+
{% else %}
|
|
113
|
+
{{
|
|
114
|
+
mpris_url | regex_replace(
|
|
115
|
+
find='https:\/\/www\\.youtube\\.com\/watch\\?v=([^&]+).*',
|
|
116
|
+
replace='https://img.youtube.com/vi/\\1/maxresdefault.jpg'
|
|
117
|
+
)
|
|
118
|
+
}}
|
|
119
|
+
{% endif %}
|
|
112
120
|
|
|
113
121
|
turn_off:
|
|
114
122
|
service: mqtt.publish
|
|
@@ -144,7 +152,7 @@ media_player:
|
|
|
144
152
|
service: mqtt.publish
|
|
145
153
|
data:
|
|
146
154
|
topic: dbus2mqtt/org.mpris.MediaPlayer2/command
|
|
147
|
-
payload:
|
|
155
|
+
payload: >
|
|
148
156
|
{ "method": "SetPosition", "args": ["{{ state_attr('sensor.mpris_media_player', 'Metadata')['mpris:trackid'] }}", {{ position | int }}] }
|
|
149
157
|
set_volume:
|
|
150
158
|
service: mqtt.publish
|
|
@@ -155,10 +163,12 @@ media_player:
|
|
|
155
163
|
service: mqtt.publish
|
|
156
164
|
data:
|
|
157
165
|
topic: dbus2mqtt/org.mpris.MediaPlayer2/command
|
|
158
|
-
payload:
|
|
166
|
+
payload: >
|
|
167
|
+
{"property": "Volume", "value": {{ [1, (state_attr('sensor.mpris_media_player', 'Volume') + 0.1)] | min }} }
|
|
159
168
|
volume_down:
|
|
160
169
|
service: mqtt.publish
|
|
161
170
|
data:
|
|
162
171
|
topic: dbus2mqtt/org.mpris.MediaPlayer2/command
|
|
163
|
-
payload:
|
|
172
|
+
payload: >
|
|
173
|
+
{"property": "Volume", "value": {{ [0, (state_attr('sensor.mpris_media_player', 'Volume') - 0.1)] | max }} }
|
|
164
174
|
```
|
|
@@ -24,6 +24,8 @@ dbus:
|
|
|
24
24
|
|
|
25
25
|
- interface: org.mpris.MediaPlayer2.Player
|
|
26
26
|
mqtt_command_topic: dbus2mqtt/org.mpris.MediaPlayer2/command
|
|
27
|
+
signals:
|
|
28
|
+
- signal: Seeked
|
|
27
29
|
methods:
|
|
28
30
|
- method: Pause
|
|
29
31
|
- method: Play
|
|
@@ -38,7 +40,7 @@ dbus:
|
|
|
38
40
|
- property: Volume
|
|
39
41
|
|
|
40
42
|
flows:
|
|
41
|
-
- name: "
|
|
43
|
+
- name: "publish player state"
|
|
42
44
|
triggers:
|
|
43
45
|
- type: bus_name_added
|
|
44
46
|
- type: schedule
|
|
@@ -47,17 +49,18 @@ dbus:
|
|
|
47
49
|
interface: org.freedesktop.DBus.Properties
|
|
48
50
|
signal: PropertiesChanged
|
|
49
51
|
# filter: "{{ args[0] == 'org.mpris.MediaPlayer2.Player' }}"
|
|
52
|
+
- type: dbus_signal
|
|
53
|
+
interface: org.mpris.MediaPlayer2.Player
|
|
54
|
+
signal: Seeked
|
|
50
55
|
actions:
|
|
51
56
|
- type: context_set
|
|
52
57
|
context:
|
|
53
58
|
mpris_bus_name: '{{ dbus_list("org.mpris.MediaPlayer2.*") | first }}'
|
|
54
|
-
|
|
59
|
+
mpris_path: /org/mpris/MediaPlayer2
|
|
55
60
|
- type: context_set
|
|
56
61
|
context:
|
|
57
62
|
player_properties: |
|
|
58
|
-
{{ dbus_call(mpris_bus_name,
|
|
59
|
-
volume: |
|
|
60
|
-
{{ dbus_property_get(mpris_bus_name, path, 'org.mpris.MediaPlayer2.Player', 'Volume', 0) }}
|
|
63
|
+
{{ dbus_call(mpris_bus_name, mpris_path, 'org.freedesktop.DBus.Properties', 'GetAll', ['org.mpris.MediaPlayer2.Player']) }}
|
|
61
64
|
- type: mqtt_publish
|
|
62
65
|
topic: dbus2mqtt/org.mpris.MediaPlayer2/state
|
|
63
66
|
payload_type: json
|
|
@@ -65,9 +68,27 @@ dbus:
|
|
|
65
68
|
{{
|
|
66
69
|
{ 'bus_name': mpris_bus_name }
|
|
67
70
|
| combine(player_properties)
|
|
68
|
-
| combine({ 'Volume': volume })
|
|
69
71
|
}}
|
|
70
|
-
|
|
72
|
+
|
|
73
|
+
- name: "publish local art image"
|
|
74
|
+
# mpris:artUrl can have a file:// or http:// schema
|
|
75
|
+
# Home Assistant is unable to access file:// so we use MQTT for that
|
|
76
|
+
triggers:
|
|
77
|
+
- type: bus_name_added
|
|
78
|
+
- type: dbus_signal
|
|
79
|
+
interface: org.freedesktop.DBus.Properties
|
|
80
|
+
signal: PropertiesChanged
|
|
81
|
+
actions:
|
|
82
|
+
- type: context_set
|
|
83
|
+
context:
|
|
84
|
+
artUrl: "{{ (dbus_property_get(bus_name, path, 'org.mpris.MediaPlayer2.Player', 'Metadata') or {}).get('mpris:artUrl') }}"
|
|
85
|
+
- type: mqtt_publish
|
|
86
|
+
topic: dbus2mqtt/org.mpris.MediaPlayer2/artUrlImage
|
|
87
|
+
payload_type: binary
|
|
88
|
+
payload_template: |
|
|
89
|
+
{{ artUrl if artUrl and artUrl.startswith('file://') else None }}
|
|
90
|
+
|
|
91
|
+
- name: "player removed"
|
|
71
92
|
triggers:
|
|
72
93
|
- type: bus_name_removed
|
|
73
94
|
# filter: # TODO: Check if this is the last or inactive one #
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Flows
|
|
2
|
+
|
|
3
|
+
**dbus2mqtt** allows you to add additional processing logic (flows) for when events occur. Configuration is best done in yaml and a complete example can be found here: [MPRIS to Home Assistant Media Player integration](https://github.com/jwnmulder/dbus2mqtt/blob/main/docs/examples/home_assistant_media_player.md)
|
|
4
|
+
|
|
5
|
+
Flows can be defined on a global or dbus subscription level and can be triggered by any of the following events:
|
|
6
|
+
|
|
7
|
+
* `schedule` for cron based schedules
|
|
8
|
+
* `dbus_signal` for when dbus signal occur
|
|
9
|
+
* `bus_name_added` when a new bus_name is registered on dbus
|
|
10
|
+
* `bus_name_removed` when a bus_name is removed from dbus
|
|
11
|
+
|
|
12
|
+
Within each flow a set of actions can be configured. These are executed in order
|
|
13
|
+
|
|
14
|
+
* `context_set` to set variables
|
|
15
|
+
* `mqtt_publish` to publish a mqtt message
|
|
16
|
+
|
|
17
|
+
Actions support string templating which is based on jinja2
|
|
18
|
+
|
|
19
|
+
## Flow triggers
|
|
20
|
+
|
|
21
|
+
### schedule
|
|
22
|
+
|
|
23
|
+
```yaml
|
|
24
|
+
type: schedule
|
|
25
|
+
cron: {second: 5}
|
|
26
|
+
interval: {seconds: 5}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Schedule based triggers can be configured by setting either a cron or interval parameter. Scheduling is based on the APScheduler library and allows the following configuration options
|
|
30
|
+
|
|
31
|
+
| key | description |
|
|
32
|
+
|------|-------------|
|
|
33
|
+
| interval | dict of time units and intervals, see <https://apscheduler.readthedocs.io/en/3.x/modules/triggers/interval.html> |
|
|
34
|
+
| cron | dict of time units and cron expressions, see <https://apscheduler.readthedocs.io/en/3.x/modules/triggers/cron.html> |
|
|
35
|
+
|
|
36
|
+
When triggered, the following context parameters are available
|
|
37
|
+
|
|
38
|
+
| name | description |
|
|
39
|
+
|------|-------------|
|
|
40
|
+
| N/A | N/A |
|
|
41
|
+
|
|
42
|
+
### dbus_signal
|
|
43
|
+
|
|
44
|
+
DBus signals triggers must be configured with an anterface and path. Note that only subscribed signals can be configured as a trigger.
|
|
45
|
+
|
|
46
|
+
| key | description |
|
|
47
|
+
|------|-------------|
|
|
48
|
+
| interface | interface to filter on, e.g. 'org.freedesktop.DBus.Properties' |
|
|
49
|
+
| signal | signal name to filter on, e.g. PropertiesChanged |
|
|
50
|
+
|
|
51
|
+
When triggered, the following context parameters are available
|
|
52
|
+
|
|
53
|
+
| name | type | description |
|
|
54
|
+
|------|------|-------------|
|
|
55
|
+
| bus_name | string | bus_name of the object that was registered on dbus |
|
|
56
|
+
| path | string | bus_name path of the object that was registered on dbus |
|
|
57
|
+
| interface | string | name of interface for which the signal was triggered |
|
|
58
|
+
| args | list | signal arguments, list of objects |
|
|
59
|
+
|
|
60
|
+
### bus_name_added
|
|
61
|
+
|
|
62
|
+
```yaml
|
|
63
|
+
type: bus_name_added
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
When triggered, the following context parameters are available
|
|
67
|
+
|
|
68
|
+
| name | description |
|
|
69
|
+
|------|-------------|
|
|
70
|
+
| bus_name | bus_name of the object that was registered on dbus |
|
|
71
|
+
| path | bus_name path of the object that was registered on dbus |
|
|
72
|
+
|
|
73
|
+
### bus_name_removed
|
|
74
|
+
|
|
75
|
+
```yaml
|
|
76
|
+
type: bus_name_removed
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
When triggered, the following context parameters are available
|
|
80
|
+
|
|
81
|
+
| name | description |
|
|
82
|
+
|------|-------------|
|
|
83
|
+
| bus_name | bus_name of the object that was registered on dbus |
|
|
84
|
+
| path | bus_name path of the object that was registered on dbus |
|
|
85
|
+
|
|
86
|
+
## Flow actions
|
|
87
|
+
|
|
88
|
+
### context_set
|
|
89
|
+
|
|
90
|
+
```yaml
|
|
91
|
+
type: context_set
|
|
92
|
+
context: {}
|
|
93
|
+
dbus_object_context: {}
|
|
94
|
+
global_context: {}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
| key | type | description |
|
|
98
|
+
|---------------------|------------------|--------------|
|
|
99
|
+
| context | dict | Per flow execution context. Value can be a dict of strings or dict of templated strings |
|
|
100
|
+
| dbus_object_context | dict | Per dbus object context, shared between multiple flow executions. Value can be a dict of strings or dict of templated strings |
|
|
101
|
+
| global_context | dict | Global context, shared between multiple flow executions, over all subscriptions. Value can be a dict of strings or dict of templated strings |
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
### mqtt_publish
|
|
106
|
+
|
|
107
|
+
```yaml
|
|
108
|
+
type: mqtt_publish
|
|
109
|
+
topic: dbus2mqtt/org.mpris.MediaPlayer2/state
|
|
110
|
+
payload_type: json
|
|
111
|
+
payload_template: {PlaybackStatus: "Off"}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
| key | type | description |
|
|
115
|
+
|------------------|------------------|-------------|
|
|
116
|
+
| topic | string | mqtt topic the messaage is published to |
|
|
117
|
+
| payload_type | string | any of [json, yaml, text], defaults to json, format the message is published in to mqtt |
|
|
118
|
+
| payload_template | string, dict | value can be a string, a dict of strings, a templated string or a nested dict of templated strings |
|
|
119
|
+
|
|
120
|
+
## Jinja2 based templating
|
|
121
|
+
|
|
122
|
+
Some configuration values allow the use of jinja 2 templating. dbus2mqtt supports both the builtin filters and comes with additional filters from [jinja2-ansible-filters](https://pypi.org/project/jinja2-ansible-filters/)
|