dbus2mqtt 0.2.0__tar.gz → 0.3.1__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.1}/.github/release-drafter.yml +4 -3
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/.github/scripts/release-versions.py +5 -5
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/.github/workflows/ci.yml +9 -6
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/.github/workflows/docker-dev.yml +9 -6
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/.github/workflows/docker-stable.yml +4 -2
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/.github/workflows/pre-commit.yml +5 -5
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/.github/workflows/publish.yml +7 -6
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/.pre-commit-config.yaml +4 -4
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/PKG-INFO +7 -5
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/README.md +5 -3
- dbus2mqtt-0.3.1/docs/examples/dbus2mqtt_internal_state.md +13 -0
- dbus2mqtt-0.3.1/docs/examples/dbus2mqtt_internal_state.yaml +40 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/docs/examples/home_assistant_media_player.md +42 -32
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/docs/examples/home_assistant_media_player.yaml +28 -7
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/docs/examples.md +1 -1
- dbus2mqtt-0.3.1/docs/flows.md +122 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/pyproject.toml +1 -1
- dbus2mqtt-0.2.0/src/dbus2mqtt/config.py → dbus2mqtt-0.3.1/src/dbus2mqtt/config/__init__.py +10 -8
- dbus2mqtt-0.3.1/src/dbus2mqtt/config/jsonarparse.py +31 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/src/dbus2mqtt/dbus/dbus_client.py +61 -37
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/src/dbus2mqtt/dbus/dbus_types.py +2 -2
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/src/dbus2mqtt/dbus/dbus_util.py +2 -2
- dbus2mqtt-0.3.1/src/dbus2mqtt/dbus/introspection_patches/mpris_playerctl.py +151 -0
- dbus2mqtt-0.3.1/src/dbus2mqtt/dbus/introspection_patches/mpris_vlc.py +122 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/src/dbus2mqtt/event_broker.py +1 -1
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/src/dbus2mqtt/flow/actions/mqtt_publish.py +12 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/src/dbus2mqtt/flow/flow_processor.py +28 -26
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/src/dbus2mqtt/main.py +12 -9
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/src/dbus2mqtt/mqtt/mqtt_client.py +31 -19
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/src/dbus2mqtt/template/dbus_template_functions.py +2 -2
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/src/dbus2mqtt/template/templating.py +3 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/tests/__init__.py +9 -11
- dbus2mqtt-0.3.1/tests/config/fixtures/payload_template_jinja_expressions.yaml +19 -0
- dbus2mqtt-0.3.1/tests/config/fixtures/payload_template_off.yaml +14 -0
- dbus2mqtt-0.3.1/tests/config/fixtures/schedule_cron_trigger.yaml +9 -0
- dbus2mqtt-0.3.1/tests/config/test_config.py +70 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/tests/config/test_examples.py +3 -4
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/tests/dbus/test_dbus_client.py +10 -8
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/tests/flow/triggers/test_dbus_client_triggers.py +14 -6
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/tests/template/test_templating.py +4 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/uv.lock +342 -310
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/.dockerignore +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/.env.example +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/.github/workflows/release-drafter.yml +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/.gitignore +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/.python-version +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/.vscode/launch.json +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/.vscode/settings.json +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/.yamllint.yml +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/LICENSE +0 -0
- /dbus2mqtt-0.2.0/docker/Dockerfile.latest → /dbus2mqtt-0.3.1/docker/Dockerfile.dev +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/docker/Dockerfile.pypi +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/docs/debugging.md +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/docs/examples/linux_desktop.md +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/docs/examples/linux_desktop.yaml +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/renovate.json +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/src/dbus2mqtt/__init__.py +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/src/dbus2mqtt/__main__.py +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/src/dbus2mqtt/flow/__init__.py +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/src/dbus2mqtt/flow/actions/context_set.py +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/tests/flow/actions/test_context_set.py +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/tests/flow/actions/test_mqtt_publish.py +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/tests/flow/test_flow_processor.py +0 -0
- {dbus2mqtt-0.2.0 → dbus2mqtt-0.3.1}/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:
|
|
@@ -26,16 +26,16 @@ def get_versions_from_git_tags() -> list[version.Version]:
|
|
|
26
26
|
|
|
27
27
|
def latest_version_by_cycle(versions: list[version.Version], cycles: list[str]) -> dict[str, version.Version]:
|
|
28
28
|
res = {}
|
|
29
|
-
for
|
|
30
|
-
|
|
29
|
+
for cycle_str in cycles:
|
|
30
|
+
cycle = version.parse(cycle_str)
|
|
31
31
|
|
|
32
32
|
for v in versions:
|
|
33
33
|
# check if version is in cycle range
|
|
34
34
|
# cycle can be major or major.minor or major.minor.patch
|
|
35
|
-
if len(v.release) > len(
|
|
35
|
+
if len(v.release) > len(cycle.release) and v.base_version.startswith(cycle.base_version):
|
|
36
36
|
# update if version is later within cycle
|
|
37
|
-
if cycle not in cycles or v >
|
|
38
|
-
res[
|
|
37
|
+
if cycle not in cycles or v > cycle:
|
|
38
|
+
res[cycle_str] = v
|
|
39
39
|
return res
|
|
40
40
|
|
|
41
41
|
def main():
|
|
@@ -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
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
name:
|
|
1
|
+
name: Publish Python Package
|
|
2
2
|
|
|
3
3
|
"on":
|
|
4
4
|
release:
|
|
@@ -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.1
|
|
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` | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✔️ | Images not working when Chromium is 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 #
|