dbus2mqtt 0.3.0__tar.gz → 0.4.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.3.0 → dbus2mqtt-0.4.0}/.github/scripts/release-versions.py +5 -5
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/.github/workflows/docker-stable.yml +6 -2
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/.github/workflows/publish.yml +1 -1
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/.pre-commit-config.yaml +3 -3
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/.vscode/launch.json +8 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/PKG-INFO +5 -5
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/README.md +4 -4
- dbus2mqtt-0.4.0/docs/examples/bluez.md +19 -0
- dbus2mqtt-0.4.0/docs/examples/bluez.yaml +66 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/docs/examples/dbus2mqtt_internal_state.yaml +1 -1
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/docs/examples/home_assistant_media_player.md +10 -3
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/docs/examples/home_assistant_media_player.yaml +7 -3
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/docs/examples/linux_desktop.md +1 -1
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/docs/examples/linux_desktop.yaml +1 -1
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/docs/examples.md +1 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/docs/flows.md +10 -9
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/src/dbus2mqtt/config/__init__.py +24 -5
- dbus2mqtt-0.4.0/src/dbus2mqtt/dbus/dbus_client.py +819 -0
- dbus2mqtt-0.4.0/src/dbus2mqtt/dbus/dbus_types.py +37 -0
- dbus2mqtt-0.4.0/src/dbus2mqtt/dbus/dbus_util.py +24 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/src/dbus2mqtt/event_broker.py +1 -21
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/src/dbus2mqtt/flow/flow_processor.py +19 -5
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/src/dbus2mqtt/main.py +17 -3
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/src/dbus2mqtt/mqtt/mqtt_client.py +9 -2
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/src/dbus2mqtt/template/dbus_template_functions.py +2 -2
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/tests/dbus/test_dbus_client.py +6 -4
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/tests/flow/test_flow_processor.py +42 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/tests/flow/triggers/test_dbus_client_triggers.py +86 -4
- dbus2mqtt-0.3.0/src/dbus2mqtt/dbus/dbus_client.py +0 -476
- dbus2mqtt-0.3.0/src/dbus2mqtt/dbus/dbus_types.py +0 -23
- dbus2mqtt-0.3.0/src/dbus2mqtt/dbus/dbus_util.py +0 -23
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/.dockerignore +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/.env.example +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/.github/release-drafter.yml +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/.github/workflows/ci.yml +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/.github/workflows/docker-dev.yml +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/.github/workflows/pre-commit.yml +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/.github/workflows/release-drafter.yml +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/.gitignore +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/.python-version +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/.vscode/settings.json +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/.yamllint.yml +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/LICENSE +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/docker/Dockerfile.dev +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/docker/Dockerfile.pypi +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/docs/debugging.md +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/docs/examples/dbus2mqtt_internal_state.md +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/pyproject.toml +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/renovate.json +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/src/dbus2mqtt/__init__.py +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/src/dbus2mqtt/__main__.py +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/src/dbus2mqtt/config/jsonarparse.py +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/src/dbus2mqtt/dbus/introspection_patches/mpris_playerctl.py +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/src/dbus2mqtt/dbus/introspection_patches/mpris_vlc.py +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/src/dbus2mqtt/flow/__init__.py +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/src/dbus2mqtt/flow/actions/context_set.py +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/src/dbus2mqtt/flow/actions/mqtt_publish.py +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/src/dbus2mqtt/template/templating.py +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/tests/__init__.py +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/tests/config/fixtures/payload_template_jinja_expressions.yaml +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/tests/config/fixtures/payload_template_off.yaml +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/tests/config/fixtures/schedule_cron_trigger.yaml +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/tests/config/test_config.py +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/tests/config/test_examples.py +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/tests/flow/actions/test_context_set.py +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/tests/flow/actions/test_mqtt_publish.py +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/tests/template/test_templating.py +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/tests/template/test_templating_config.py +0 -0
- {dbus2mqtt-0.3.0 → dbus2mqtt-0.4.0}/uv.lock +0 -0
|
@@ -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():
|
|
@@ -6,8 +6,10 @@ name: docker-stable releases
|
|
|
6
6
|
- main
|
|
7
7
|
paths:
|
|
8
8
|
- "docker/**"
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
workflow_run:
|
|
10
|
+
workflows: ["Publish Python Package"]
|
|
11
|
+
types:
|
|
12
|
+
- completed
|
|
11
13
|
workflow_dispatch:
|
|
12
14
|
|
|
13
15
|
jobs:
|
|
@@ -61,6 +63,8 @@ jobs:
|
|
|
61
63
|
# type=ref,event=branch
|
|
62
64
|
# type=ref,event=pr
|
|
63
65
|
# type=semver,pattern={{version}},value=${{ matrix.version }}
|
|
66
|
+
flavor:
|
|
67
|
+
latest=false
|
|
64
68
|
labels: |
|
|
65
69
|
org.opencontainers.image.source=https://github.com/jwnmulder/dbus2mqtt
|
|
66
70
|
|
|
@@ -33,7 +33,7 @@ repos:
|
|
|
33
33
|
- --strict
|
|
34
34
|
|
|
35
35
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
36
|
-
rev: v0.11.
|
|
36
|
+
rev: v0.11.13
|
|
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.7.
|
|
45
|
+
rev: 0.7.13
|
|
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.402
|
|
51
51
|
hooks:
|
|
52
52
|
- id: pyright
|
|
@@ -8,6 +8,14 @@
|
|
|
8
8
|
"module": "dbus2mqtt",
|
|
9
9
|
"console": "integratedTerminal",
|
|
10
10
|
"args": "--config docs/examples/home_assistant_media_player.yaml"
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "dbus2mqtt - bluez",
|
|
14
|
+
"type": "debugpy",
|
|
15
|
+
"request": "launch",
|
|
16
|
+
"module": "dbus2mqtt",
|
|
17
|
+
"console": "integratedTerminal",
|
|
18
|
+
"args": "--config docs/examples/bluez.yaml"
|
|
11
19
|
}
|
|
12
20
|
]
|
|
13
21
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dbus2mqtt
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.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
|
|
@@ -53,7 +53,7 @@ Initial testing has focused on MPRIS integration. A table of tested MPRIS player
|
|
|
53
53
|
|
|
54
54
|
## Getting started with dbus2mqtt
|
|
55
55
|
|
|
56
|
-
Create a `config.yaml` file with the contents shown below. This configuration will expose all bus properties from the `org.mpris.MediaPlayer2.Player` interface to MQTT on the `dbus2mqtt/org.mpris.MediaPlayer2/state` topic. Have a look at [docs/examples](docs/examples.md) for more examples
|
|
56
|
+
Create a `config.yaml` file with the contents shown below. This configuration will expose all bus properties from the `org.mpris.MediaPlayer2.Player` interface to MQTT on the `dbus2mqtt/org.mpris.MediaPlayer2/state` topic. Have a look at [docs/examples](https://github.com/jwnmulder/dbus2mqtt/blob/main/docs/examples.md) for more examples
|
|
57
57
|
|
|
58
58
|
```yaml
|
|
59
59
|
dbus:
|
|
@@ -68,7 +68,7 @@ dbus:
|
|
|
68
68
|
flows:
|
|
69
69
|
- name: "Publish MPRIS state"
|
|
70
70
|
triggers:
|
|
71
|
-
- type:
|
|
71
|
+
- type: object_added
|
|
72
72
|
- type: schedule
|
|
73
73
|
interval: {seconds: 5}
|
|
74
74
|
actions:
|
|
@@ -111,8 +111,8 @@ 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
|
-
docker pull jwnmulder/dbus2mqtt
|
|
115
|
-
docker run --detach --name dbus2mqtt \
|
|
114
|
+
sudo docker pull jwnmulder/dbus2mqtt
|
|
115
|
+
sudo docker run --detach --name dbus2mqtt \
|
|
116
116
|
--volume "$HOME"/.config/dbus2mqtt:"$HOME"/.config/dbus2mqtt \
|
|
117
117
|
--volume /run/user:/run/user \
|
|
118
118
|
--env DBUS_SESSION_BUS_ADDRESS="$DBUS_SESSION_BUS_ADDRESS" \
|
|
@@ -21,7 +21,7 @@ Initial testing has focused on MPRIS integration. A table of tested MPRIS player
|
|
|
21
21
|
|
|
22
22
|
## Getting started with dbus2mqtt
|
|
23
23
|
|
|
24
|
-
Create a `config.yaml` file with the contents shown below. This configuration will expose all bus properties from the `org.mpris.MediaPlayer2.Player` interface to MQTT on the `dbus2mqtt/org.mpris.MediaPlayer2/state` topic. Have a look at [docs/examples](docs/examples.md) for more examples
|
|
24
|
+
Create a `config.yaml` file with the contents shown below. This configuration will expose all bus properties from the `org.mpris.MediaPlayer2.Player` interface to MQTT on the `dbus2mqtt/org.mpris.MediaPlayer2/state` topic. Have a look at [docs/examples](https://github.com/jwnmulder/dbus2mqtt/blob/main/docs/examples.md) for more examples
|
|
25
25
|
|
|
26
26
|
```yaml
|
|
27
27
|
dbus:
|
|
@@ -36,7 +36,7 @@ dbus:
|
|
|
36
36
|
flows:
|
|
37
37
|
- name: "Publish MPRIS state"
|
|
38
38
|
triggers:
|
|
39
|
-
- type:
|
|
39
|
+
- type: object_added
|
|
40
40
|
- type: schedule
|
|
41
41
|
interval: {seconds: 5}
|
|
42
42
|
actions:
|
|
@@ -79,8 +79,8 @@ 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
|
-
docker pull jwnmulder/dbus2mqtt
|
|
83
|
-
docker run --detach --name dbus2mqtt \
|
|
82
|
+
sudo docker pull jwnmulder/dbus2mqtt
|
|
83
|
+
sudo docker run --detach --name dbus2mqtt \
|
|
84
84
|
--volume "$HOME"/.config/dbus2mqtt:"$HOME"/.config/dbus2mqtt \
|
|
85
85
|
--volume /run/user:/run/user \
|
|
86
86
|
--env DBUS_SESSION_BUS_ADDRESS="$DBUS_SESSION_BUS_ADDRESS" \
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Bluez
|
|
2
|
+
|
|
3
|
+
This configuration file demonstrates how to use dbus2mqtt to bridge D-Bus events from BlueZ (the official Linux Bluetooth protocol stack) to MQTT topics. It subscribes to relevant D-Bus signals and properties for both the Bluetooth adapter (`hci0`) and all Bluetooth devices managed by BlueZ. The configuration defines flows that:
|
|
4
|
+
|
|
5
|
+
* Monitor property changes and object lifecycle events (added/removed) for the Bluetooth adapter and devices.
|
|
6
|
+
* Retrieve the current state of the adapter or device using the `GetAll` method from the `org.freedesktop.DBus.Properties` interface.
|
|
7
|
+
* Publish the retrieved state as JSON payloads to structured MQTT topics, enabling real-time monitoring and integration with home automation or IoT systems.
|
|
8
|
+
|
|
9
|
+
This setup allows MQTT clients to receive updates about Bluetooth adapter and device states, as well as notifications when devices are removed, making it easier to integrate Bluetooth events into broader automation workflows.
|
|
10
|
+
|
|
11
|
+
Configuration activities
|
|
12
|
+
|
|
13
|
+
* dbus2mqtt setup using the supplied [bluez.yaml](https://github.com/jwnmulder/dbus2mqtt/blob/main/docs/examples/bluez.yaml)
|
|
14
|
+
|
|
15
|
+
Execute the following command to run dbus2mqtt with the example configuration in this repository.
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
uv run dbus2mqtt --config docs/examples/bluez.yaml
|
|
19
|
+
```
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
dbus:
|
|
2
|
+
bus_type: SYSTEM
|
|
3
|
+
subscriptions:
|
|
4
|
+
|
|
5
|
+
- bus_name: org.bluez
|
|
6
|
+
path: /org/bluez/hci0
|
|
7
|
+
|
|
8
|
+
interfaces:
|
|
9
|
+
- interface: org.freedesktop.DBus.Properties
|
|
10
|
+
signals:
|
|
11
|
+
- signal: PropertiesChanged
|
|
12
|
+
methods:
|
|
13
|
+
- method: GetAll
|
|
14
|
+
|
|
15
|
+
flows:
|
|
16
|
+
- name: "publish adapter state"
|
|
17
|
+
triggers:
|
|
18
|
+
- type: object_added
|
|
19
|
+
- type: dbus_signal
|
|
20
|
+
interface: org.freedesktop.DBus.Properties
|
|
21
|
+
signal: PropertiesChanged
|
|
22
|
+
actions:
|
|
23
|
+
- type: context_set
|
|
24
|
+
context:
|
|
25
|
+
adapter_properties: |
|
|
26
|
+
{{ dbus_call('org.bluez', '/org/bluez/hci0', 'org.freedesktop.DBus.Properties', 'GetAll', ['org.bluez.Adapter1']) }}
|
|
27
|
+
- type: mqtt_publish
|
|
28
|
+
topic: dbus2mqtt/bluez/hci0
|
|
29
|
+
payload_type: json
|
|
30
|
+
payload_template:
|
|
31
|
+
hci0: "{{ adapter_properties }}"
|
|
32
|
+
|
|
33
|
+
- bus_name: org.bluez
|
|
34
|
+
path: /org/bluez/hci0/dev_*
|
|
35
|
+
|
|
36
|
+
interfaces:
|
|
37
|
+
- interface: org.freedesktop.DBus.Properties
|
|
38
|
+
signals:
|
|
39
|
+
- signal: PropertiesChanged
|
|
40
|
+
methods:
|
|
41
|
+
- method: GetAll
|
|
42
|
+
|
|
43
|
+
flows:
|
|
44
|
+
- name: "publish device state"
|
|
45
|
+
triggers:
|
|
46
|
+
- type: object_added
|
|
47
|
+
- type: dbus_signal
|
|
48
|
+
interface: org.freedesktop.DBus.Properties
|
|
49
|
+
signal: PropertiesChanged
|
|
50
|
+
actions:
|
|
51
|
+
- type: context_set
|
|
52
|
+
context:
|
|
53
|
+
device_properties: |
|
|
54
|
+
{{ dbus_call('org.bluez', path, 'org.freedesktop.DBus.Properties', 'GetAll', ['org.bluez.Device1']) }}
|
|
55
|
+
- type: mqtt_publish
|
|
56
|
+
topic: dbus2mqtt/bluez/{{ path | replace('/org/bluez/', '') }}
|
|
57
|
+
payload_type: json
|
|
58
|
+
payload_template: "{{ device_properties }}"
|
|
59
|
+
- name: "device removed"
|
|
60
|
+
triggers:
|
|
61
|
+
- type: object_removed
|
|
62
|
+
actions:
|
|
63
|
+
- type: mqtt_publish
|
|
64
|
+
topic: dbus2mqtt/bluez/{{ path | replace('/org/bluez/', '') }}
|
|
65
|
+
payload_type: json
|
|
66
|
+
payload_template: "{{ None }}"
|
|
@@ -19,7 +19,7 @@ Features:
|
|
|
19
19
|
Configuration activities
|
|
20
20
|
|
|
21
21
|
* MQTT Sensor and player configuration in Home Assistant (see below)
|
|
22
|
-
* dbus2mqtt setup using the supplied
|
|
22
|
+
* dbus2mqtt setup using the supplied [home_assistant_media_player.yaml](https://github.com/jwnmulder/dbus2mqtt/blob/main/docs/examples/home_assistant_media_player.yaml)
|
|
23
23
|
|
|
24
24
|
Execute the following command to run dbus2mqtt with the example configuration in this repository.
|
|
25
25
|
|
|
@@ -35,7 +35,9 @@ The following setup is known to work with Home Assistant.
|
|
|
35
35
|
|--------------|-----------------------|------|--------------------|------|--------|------|------------|-------------|-------------------|
|
|
36
36
|
| `Firefox` | ✅ | ✅ | ✅ | ✅ | | ❌ | ✅ | ✅ | |
|
|
37
37
|
| `VLC` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | |
|
|
38
|
-
| `Chromium` | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✔️ |
|
|
38
|
+
| `Chromium` | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✔️ | Images not working when Chromium is running as snap |
|
|
39
|
+
| `Kodi` | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | ✅ | ✅ | Requires Kodi plugin [MediaPlayerRemoteInterface](https://github.com/wastis/MediaPlayerRemoteInterface)<br /> Requires path to be set to '/'<br />Signals not working due to non-defaut path |
|
|
40
|
+
|
|
39
41
|
|
|
40
42
|
More players that support MPRIS can be found here: <https://wiki.archlinux.org/title/MPRIS>
|
|
41
43
|
|
|
@@ -97,7 +99,12 @@ media_player:
|
|
|
97
99
|
media_content_type_template: music # needed to show 'artist'
|
|
98
100
|
media_duration_template: "{{ (state_attr('sensor.mpris_media_player', 'Metadata') or {}).get('mpris:length', 0) }}"
|
|
99
101
|
album_template: "{{ (state_attr('sensor.mpris_media_player', 'Metadata') or {}).get('xesam:album', '') }}"
|
|
100
|
-
artist_template:
|
|
102
|
+
artist_template: >-
|
|
103
|
+
{% set artist = (state_attr('sensor.mpris_media_player', 'Metadata') or {}).get('xesam:artist', '') %}
|
|
104
|
+
{% if artist is string %}
|
|
105
|
+
{% set artist = [artist] %}
|
|
106
|
+
{% endif %}
|
|
107
|
+
{{ artist | first }}
|
|
101
108
|
|
|
102
109
|
# mpris:artUrl might contain a file:// schema. In these cases we rely on images published via MQTT
|
|
103
110
|
media_image_url_template: >-
|
|
@@ -42,7 +42,7 @@ dbus:
|
|
|
42
42
|
flows:
|
|
43
43
|
- name: "publish player state"
|
|
44
44
|
triggers:
|
|
45
|
-
- type:
|
|
45
|
+
- type: object_added
|
|
46
46
|
- type: schedule
|
|
47
47
|
interval: {seconds: 5}
|
|
48
48
|
- type: dbus_signal
|
|
@@ -57,6 +57,9 @@ dbus:
|
|
|
57
57
|
context:
|
|
58
58
|
mpris_bus_name: '{{ dbus_list("org.mpris.MediaPlayer2.*") | first }}'
|
|
59
59
|
mpris_path: /org/mpris/MediaPlayer2
|
|
60
|
+
# Some players return stale position if GetAll is executed immediately after a seeked signal.
|
|
61
|
+
# By storing the seeked position it can be used to override Position below
|
|
62
|
+
seeked_position: '{{ args[0] if trigger_type == "dbus_signal" and signal == "Seeked" else None }}'
|
|
60
63
|
- type: context_set
|
|
61
64
|
context:
|
|
62
65
|
player_properties: |
|
|
@@ -68,13 +71,14 @@ dbus:
|
|
|
68
71
|
{{
|
|
69
72
|
{ 'bus_name': mpris_bus_name }
|
|
70
73
|
| combine(player_properties)
|
|
74
|
+
| combine ({ 'Position': seeked_position } if seeked_position else {})
|
|
71
75
|
}}
|
|
72
76
|
|
|
73
77
|
- name: "publish local art image"
|
|
74
78
|
# mpris:artUrl can have a file:// or http:// schema
|
|
75
79
|
# Home Assistant is unable to access file:// so we use MQTT for that
|
|
76
80
|
triggers:
|
|
77
|
-
- type:
|
|
81
|
+
- type: object_added
|
|
78
82
|
- type: dbus_signal
|
|
79
83
|
interface: org.freedesktop.DBus.Properties
|
|
80
84
|
signal: PropertiesChanged
|
|
@@ -90,7 +94,7 @@ dbus:
|
|
|
90
94
|
|
|
91
95
|
- name: "player removed"
|
|
92
96
|
triggers:
|
|
93
|
-
- type:
|
|
97
|
+
- type: object_removed
|
|
94
98
|
# filter: # TODO: Check if this is the last or inactive one #
|
|
95
99
|
actions:
|
|
96
100
|
- type: mqtt_publish
|
|
@@ -6,8 +6,8 @@ Flows can be defined on a global or dbus subscription level and can be triggered
|
|
|
6
6
|
|
|
7
7
|
* `schedule` for cron based schedules
|
|
8
8
|
* `dbus_signal` for when dbus signal occur
|
|
9
|
-
* `
|
|
10
|
-
* `
|
|
9
|
+
* `object_added` when a new bus_name is registered on dbus
|
|
10
|
+
* `object_removed` when a bus_name is removed from dbus
|
|
11
11
|
|
|
12
12
|
Within each flow a set of actions can be configured. These are executed in order
|
|
13
13
|
|
|
@@ -53,14 +53,15 @@ When triggered, the following context parameters are available
|
|
|
53
53
|
| name | type | description |
|
|
54
54
|
|------|------|-------------|
|
|
55
55
|
| bus_name | string | bus_name of the object that was registered on dbus |
|
|
56
|
-
| path | string |
|
|
56
|
+
| path | string | path of the object that was registered on dbus |
|
|
57
57
|
| interface | string | name of interface for which the signal was triggered |
|
|
58
|
+
| signal | string | name of the signal, e.g. 'Seeked'
|
|
58
59
|
| args | list | signal arguments, list of objects |
|
|
59
60
|
|
|
60
|
-
###
|
|
61
|
+
### object_added
|
|
61
62
|
|
|
62
63
|
```yaml
|
|
63
|
-
type:
|
|
64
|
+
type: object_added
|
|
64
65
|
```
|
|
65
66
|
|
|
66
67
|
When triggered, the following context parameters are available
|
|
@@ -68,12 +69,12 @@ When triggered, the following context parameters are available
|
|
|
68
69
|
| name | description |
|
|
69
70
|
|------|-------------|
|
|
70
71
|
| bus_name | bus_name of the object that was registered on dbus |
|
|
71
|
-
| path |
|
|
72
|
+
| path | path of the object that was registered on dbus |
|
|
72
73
|
|
|
73
|
-
###
|
|
74
|
+
### object_removed
|
|
74
75
|
|
|
75
76
|
```yaml
|
|
76
|
-
type:
|
|
77
|
+
type: object_removed
|
|
77
78
|
```
|
|
78
79
|
|
|
79
80
|
When triggered, the following context parameters are available
|
|
@@ -81,7 +82,7 @@ When triggered, the following context parameters are available
|
|
|
81
82
|
| name | description |
|
|
82
83
|
|------|-------------|
|
|
83
84
|
| bus_name | bus_name of the object that was registered on dbus |
|
|
84
|
-
| path |
|
|
85
|
+
| path | path of the object that was registered on dbus |
|
|
85
86
|
|
|
86
87
|
## Flow actions
|
|
87
88
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fnmatch
|
|
2
2
|
import uuid
|
|
3
|
+
import warnings
|
|
3
4
|
|
|
4
5
|
from dataclasses import dataclass, field
|
|
5
6
|
from typing import Annotated, Any, Literal
|
|
@@ -65,15 +66,29 @@ class FlowTriggerDbusSignalConfig:
|
|
|
65
66
|
@dataclass
|
|
66
67
|
class FlowTriggerBusNameAddedConfig:
|
|
67
68
|
type: Literal["bus_name_added"] = "bus_name_added"
|
|
68
|
-
|
|
69
|
+
|
|
70
|
+
def __post_init__(self):
|
|
71
|
+
warnings.warn(f"{self.type} flow trigger may be removed in a future version.", DeprecationWarning, stacklevel=2)
|
|
69
72
|
|
|
70
73
|
@dataclass
|
|
71
74
|
class FlowTriggerBusNameRemovedConfig:
|
|
72
75
|
type: Literal["bus_name_removed"] = "bus_name_removed"
|
|
76
|
+
|
|
77
|
+
def __post_init__(self):
|
|
78
|
+
warnings.warn(f"{self.type} flow trigger may be removed in a future version.", DeprecationWarning, stacklevel=2)
|
|
79
|
+
|
|
80
|
+
@dataclass
|
|
81
|
+
class FlowTriggerObjectAddedConfig:
|
|
82
|
+
type: Literal["object_added"] = "object_added"
|
|
83
|
+
# filter: str | None = None
|
|
84
|
+
|
|
85
|
+
@dataclass
|
|
86
|
+
class FlowTriggerObjectRemovedConfig:
|
|
87
|
+
type: Literal["object_removed"] = "object_removed"
|
|
73
88
|
# filter: str | None = None
|
|
74
89
|
|
|
75
90
|
FlowTriggerConfig = Annotated[
|
|
76
|
-
FlowTriggerMqttConfig | FlowTriggerScheduleConfig | FlowTriggerDbusSignalConfig | FlowTriggerBusNameAddedConfig | FlowTriggerBusNameRemovedConfig,
|
|
91
|
+
FlowTriggerMqttConfig | FlowTriggerScheduleConfig | FlowTriggerDbusSignalConfig | FlowTriggerBusNameAddedConfig | FlowTriggerBusNameRemovedConfig | FlowTriggerObjectAddedConfig | FlowTriggerObjectRemovedConfig,
|
|
77
92
|
Field(discriminator="type")
|
|
78
93
|
]
|
|
79
94
|
|
|
@@ -117,6 +132,7 @@ class SubscriptionConfig:
|
|
|
117
132
|
@dataclass
|
|
118
133
|
class DbusConfig:
|
|
119
134
|
subscriptions: list[SubscriptionConfig]
|
|
135
|
+
bus_type: Literal["SESSION", "SYSTEM"] = "SESSION"
|
|
120
136
|
|
|
121
137
|
def is_bus_name_configured(self, bus_name: str) -> bool:
|
|
122
138
|
|
|
@@ -125,11 +141,14 @@ class DbusConfig:
|
|
|
125
141
|
return True
|
|
126
142
|
return False
|
|
127
143
|
|
|
128
|
-
def get_subscription_configs(self, bus_name: str, path: str) -> list[SubscriptionConfig]:
|
|
144
|
+
def get_subscription_configs(self, bus_name: str, path: str|None = None) -> list[SubscriptionConfig]:
|
|
129
145
|
res: list[SubscriptionConfig] = []
|
|
130
146
|
for subscription in self.subscriptions:
|
|
131
|
-
if fnmatch.fnmatchcase(bus_name, subscription.bus_name)
|
|
132
|
-
|
|
147
|
+
if fnmatch.fnmatchcase(bus_name, subscription.bus_name):
|
|
148
|
+
if not path or path == subscription.path:
|
|
149
|
+
res.append(subscription)
|
|
150
|
+
elif fnmatch.fnmatchcase(path, subscription.path):
|
|
151
|
+
res.append(subscription)
|
|
133
152
|
return res
|
|
134
153
|
|
|
135
154
|
@dataclass
|