dbus2mqtt 0.4.1__py3-none-any.whl → 0.4.3__py3-none-any.whl
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/config/__init__.py +8 -1
- dbus2mqtt/dbus/dbus_client.py +1 -1
- dbus2mqtt/flow/actions/log_action.py +36 -0
- dbus2mqtt/flow/flow_processor.py +5 -1
- dbus2mqtt/mqtt/mqtt_client.py +29 -8
- dbus2mqtt/template/templating.py +11 -0
- {dbus2mqtt-0.4.1.dist-info → dbus2mqtt-0.4.3.dist-info}/METADATA +19 -13
- {dbus2mqtt-0.4.1.dist-info → dbus2mqtt-0.4.3.dist-info}/RECORD +11 -10
- {dbus2mqtt-0.4.1.dist-info → dbus2mqtt-0.4.3.dist-info}/WHEEL +0 -0
- {dbus2mqtt-0.4.1.dist-info → dbus2mqtt-0.4.3.dist-info}/entry_points.txt +0 -0
- {dbus2mqtt-0.4.1.dist-info → dbus2mqtt-0.4.3.dist-info}/licenses/LICENSE +0 -0
dbus2mqtt/config/__init__.py
CHANGED
|
@@ -107,8 +107,14 @@ class FlowActionMqttPublishConfig:
|
|
|
107
107
|
type: Literal["mqtt_publish"] = "mqtt_publish"
|
|
108
108
|
payload_type: Literal["json", "yaml", "text", "binary"] = "json"
|
|
109
109
|
|
|
110
|
+
@dataclass
|
|
111
|
+
class FlowActionLogConfig:
|
|
112
|
+
msg: str
|
|
113
|
+
type: Literal["log"] = "log"
|
|
114
|
+
level: Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] = "INFO"
|
|
115
|
+
|
|
110
116
|
FlowActionConfig = Annotated[
|
|
111
|
-
FlowActionMqttPublishConfig | FlowActionContextSetConfig,
|
|
117
|
+
FlowActionMqttPublishConfig | FlowActionContextSetConfig | FlowActionLogConfig,
|
|
112
118
|
Field(discriminator="type")
|
|
113
119
|
]
|
|
114
120
|
|
|
@@ -157,6 +163,7 @@ class MqttConfig:
|
|
|
157
163
|
username: str
|
|
158
164
|
password: SecretStr
|
|
159
165
|
port: int = 1883
|
|
166
|
+
subscription_topics: list[str] = field(default_factory=lambda: ['dbus2mqtt/#'])
|
|
160
167
|
|
|
161
168
|
@dataclass
|
|
162
169
|
class Config:
|
dbus2mqtt/dbus/dbus_client.py
CHANGED
|
@@ -512,7 +512,7 @@ class DbusClient:
|
|
|
512
512
|
# clean lingering interface messgage handler from bus
|
|
513
513
|
self.bus.remove_message_handler(proxy_interface._message_handler)
|
|
514
514
|
|
|
515
|
-
# For now that InterfacesRemoved signal means the entire object is removed
|
|
515
|
+
# For now that InterfacesRemoved signal means the entire object is removed from D-Bus
|
|
516
516
|
del self.subscriptions[bus_name].path_objects[path]
|
|
517
517
|
|
|
518
518
|
# cleanup the entire BusNameSubscriptions if no more objects are subscribed
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
from jinja2.exceptions import TemplateError
|
|
5
|
+
|
|
6
|
+
from dbus2mqtt import AppContext
|
|
7
|
+
from dbus2mqtt.config import FlowActionLogConfig
|
|
8
|
+
from dbus2mqtt.flow import FlowAction, FlowExecutionContext
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
class LogAction(FlowAction):
|
|
13
|
+
|
|
14
|
+
def __init__(self, config: FlowActionLogConfig, app_context: AppContext):
|
|
15
|
+
self.config = config
|
|
16
|
+
self.templating = app_context.templating
|
|
17
|
+
|
|
18
|
+
async def execute(self, context: FlowExecutionContext):
|
|
19
|
+
|
|
20
|
+
render_context = context.get_aggregated_context()
|
|
21
|
+
|
|
22
|
+
log_msg = self.config.msg
|
|
23
|
+
log_level = logging._nameToLevel.get(self.config.level.upper(), logging.INFO)
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
log_msg = await self.templating.async_render_template(
|
|
27
|
+
templatable=self.config.msg,
|
|
28
|
+
context=render_context,
|
|
29
|
+
res_type=str
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
except TemplateError as e:
|
|
33
|
+
logger.warning(f"Error rendering jinja template, flow: '{context.name or ''}', msg={e}, msg={self.config.msg}, render_context={render_context}", exc_info=True)
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
logger.log(level=log_level, msg=log_msg)
|
dbus2mqtt/flow/flow_processor.py
CHANGED
|
@@ -17,6 +17,7 @@ from dbus2mqtt.config import (
|
|
|
17
17
|
from dbus2mqtt.event_broker import FlowTriggerMessage
|
|
18
18
|
from dbus2mqtt.flow import FlowAction, FlowExecutionContext
|
|
19
19
|
from dbus2mqtt.flow.actions.context_set import ContextSetAction
|
|
20
|
+
from dbus2mqtt.flow.actions.log_action import LogAction
|
|
20
21
|
from dbus2mqtt.flow.actions.mqtt_publish import MqttPublishAction
|
|
21
22
|
|
|
22
23
|
logger = logging.getLogger(__name__)
|
|
@@ -102,8 +103,11 @@ class FlowActionContext:
|
|
|
102
103
|
action = None
|
|
103
104
|
if action_config.type == "context_set":
|
|
104
105
|
action = ContextSetAction(action_config, self.app_context)
|
|
105
|
-
|
|
106
|
+
elif action_config.type == "mqtt_publish":
|
|
106
107
|
action = MqttPublishAction(action_config, self.app_context)
|
|
108
|
+
elif action_config.type == "log":
|
|
109
|
+
action = LogAction(action_config, self.app_context)
|
|
110
|
+
|
|
107
111
|
if action:
|
|
108
112
|
res.append(action)
|
|
109
113
|
|
dbus2mqtt/mqtt/mqtt_client.py
CHANGED
|
@@ -13,6 +13,8 @@ import paho.mqtt.client as mqtt
|
|
|
13
13
|
import yaml
|
|
14
14
|
|
|
15
15
|
from paho.mqtt.enums import CallbackAPIVersion
|
|
16
|
+
from paho.mqtt.packettypes import PacketTypes
|
|
17
|
+
from paho.mqtt.properties import Properties
|
|
16
18
|
from paho.mqtt.subscribeoptions import SubscribeOptions
|
|
17
19
|
|
|
18
20
|
from dbus2mqtt import AppContext
|
|
@@ -27,8 +29,11 @@ class MqttClient:
|
|
|
27
29
|
self.event_broker = app_context.event_broker
|
|
28
30
|
|
|
29
31
|
unique_client_id_postfix = ''.join(random.choices(string.ascii_lowercase + string.digits, k=6))
|
|
32
|
+
self.client_id_prefix = "dbus2mqtt-"
|
|
33
|
+
self.client_id = f"{self.client_id_prefix}{unique_client_id_postfix}"
|
|
34
|
+
|
|
30
35
|
self.client = mqtt.Client(
|
|
31
|
-
client_id=
|
|
36
|
+
client_id=self.client_id,
|
|
32
37
|
protocol=mqtt.MQTTv5,
|
|
33
38
|
callback_api_version=CallbackAPIVersion.VERSION2
|
|
34
39
|
)
|
|
@@ -84,7 +89,16 @@ class MqttClient:
|
|
|
84
89
|
if first_message:
|
|
85
90
|
await asyncio.wait_for(self.connected_event.wait(), timeout=5)
|
|
86
91
|
|
|
87
|
-
|
|
92
|
+
publish_properties = Properties(PacketTypes.PUBLISH)
|
|
93
|
+
publish_properties.UserProperty = ("client_id", self.client_id)
|
|
94
|
+
|
|
95
|
+
publish_info = self.client.publish(
|
|
96
|
+
topic=msg.topic,
|
|
97
|
+
payload=payload or "",
|
|
98
|
+
properties=publish_properties
|
|
99
|
+
)
|
|
100
|
+
publish_info.wait_for_publish(timeout=1000)
|
|
101
|
+
|
|
88
102
|
if first_message:
|
|
89
103
|
logger.info(f"First message published: topic={msg.topic}, payload={payload_log_msg}")
|
|
90
104
|
first_message = False
|
|
@@ -100,22 +114,29 @@ class MqttClient:
|
|
|
100
114
|
logger.warning(f"on_connect: Failed to connect: {reason_code}. Will retry connection")
|
|
101
115
|
else:
|
|
102
116
|
logger.info(f"on_connect: Connected to {self.config.host}:{self.config.port}")
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
client.subscribe("dbus2mqtt/#", options=SubscribeOptions(noLocal=True))
|
|
117
|
+
|
|
118
|
+
subscriptions = [(t, SubscribeOptions(noLocal=True)) for t in self.config.subscription_topics]
|
|
119
|
+
client.subscribe(subscriptions)
|
|
107
120
|
|
|
108
121
|
self.loop.call_soon_threadsafe(self.connected_event.set)
|
|
109
122
|
|
|
110
123
|
def on_message(self, client: mqtt.Client, userdata: Any, msg: mqtt.MQTTMessage):
|
|
111
124
|
|
|
112
|
-
#
|
|
113
|
-
|
|
125
|
+
# Skip retained messages
|
|
114
126
|
payload = msg.payload.decode()
|
|
115
127
|
if msg.retain:
|
|
116
128
|
logger.info(f"on_message: skipping msg with retain=True, topic={msg.topic}, payload={payload}")
|
|
117
129
|
return
|
|
118
130
|
|
|
131
|
+
# Skip messages being sent by other dbus2mqtt clients
|
|
132
|
+
if msg.properties:
|
|
133
|
+
user_properties: list[tuple[str, object]] = getattr(msg.properties, "UserProperty", [])
|
|
134
|
+
client_id = next((str(v) for k, v in user_properties if k == "client_id"), None)
|
|
135
|
+
if client_id and client_id != self.client_id:
|
|
136
|
+
logger.info(f"on_message: skipping msg from another dbus2mqtt client, topic={msg.topic}, client_id={client_id}")
|
|
137
|
+
if client_id and client_id.startswith(self.client_id_prefix):
|
|
138
|
+
return
|
|
139
|
+
|
|
119
140
|
try:
|
|
120
141
|
json_payload = json.loads(payload) if payload else {}
|
|
121
142
|
logger.debug(f"on_message: msg.topic={msg.topic}, msg.payload={json.dumps(json_payload)}")
|
dbus2mqtt/template/templating.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import urllib.parse
|
|
1
2
|
|
|
2
3
|
from datetime import datetime
|
|
3
4
|
from typing import Any, TypeVar
|
|
@@ -7,11 +8,18 @@ from jinja2.nativetypes import NativeEnvironment
|
|
|
7
8
|
|
|
8
9
|
TemplateResultType = TypeVar('TemplateResultType')
|
|
9
10
|
|
|
11
|
+
def urldecode(string):
|
|
12
|
+
return urllib.parse.unquote(string)
|
|
13
|
+
|
|
10
14
|
class TemplateEngine:
|
|
11
15
|
def __init__(self):
|
|
12
16
|
|
|
13
17
|
engine_globals = {}
|
|
14
18
|
engine_globals['now'] = datetime.now
|
|
19
|
+
engine_globals['urldecode'] = urldecode
|
|
20
|
+
|
|
21
|
+
engine_filters = {}
|
|
22
|
+
engine_filters['urldecode'] = urldecode
|
|
15
23
|
|
|
16
24
|
self.jinja2_env = NativeEnvironment(
|
|
17
25
|
loader=BaseLoader(),
|
|
@@ -32,6 +40,9 @@ class TemplateEngine:
|
|
|
32
40
|
self.jinja2_env.globals.update(engine_globals)
|
|
33
41
|
self.jinja2_async_env.globals.update(engine_globals)
|
|
34
42
|
|
|
43
|
+
self.jinja2_env.filters.update(engine_filters)
|
|
44
|
+
self.jinja2_async_env.filters.update(engine_filters)
|
|
45
|
+
|
|
35
46
|
def add_functions(self, custom_functions: dict[str, Any]):
|
|
36
47
|
self.jinja2_env.globals.update(custom_functions)
|
|
37
48
|
self.jinja2_async_env.globals.update(custom_functions)
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dbus2mqtt
|
|
3
|
-
Version: 0.4.
|
|
4
|
-
Summary:
|
|
5
|
-
Project-URL:
|
|
3
|
+
Version: 0.4.3
|
|
4
|
+
Summary: General purpose DBus to MQTT bridge - expose signals, methods and properties over MQTT - featuring jinja based templating, payload enrichment and MPRIS / BlueZ / Home Assistant ready examples
|
|
5
|
+
Project-URL: Documentation, https://jwnmulder.github.io/dbus2mqtt
|
|
6
|
+
Project-URL: Source, https://github.com/jwnmulder/dbus2mqtt
|
|
6
7
|
Project-URL: Issues, https://github.com/jwnmulder/dbus2mqtt/issues
|
|
7
8
|
License-Expression: MIT
|
|
8
9
|
License-File: LICENSE
|
|
9
|
-
Keywords: dbus,home-assistant,mpris,mqtt,python
|
|
10
|
-
Classifier: Development Status ::
|
|
10
|
+
Keywords: bluez,bridge,dbus,home-assistant,jinja2,mpris,mqtt,python
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
12
|
Classifier: Intended Audience :: Developers
|
|
12
13
|
Classifier: License :: OSI Approved :: MIT License
|
|
13
14
|
Classifier: Operating System :: POSIX :: Linux
|
|
@@ -16,6 +17,7 @@ Classifier: Programming Language :: Python :: 3.10
|
|
|
16
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
17
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
18
19
|
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Home Automation
|
|
19
21
|
Requires-Python: >=3.10
|
|
20
22
|
Requires-Dist: apscheduler>=3.11.0
|
|
21
23
|
Requires-Dist: colorlog>=6.9.0
|
|
@@ -32,12 +34,12 @@ Description-Content-Type: text/markdown
|
|
|
32
34
|
|
|
33
35
|
# dbus2mqtt
|
|
34
36
|
|
|
35
|
-
**dbus2mqtt** is a Python application that bridges **
|
|
36
|
-
It lets you forward D-Bus signals and properties to MQTT topics, call D-Bus methods via MQTT messages, and shape payloads using flexible **Jinja2 templating**.
|
|
37
|
+
**dbus2mqtt** is a Python application that bridges **DBus** with **MQTT**.
|
|
38
|
+
It lets you forward Linux D-Bus signals and properties to MQTT topics, call D-Bus methods via MQTT messages, and shape payloads using flexible **Jinja2 templating**.
|
|
37
39
|
|
|
38
40
|
This makes it easy to integrate Linux desktop services or system signals into MQTT-based workflows - including **Home Assistant**.
|
|
39
41
|
|
|
40
|
-
##
|
|
42
|
+
## Features
|
|
41
43
|
|
|
42
44
|
* 🔗 Forward **D-Bus signals** to MQTT topics.
|
|
43
45
|
* 🧠 Enrich or transform **MQTT payloads** using Jinja2 templates and additional D-Bus calls.
|
|
@@ -49,11 +51,11 @@ This makes it easy to integrate Linux desktop services or system signals into MQ
|
|
|
49
51
|
|
|
50
52
|
**dbus2mqtt** is considered stable for the use-cases it has been tested against, and is actively being developed. Documentation is continuously being improved.
|
|
51
53
|
|
|
52
|
-
Initial testing has focused on MPRIS integration. A table of tested MPRIS players and their supported methods can be found here: [
|
|
54
|
+
Initial testing has focused on MPRIS integration. A table of tested MPRIS players and their supported methods can be found here: [Mediaplayer integration with Home Assistant](https://jwnmulder.github.io/dbus2mqtt/examples/home_assistant_media_player/)
|
|
53
55
|
|
|
54
56
|
## Getting started with dbus2mqtt
|
|
55
57
|
|
|
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.
|
|
58
|
+
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.
|
|
57
59
|
|
|
58
60
|
```yaml
|
|
59
61
|
dbus:
|
|
@@ -92,6 +94,7 @@ MQTT__USERNAME=
|
|
|
92
94
|
MQTT__PASSWORD=
|
|
93
95
|
```
|
|
94
96
|
|
|
97
|
+
|
|
95
98
|
### Install and run dbus2mqtt
|
|
96
99
|
|
|
97
100
|
```bash
|
|
@@ -129,7 +132,8 @@ sudo docker logs dbus2mqtt -f
|
|
|
129
132
|
|
|
130
133
|
## Examples
|
|
131
134
|
|
|
132
|
-
|
|
135
|
+
More dbus2mqtt examples can be found here: [examples](https://jwnmulder.github.io/dbus2mqtt/examples/).
|
|
136
|
+
The most complete one being [MPRIS to Home Assistant Media Player integration](https://jwnmulder.github.io/dbus2mqtt/examples/home_assistant_media_player/)
|
|
133
137
|
|
|
134
138
|
## Configuration reference
|
|
135
139
|
|
|
@@ -154,6 +158,8 @@ or
|
|
|
154
158
|
mqtt:
|
|
155
159
|
host: localhost
|
|
156
160
|
port: 1883
|
|
161
|
+
subscription_topics:
|
|
162
|
+
- dbus2mqtt/#
|
|
157
163
|
```
|
|
158
164
|
|
|
159
165
|
### Exposing dbus methods
|
|
@@ -224,8 +230,8 @@ dbus:
|
|
|
224
230
|
|
|
225
231
|
## Flows
|
|
226
232
|
|
|
227
|
-
|
|
233
|
+
A reference of all supported flow triggers and actions can be found on [Flows](https://jwnmulder.github.io/dbus2mqtt/flows/)
|
|
228
234
|
|
|
229
235
|
## Jinja templating
|
|
230
236
|
|
|
231
|
-
TODO: Document Jinja templating, for now see the [MPRIS to Home Assistant Media Player integration](https://github.
|
|
237
|
+
TODO: Document Jinja templating, for now see the [MPRIS to Home Assistant Media Player integration](https://jwnmulder.github.io/dbus2mqtt/examples/home_assistant_media_player/) example
|
|
@@ -2,22 +2,23 @@ dbus2mqtt/__init__.py,sha256=VunubKEH4_lne9Ttd2YRpyXjZMIAzyD2eiJ2sfvvTFU,362
|
|
|
2
2
|
dbus2mqtt/__main__.py,sha256=NAoa3nwgBSQI22eWzzRx61SIDThDwXmUofWWZU3_4-Q,71
|
|
3
3
|
dbus2mqtt/event_broker.py,sha256=Hp5yurhP8FkAO-y0l2grygHxR2e37ZQ7QScjcQDA2UU,1334
|
|
4
4
|
dbus2mqtt/main.py,sha256=Kr2LRVxWcPDtNwCj8Eqz9TxtGLAVrV4q0nizKh1pLXc,4539
|
|
5
|
-
dbus2mqtt/config/__init__.py,sha256=
|
|
5
|
+
dbus2mqtt/config/__init__.py,sha256=947_dLVt8qq7P3p15jGIy5Vf1jUUMGrh1xr_DVhZclQ,5372
|
|
6
6
|
dbus2mqtt/config/jsonarparse.py,sha256=VJGFeyQJcOE6bRXlSRr3FClvN_HnmiIlEGmOgNM0oCc,1214
|
|
7
|
-
dbus2mqtt/dbus/dbus_client.py,sha256=
|
|
7
|
+
dbus2mqtt/dbus/dbus_client.py,sha256=WHsmOiaJ5SY6zk-C99m83MEpycnUyGpsYmGopJJbPE8,39690
|
|
8
8
|
dbus2mqtt/dbus/dbus_types.py,sha256=NmPD9um499e49Pk8DWH4IrIPQh1BinHYQgoXllCNiDw,777
|
|
9
9
|
dbus2mqtt/dbus/dbus_util.py,sha256=h-1Y8Mvz9bj9X7mPZ8LghkvXDrujdJHK0__AOW373hE,697
|
|
10
10
|
dbus2mqtt/dbus/introspection_patches/mpris_playerctl.py,sha256=q93d_Yp93u3Y-9q0dRdKW5hrij9GK3CFqKhUWVE8uw4,5883
|
|
11
11
|
dbus2mqtt/dbus/introspection_patches/mpris_vlc.py,sha256=Cf-o-05W6gUoKpcYR7n0dRi-CrbeASPTwkyEzZGnU3Y,4241
|
|
12
12
|
dbus2mqtt/flow/__init__.py,sha256=tAL-CjXQHq_tGTKctIdOZ5teVKBtcJs6Astq_RdruV8,1540
|
|
13
|
-
dbus2mqtt/flow/flow_processor.py,sha256
|
|
13
|
+
dbus2mqtt/flow/flow_processor.py,sha256=N-btGap1wqnM4zKyulH_5KQhGi0IRlsK2cHrrnomMQQ,8922
|
|
14
14
|
dbus2mqtt/flow/actions/context_set.py,sha256=dIT39MJJVb0wuRI_ZM3ssnXYfa-iyB4o_UZD-1BZL2g,1087
|
|
15
|
+
dbus2mqtt/flow/actions/log_action.py,sha256=2_-YEKkX5kvFzK6x4v-Hx3u2PEM8fip_4buMg_ij-oI,1156
|
|
15
16
|
dbus2mqtt/flow/actions/mqtt_publish.py,sha256=psNkTvaR3JZwAwpM4AqiZTDnA5UQX9r4CUZ1LA7iRW4,2366
|
|
16
|
-
dbus2mqtt/mqtt/mqtt_client.py,sha256=
|
|
17
|
+
dbus2mqtt/mqtt/mqtt_client.py,sha256=P6rxVNA2M_wxhI3RcHpvayEEmcUQGGDG6hkLmjiqY1w,6056
|
|
17
18
|
dbus2mqtt/template/dbus_template_functions.py,sha256=UEoXK2PqDKF6jR4vTFHQwq58f5APnOJr7B1_I1zW8yM,2449
|
|
18
|
-
dbus2mqtt/template/templating.py,sha256=
|
|
19
|
-
dbus2mqtt-0.4.
|
|
20
|
-
dbus2mqtt-0.4.
|
|
21
|
-
dbus2mqtt-0.4.
|
|
22
|
-
dbus2mqtt-0.4.
|
|
23
|
-
dbus2mqtt-0.4.
|
|
19
|
+
dbus2mqtt/template/templating.py,sha256=YzE6-pBoATrV7nXkgxSiLlbxgbC65-2wGiFPHgIDd9g,4470
|
|
20
|
+
dbus2mqtt-0.4.3.dist-info/METADATA,sha256=XcxIrk2rZt7HWU1ch1Eqx2DzVIQgvsjpwYMZ0q6on2A,8071
|
|
21
|
+
dbus2mqtt-0.4.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
22
|
+
dbus2mqtt-0.4.3.dist-info/entry_points.txt,sha256=pmmacoHCsvTTUB5dIPaY4i0H9gX7BQlpd3rBU-Jbv3A,50
|
|
23
|
+
dbus2mqtt-0.4.3.dist-info/licenses/LICENSE,sha256=a4bIEgyA9rrnAfUN90CgbgZ6BQIFHeABkk0JihiBaxM,1074
|
|
24
|
+
dbus2mqtt-0.4.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|