diff --git a/docs/docs/configuration/reference.md b/docs/docs/configuration/reference.md index bb7ae49a3c..8fad3a08df 100644 --- a/docs/docs/configuration/reference.md +++ b/docs/docs/configuration/reference.md @@ -19,6 +19,9 @@ mqtt: host: mqtt.server.com # Optional: port (default: shown below) port: 1883 + # Optional: MQTT transport mechanism (default: shown below) + # NOTE: must be tcp (raw MQTT) or websockets. + transport: tcp # Optional: topic prefix (default: shown below) # NOTE: must be unique if you are running multiple instances topic_prefix: frigate diff --git a/frigate/comms/mqtt.py b/frigate/comms/mqtt.py index 5a85a710b6..14a77b5d3a 100644 --- a/frigate/comms/mqtt.py +++ b/frigate/comms/mqtt.py @@ -168,9 +168,11 @@ def _on_disconnect( def _start(self) -> None: """Start mqtt client.""" + logger.info("MQTT transport mechanism: %s" % str(self.mqtt_config.transport)) self.client = mqtt.Client( callback_api_version=CallbackAPIVersion.VERSION2, client_id=self.mqtt_config.client_id, + transport=self.mqtt_config.transport, ) self.client.on_connect = self._on_connect self.client.on_disconnect = self._on_disconnect @@ -180,6 +182,8 @@ def _start(self) -> None: qos=1, retain=True, ) + if self.mqtt_config.transport == "websockets": + self.client.ws_set_options(path="/mqtt") # register callbacks callback_types = [ diff --git a/frigate/config/mqtt.py b/frigate/config/mqtt.py index 1f3bb025dd..6367000200 100644 --- a/frigate/config/mqtt.py +++ b/frigate/config/mqtt.py @@ -1,6 +1,6 @@ from typing import Optional -from pydantic import Field, ValidationInfo, model_validator +from pydantic import Field, ValidationInfo, model_validator, field_validator from typing_extensions import Self from frigate.const import FREQUENCY_STATS_POINTS @@ -15,6 +15,7 @@ class MqttConfig(FrigateBaseModel): enabled: bool = Field(default=True, title="Enable MQTT Communication.") host: str = Field(default="", title="MQTT Host") port: int = Field(default=1883, title="MQTT Port") + transport: str = Field(default="tcp", title="MQTT Transport Mechanism") topic_prefix: str = Field(default="frigate", title="MQTT Topic Prefix") client_id: str = Field(default="frigate", title="MQTT Client ID") stats_interval: int = Field( @@ -36,3 +37,10 @@ def user_requires_pass(self, info: ValidationInfo) -> Self: if (self.user is None) != (self.password is None): raise ValueError("Password must be provided with username.") return self + + @field_validator("transport") + @classmethod + def check_transport_mechanism(cls, v: str) -> str: + if v != "tcp" and v != "websockets": + raise ValueError("MQTT transport could only be tcp or websockets.") + return v