Skip to content

Commit 8968d78

Browse files
authored
Merge pull request #457 from SAIC-iSmart-API/chore/aiomqtt
Migrate to aiomqtt (rebased)
2 parents 883f7b3 + 4fecfcd commit 8968d78

12 files changed

Lines changed: 472 additions & 225 deletions

File tree

poetry.lock

Lines changed: 31 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ requires-python = '>=3.12,<4.0'
1717
dependencies = [
1818
"saic-ismart-client-ng (>=0.9.3,<0.10.0)",
1919
'httpx (>=0.28.1,<0.29.0)',
20-
'gmqtt (>=0.7.0,<0.8.0)',
2120
'inflection (>=0.5.1,<0.6.0)',
2221
'apscheduler (>=3.11.0,<4.0.0)',
2322
'python-dotenv (>=1.1.1,<2.0.0)',
23+
"aiomqtt (>=2.4.0,<3.0.0)",
2424
]
2525

2626
[project.urls]

src/configuration/__init__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
from __future__ import annotations
22

33
from enum import Enum
4-
from typing import TYPE_CHECKING
4+
from typing import TYPE_CHECKING, Literal
55

66
if TYPE_CHECKING:
77
from zoneinfo import ZoneInfo
88

99
from integrations.openwb.charging_station import ChargingStation
1010

1111

12+
Transport = Literal["tcp", "websockets"]
13+
14+
1215
class TransportProtocol(Enum):
13-
def __init__(self, transport_mechanism: str, with_tls: bool) -> None:
16+
def __init__(self, transport_mechanism: Transport, with_tls: bool) -> None:
1417
self.transport_mechanism = transport_mechanism
1518
self.with_tls = with_tls
1619

src/configuration/parser.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,15 +105,18 @@ def __parse_mqtt_transport(args: Namespace, config: Configuration) -> None:
105105
args.tls_server_cert_check_hostname
106106
)
107107
else:
108-
msg = f"Invalid MQTT URI scheme: {parse_result.scheme}, use tcp or ws"
108+
msg = f"Invalid MQTT URI scheme: {parse_result.scheme}, use tls, tcp or ws"
109109
raise SystemExit(msg)
110110

111111
if parse_result.port:
112112
config.mqtt_port = parse_result.port
113-
elif config.mqtt_transport_protocol == TransportProtocol.TCP:
114-
config.mqtt_port = 1883
115-
else:
113+
elif config.mqtt_transport_protocol == TransportProtocol.TLS:
114+
config.mqtt_port = 8883
115+
elif config.mqtt_transport_protocol == TransportProtocol.WS:
116116
config.mqtt_port = 9001
117+
else:
118+
# fallback to default mqtt port
119+
config.mqtt_port = 1883
117120
config.mqtt_host = str(parse_result.hostname)
118121

119122

