Add support for Mqtt protocol version 5 (#82260)

pull/82289/head
Jan Bouwhuis 2022-11-17 21:12:27 +01:00 committed by GitHub
parent b5390f55ce
commit b717da879f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 6 deletions

View File

@ -57,6 +57,7 @@ from .const import (
DEFAULT_QOS,
MQTT_CONNECTED,
MQTT_DISCONNECTED,
PROTOCOL_5,
PROTOCOL_31,
)
from .models import (
@ -272,8 +273,10 @@ class MqttClientSetup:
# should be able to optionally rely on MQTT.
import paho.mqtt.client as mqtt # pylint: disable=import-outside-toplevel
if config.get(CONF_PROTOCOL, DEFAULT_PROTOCOL) == PROTOCOL_31:
if (protocol := config.get(CONF_PROTOCOL, DEFAULT_PROTOCOL)) == PROTOCOL_31:
proto = mqtt.MQTTv31
elif protocol == PROTOCOL_5:
proto = mqtt.MQTTv5
else:
proto = mqtt.MQTTv311
@ -558,8 +561,9 @@ class MQTT:
self,
_mqttc: mqtt.Client,
_userdata: None,
_flags: dict[str, Any],
_flags: dict[str, int],
result_code: int,
properties: mqtt.Properties | None = None,
) -> None:
"""On connect callback.
@ -677,9 +681,13 @@ class MQTT:
_mqttc: mqtt.Client,
_userdata: None,
mid: int,
_granted_qos: tuple[Any, ...] | None = None,
_granted_qos_reason: tuple[int, ...] | mqtt.ReasonCodes | None = None,
_properties_reason: mqtt.ReasonCodes | None = None,
) -> None:
"""Publish / Subscribe / Unsubscribe callback."""
# The callback signature for on_unsubscribe is different from on_subscribe
# see https://github.com/eclipse/paho.mqtt.python/issues/687
# properties and reasoncodes are not used in Home Assistant
self.hass.add_job(self._mqtt_handle_mid, mid)
async def _mqtt_handle_mid(self, mid: int) -> None:
@ -695,7 +703,11 @@ class MQTT:
self._pending_operations[mid] = asyncio.Event()
def _mqtt_on_disconnect(
self, _mqttc: mqtt.Client, _userdata: None, result_code: int
self,
_mqttc: mqtt.Client,
_userdata: None,
result_code: int,
properties: mqtt.Properties | None = None,
) -> None:
"""Disconnected callback."""
self.connected = False

View File

@ -683,7 +683,11 @@ def try_connection(
result: queue.Queue[bool] = queue.Queue(maxsize=1)
def on_connect(
client_: mqtt.Client, userdata: None, flags: dict[str, Any], result_code: int
client_: mqtt.Client,
userdata: None,
flags: dict[str, Any],
result_code: int,
properties: mqtt.Properties | None = None,
) -> None:
"""Handle connection result."""
result.put(result_code == mqtt.CONNACK_ACCEPTED)

View File

@ -46,7 +46,8 @@ DEFAULT_RETAIN = False
PROTOCOL_31 = "3.1"
PROTOCOL_311 = "3.1.1"
SUPPORTED_PROTOCOLS = [PROTOCOL_31, PROTOCOL_311]
PROTOCOL_5 = "5"
SUPPORTED_PROTOCOLS = [PROTOCOL_31, PROTOCOL_311, PROTOCOL_5]
DEFAULT_PORT = 1883
DEFAULT_KEEPALIVE = 60

View File

@ -194,6 +194,45 @@ async def test_user_connection_works(
assert len(mock_finish_setup.mock_calls) == 1
async def test_user_v5_connection_works(
hass, mock_try_connection, mock_finish_setup, mqtt_client_mock
):
"""Test we can finish a config flow."""
mock_try_connection.return_value = True
result = await hass.config_entries.flow.async_init(
"mqtt", context={"source": config_entries.SOURCE_USER}
)
assert result["type"] == "form"
result = await hass.config_entries.flow.async_configure(
result["flow_id"], {"broker": "127.0.0.1", "advanced_options": True}
)
assert result["step_id"] == "broker"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
mqtt.CONF_BROKER: "another-broker",
mqtt.CONF_PORT: 2345,
mqtt.CONF_PROTOCOL: "5",
},
)
assert result["type"] == "create_entry"
assert result["result"].data == {
"broker": "another-broker",
"discovery": True,
"discovery_prefix": "homeassistant",
"port": 2345,
"protocol": "5",
}
# Check we tried the connection
assert len(mock_try_connection.mock_calls) == 1
# Check config entry got setup
assert len(mock_finish_setup.mock_calls) == 1
async def test_user_connection_fails(
hass, mock_try_connection_time_out, mock_finish_setup
):