Add support for Mqtt protocol version 5 (#82260)
parent
b5390f55ce
commit
b717da879f
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
):
|
||||
|
|
Loading…
Reference in New Issue