src/log_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
MODULES_DEFAULT_LOG_LEVEL = {
99
"asyncio": "WARNING",
10-
"gmqtt": "WARNING",
10+
"aiomqtt": "WARNING",
1111
"httpcore": "WARNING",
1212
"httpx": "WARNING",
1313
"saic_ismart_client_ng": "WARNING",

src/main.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,5 @@
2727
configuration = process_command_line()
2828

2929
mqtt_gateway = MqttGateway(configuration)
30+
3031
asyncio.run(mqtt_gateway.run(), debug=debug_log_enabled())

src/publisher/core.py

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,30 +102,55 @@ def publish_json(
102102
no_prefix: bool = False,
103103
*,
104104
retain: bool = True,
105+
qos: int = 0,
105106
) -> None:
106107
raise NotImplementedError
107108

108109
@abstractmethod
109110
def publish_str(
110-
self, key: str, value: str, no_prefix: bool = False, *, retain: bool = True
111+
self,
112+
key: str,
113+
value: str,
114+
no_prefix: bool = False,
115+
*,
116+
retain: bool = True,
117+
qos: int = 0,
111118
) -> None:
112119
raise NotImplementedError
113120

114121
@abstractmethod
115122
def publish_int(
116-
self, key: str, value: int, no_prefix: bool = False, *, retain: bool = True
123+
self,
124+
key: str,
125+
value: int,
126+
no_prefix: bool = False,
127+
*,
128+
retain: bool = True,
129+
qos: int = 0,
117130
) -> None:
118131
raise NotImplementedError
119132

120133
@abstractmethod
121134
def publish_bool(
122-
self, key: str, value: bool, no_prefix: bool = False, *, retain: bool = True
135+
self,
136+
key: str,
137+
value: bool,
138+
no_prefix: bool = False,
139+
*,
140+
retain: bool = True,
141+
qos: int = 0,
123142
) -> None:
124143
raise NotImplementedError
125144

126145
@abstractmethod
127146
def publish_float(
128-
self, key: str, value: float, no_prefix: bool = False, *, retain: bool = True
147+
self,
148+
key: str,
149+
value: float,
150+
no_prefix: bool = False,
151+
*,
152+
retain: bool = True,
153+
qos: int = 0,
129154
) -> None:
130155
raise NotImplementedError
131156

@@ -173,7 +198,7 @@ def publish(
173198
raise TypeError(msg)
174199

175200
@abstractmethod
176-
def clear_topic(self, key: str, no_prefix: bool = False) -> None:
201+
def clear_topic(self, key: str, no_prefix: bool = False, qos: int = 0) -> None:
177202
raise NotImplementedError
178203

179204
def get_mqtt_account_prefix(self) -> str:
@@ -249,7 +274,9 @@ def __anonymize(self, data: T) -> T:
249274
return data
250275

251276
def keepalive(self) -> None:
252-
self.publish_str(mqtt_topics.INTERNAL_LWT, "online", False)
277+
self.publish_str(
278+
mqtt_topics.INTERNAL_LWT, "online", no_prefix=False, retain=True, qos=1
279+
)
253280

254281
@staticmethod
255282
def anonymize_str(value: str) -> str:

src/publisher/log_publisher.py

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,36 +30,61 @@ def publish_json(
3030
no_prefix: bool = False,
3131
*,
3232
retain: bool = True,
33+
qos: int = 0,
3334
) -> None:
3435
anonymized_json = self.dict_to_anonymized_json(data)
3536
self.internal_publish(key, anonymized_json, retain=retain)
3637

3738
@override
3839
def publish_str(
39-
self, key: str, value: str, no_prefix: bool = False, *, retain: bool = True
40+
self,
41+
key: str,
42+
value: str,
43+
no_prefix: bool = False,
44+
*,
45+
retain: bool = True,
46+
qos: int = 0,
4047
) -> None:
4148
self.internal_publish(key, value, retain=retain)
4249

4350
@override
4451
def publish_int(
45-
self, key: str, value: int, no_prefix: bool = False, *, retain: bool = True
52+
self,
53+
key: str,
54+
value: int,
55+
no_prefix: bool = False,
56+
*,
57+
retain: bool = True,
58+
qos: int = 0,
4659
) -> None:
4760
self.internal_publish(key, value, retain=retain)
4861

4962
@override
5063
def publish_bool(
51-
self, key: str, value: bool, no_prefix: bool = False, *, retain: bool = True
64+
self,
65+
key: str,
66+
value: bool,
67+
no_prefix: bool = False,
68+
*,
69+
retain: bool = True,
70+
qos: int = 0,
5271
) -> None:
5372
self.internal_publish(key, value, retain=retain)
5473

5574
@override
5675
def publish_float(
57-
self, key: str, value: float, no_prefix: bool = False, *, retain: bool = True
76+
self,
77+
key: str,
78+
value: float,
79+
no_prefix: bool = False,
80+
*,
81+
retain: bool = True,
82+
qos: int = 0,
5883
) -> None:
5984
self.internal_publish(key, value, retain=retain)
6085

6186
@override
62-
def clear_topic(self, key: str, no_prefix: bool = False) -> None:
87+
def clear_topic(self, key: str, no_prefix: bool = False, qos: int = 0) -> None:
6388
self.internal_publish(key, None)
6489

6590
def internal_publish(

0 commit comments

Comments
 (0)