Skip to content

Commit

Permalink
improve mqtt connection (#303)
Browse files Browse the repository at this point in the history
  • Loading branch information
prvakt authored Dec 29, 2024
1 parent 2948ff3 commit 6bfdbef
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 7 deletions.
4 changes: 2 additions & 2 deletions myskoda/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@
MQTT_ACCOUNT_EVENT_TOPICS = [
"account-event/privacy",
]
MQTT_KEEPALIVE = 15
MQTT_KEEPALIVE = 60
MQTT_RECONNECT_DELAY = 5

MQTT_FAST_RETRY = 10
MAX_RETRIES = 5

REQUEST_TIMEOUT_IN_SECONDS = 300
17 changes: 12 additions & 5 deletions myskoda/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
MQTT_BROKER_HOST,
MQTT_BROKER_PORT,
MQTT_KEEPALIVE,
MQTT_FAST_RETRY,
MQTT_OPERATION_TOPICS,
MQTT_RECONNECT_DELAY,
MQTT_SERVICE_EVENT_TOPICS,
Expand All @@ -43,7 +44,7 @@

_LOGGER = logging.getLogger(__name__)
TOPIC_RE = re.compile("^(.*?)/(.*?)/(.*?)/(.*?)$")

app_uuid = uuid.uuid4()

def _create_ssl_context() -> ssl.SSLContext:
"""Create a SSL context for the MQTT connection."""
Expand Down Expand Up @@ -144,17 +145,20 @@ async def _connect_and_listen(self) -> None:
"""
_LOGGER.debug("Starting _connect_and_listen")
self._running = True
retry_count = 0 # Track the number of retries
self._reconnect_delay = MQTT_RECONNECT_DELAY # Initial delay for backoff
while self._running:
try:
async with aiomqtt.Client(
hostname=self.hostname,
port=self.port,
username="android-app", # Explicit username from working payload
identifier=str(uuid.uuid4()), # Dynamically generate a UUID-based client ID
identifier=str(app_uuid),
password=await self.authorization.get_access_token(),
logger=_LOGGER,
tls_context=_SSL_CONTEXT if self.enable_ssl else None,
keepalive=MQTT_KEEPALIVE,
clean_session=True,
) as client:
_LOGGER.info("Connected to MQTT")
_LOGGER.debug("using MQTT client %s", client)
Expand All @@ -170,16 +174,19 @@ async def _connect_and_listen(self) -> None:

self._subscribed.set()
self._reconnect_delay = MQTT_RECONNECT_DELAY
retry_count = 0 # Reset retry count on successful connection
async for message in client.messages:
self._on_message(message)
except aiomqtt.MqttError as exc:
retry_count += 1
_LOGGER.info(
"Connection lost (%s); reconnecting in %ss", exc, self._reconnect_delay
)
await asyncio.sleep(self._reconnect_delay)
self._reconnect_delay *= 2
self._reconnect_delay += uniform(0, 1) # noqa: S311
_LOGGER.debug("Increased reconnect backoff to %s", self._reconnect_delay)
if retry_count > MQTT_FAST_RETRY: # first x retries are not exponential
self._reconnect_delay *= 2
self._reconnect_delay += uniform(0, 1) # noqa: S311
_LOGGER.debug("Increased reconnect backoff to %s", self._reconnect_delay)

def _on_message(self, msg: aiomqtt.Message) -> None:
"""Deserialize received MQTT message and emit Event to subscribed callbacks."""
Expand Down

0 comments on commit 6bfdbef

Please sign in to comment.