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.

Files changed (66) hide show
  1. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/release-drafter.yml +4 -3
  2. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/workflows/ci.yml +9 -6
  3. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/workflows/docker-dev.yml +9 -6
  4. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/workflows/pre-commit.yml +5 -5
  5. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/workflows/publish.yml +6 -5
  6. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.pre-commit-config.yaml +4 -4
  7. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/PKG-INFO +7 -5
  8. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/README.md +5 -3
  9. dbus2mqtt-0.3.0/docs/examples/dbus2mqtt_internal_state.md +13 -0
  10. dbus2mqtt-0.3.0/docs/examples/dbus2mqtt_internal_state.yaml +40 -0
  11. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/docs/examples/home_assistant_media_player.md +42 -32
  12. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/docs/examples/home_assistant_media_player.yaml +28 -7
  13. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/docs/examples.md +1 -1
  14. dbus2mqtt-0.3.0/docs/flows.md +122 -0
  15. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/pyproject.toml +1 -1
  16. dbus2mqtt-0.2.0/src/dbus2mqtt/config.py → dbus2mqtt-0.3.0/src/dbus2mqtt/config/__init__.py +10 -8
  17. dbus2mqtt-0.3.0/src/dbus2mqtt/config/jsonarparse.py +31 -0
  18. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/dbus/dbus_client.py +61 -37
  19. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/dbus/dbus_types.py +2 -2
  20. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/dbus/dbus_util.py +2 -2
  21. dbus2mqtt-0.3.0/src/dbus2mqtt/dbus/introspection_patches/mpris_playerctl.py +151 -0
  22. dbus2mqtt-0.3.0/src/dbus2mqtt/dbus/introspection_patches/mpris_vlc.py +122 -0
  23. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/event_broker.py +1 -1
  24. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/flow/actions/mqtt_publish.py +12 -0
  25. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/flow/flow_processor.py +28 -26
  26. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/main.py +12 -9
  27. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/mqtt/mqtt_client.py +31 -19
  28. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/template/dbus_template_functions.py +2 -2
  29. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/template/templating.py +3 -0
  30. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/tests/__init__.py +9 -11
  31. dbus2mqtt-0.3.0/tests/config/fixtures/payload_template_jinja_expressions.yaml +19 -0
  32. dbus2mqtt-0.3.0/tests/config/fixtures/payload_template_off.yaml +14 -0
  33. dbus2mqtt-0.3.0/tests/config/fixtures/schedule_cron_trigger.yaml +9 -0
  34. dbus2mqtt-0.3.0/tests/config/test_config.py +70 -0
  35. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/tests/config/test_examples.py +3 -4
  36. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/tests/dbus/test_dbus_client.py +10 -8
  37. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/tests/flow/triggers/test_dbus_client_triggers.py +14 -6
  38. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/tests/template/test_templating.py +4 -0
  39. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/uv.lock +342 -310
  40. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.dockerignore +0 -0
  41. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.env.example +0 -0
  42. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  43. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  44. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/scripts/release-versions.py +0 -0
  45. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/workflows/docker-stable.yml +0 -0
  46. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.github/workflows/release-drafter.yml +0 -0
  47. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.gitignore +0 -0
  48. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.python-version +0 -0
  49. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.vscode/launch.json +0 -0
  50. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.vscode/settings.json +0 -0
  51. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/.yamllint.yml +0 -0
  52. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/LICENSE +0 -0
  53. /dbus2mqtt-0.2.0/docker/Dockerfile.latest → /dbus2mqtt-0.3.0/docker/Dockerfile.dev +0 -0
  54. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/docker/Dockerfile.pypi +0 -0
  55. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/docs/debugging.md +0 -0
  56. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/docs/examples/linux_desktop.md +0 -0
  57. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/docs/examples/linux_desktop.yaml +0 -0
  58. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/renovate.json +0 -0
  59. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/__init__.py +0 -0
  60. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/__main__.py +0 -0
  61. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/flow/__init__.py +0 -0
  62. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/src/dbus2mqtt/flow/actions/context_set.py +0 -0
  63. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/tests/flow/actions/test_context_set.py +0 -0
  64. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/tests/flow/actions/test_mqtt_publish.py +0 -0
  65. {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.0}/tests/flow/test_flow_processor.py +0 -0
  66. {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: 💥 Breaking changes
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@v5
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 --python ${{ matrix.python-version }} pytest
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@v5
22
+ uses: astral-sh/setup-uv@v6
20
23
  with:
21
24
  enable-cache: true
22
25
 
23
- - name: "Set up Python"
24
- uses: actions/setup-python@v5
25
- with:
26
- python-version-file: ".python-version"
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.latest
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@v5
19
+ uses: astral-sh/setup-uv@v6
20
20
 
21
- - name: "Set up Python"
22
- uses: actions/setup-python@v5
23
- with:
24
- python-version-file: ".python-version"
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@v5
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
- uses: actions/setup-python@v5
26
- with:
27
- python-version-file: ".python-version"
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.0
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.6
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.6.16
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.399
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.2.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-next>=0.2.3
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
- sudo docker pull jwnmulder/dbus2mqtt
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
- # dbus_next configuration
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
- sudo docker pull jwnmulder/dbus2mqtt
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
- # dbus_next configuration
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, the [media_player.template](https://github.com/Sennevds/media_player.template/tree/master) plugin installed and a working MQTT setup
10
- plugins installed
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` | ✅ | ✅ | ✅ | ✅ | | ❌ | ✅ | Youtube only |
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 | `{ "property": "Volume", "value": 50 }` |
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
- {% if status == 'Playing' %}
77
- playing
78
- {% elif status == 'Paused' %}
79
- paused
80
- {% elif status == 'Stopped' %}
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')['xesam:title'] }}"
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')['mpris:length'] }}"
101
- album_template: "{{ state_attr('sensor.mpris_media_player', 'Metadata')['xesam:album'] }}"
102
- artist_template: "{{ state_attr('sensor.mpris_media_player', 'Metadata')['xesam:artist'] | first }}"
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 is referencing a local file when firefox is used, for now this will provide Youtube img support
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
- {{ state_attr('sensor.mpris_media_player', 'Metadata')['xesam:url']
107
- | regex_replace(
108
- find='https:\/\/www\\.youtube\\.com\/watch\\?v=([^&]+).*',
109
- replace='https://img.youtube.com/vi/\\1/maxresdefault.jpg'
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: '{"property": "Volume", "value": 0.0 }'
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: '{"property": "Volume", "value": 0.0 }'
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: "MPRIS publish player state"
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
- path: /org/mpris/MediaPlayer2
59
+ mpris_path: /org/mpris/MediaPlayer2
55
60
  - type: context_set
56
61
  context:
57
62
  player_properties: |
58
- {{ dbus_call(mpris_bus_name, path, 'org.freedesktop.DBus.Properties', 'GetAll', ['org.mpris.MediaPlayer2.Player']) }}
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
- - name: "MPRIS player removed"
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 #
@@ -1,4 +1,4 @@
1
1
  Examples in this repository
2
2
 
3
3
  * [MPRIS to Home Assistant Media Player integration](examples/home_assistant_media_player.md)
4
- * [Some other examples (WIP)](examples/linux_desktop.md)
4
+ * [Publish dbus2mqtt internal state](examples/dbus2mqtt_internal_state.md)
@@ -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/)
@@ -40,7 +40,7 @@ requires-python = ">=3.10"
40
40
  dependencies = [
41
41
  "apscheduler>=3.11.0",
42
42
  "colorlog>=6.9.0",
43
- "dbus-next>=0.2.3",
43
+ "dbus-fast>=2.44.1",
44
44
  "janus>=2.0.0",
45
45
  "jinja2>=3.1.6",
46
46
  "jinja2-ansible-filters>=1.3.2",