diff --git a/changelog b/changelog index 22ea190..17e1ee5 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,6 @@ 0.8.0b7: + Allow more MQTT config. + Fix headers. Distinguish between user/shared location. Fix missing event issue. Tidy capture code. diff --git a/pyaarlo/__init__.py b/pyaarlo/__init__.py index 0c9e417..558d982 100644 --- a/pyaarlo/__init__.py +++ b/pyaarlo/__init__.py @@ -126,6 +126,9 @@ class PyArlo(object): based on camera model. Can also be `v1`, `v2` or `v3`. Use `v3` for the new location API. * **reconnect_every** - Time, in minutes, to close and relogin to Arlo. * **snapshot_timeout** - Time, in seconds, to stop the snapshot attempt and return the camera to the idle state. + * **mqtt_host** - specify the mqtt host to use, default mqtt-cluster.arloxcld.com + * **mqtt_hostname_check** - disable MQTT host SSL certificate checking, default True + * **mqtt_transport** - specify either `websockets` or `tcp`, default `tcp` **Attributes** diff --git a/pyaarlo/backend.py b/pyaarlo/backend.py index eb196bb..ac9b7e8 100644 --- a/pyaarlo/backend.py +++ b/pyaarlo/backend.py @@ -501,17 +501,22 @@ def _mqtt_main(self): # Create and set up the MQTT client. self._event_client = mqtt.Client( - client_id=self._event_client_id, transport="websockets" + client_id=self._event_client_id, transport=self._arlo.cfg.mqtt_transport ) self._event_client.on_log = self._mqtt_on_log self._event_client.on_connect = self._mqtt_on_connect self._event_client.on_message = self._mqtt_on_message - self._event_client.tls_set_context(ssl.create_default_context()) + ssl_context = ssl.create_default_context() + ssl_context.check_hostname = self._arlo.cfg.mqtt_hostname_check + self._event_client.tls_set_context(ssl_context) self._event_client.username_pw_set(f"{self._user_id}", self._token) self._event_client.ws_set_options(path=MQTT_PATH, headers=headers) + self.debug(f"mqtt: host={self._arlo.cfg.mqtt_host}, " + f"check={self._arlo.cfg.mqtt_hostname_check}, " + f"transport={self._arlo.cfg.mqtt_transport}") # Connect. - self._event_client.connect(MQTT_HOST, port=443, keepalive=60) + self._event_client.connect(self._arlo.cfg.mqtt_host, port=443, keepalive=60) self._event_client.loop_forever() except Exception as e: @@ -671,7 +676,7 @@ def _auth(self): "Source": "arloCamWeb", "User-Agent": self._user_agent, "x-user-device-id": self._user_id, - "x-user-device-name": "QlJPV1NFUg==", + "x-user-device-automation-name": "QlJPV1NFUg==", "x-user-device-type": "BROWSER", } @@ -822,7 +827,7 @@ def _validate(self): "User-Agent": self._user_agent, "Source": "arloCamWeb", "x-user-device-id": self._user_id, - "x-user-device-name": "QlJPV1NFUg==", + "x-user-device-automation-name": "QlJPV1NFUg==", "x-user-device-type": "BROWSER", } diff --git a/pyaarlo/cfg.py b/pyaarlo/cfg.py index cf5f21f..9100dbc 100644 --- a/pyaarlo/cfg.py +++ b/pyaarlo/cfg.py @@ -3,6 +3,7 @@ from .constant import ( DEFAULT_AUTH_HOST, DEFAULT_HOST, + MQTT_HOST, PRELOAD_DAYS, TFA_CONSOLE_SOURCE, TFA_DEFAULT_HOST, @@ -59,6 +60,18 @@ def host(self): def auth_host(self): return self._kw.get("auth_host", DEFAULT_AUTH_HOST) + @property + def mqtt_host(self): + return self._kw.get("mqtt_host", MQTT_HOST) + + @property + def mqtt_hostname_check(self): + return self._kw.get("mqtt_hostname_check", True) + + @property + def mqtt_transport(self): + return self._kw.get("mqtt_transport", "tcp") + @property def dump(self): return self._kw.get("dump", False) diff --git a/setup.py b/setup.py index b77e227..6624741 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ def readme(): 'click', 'pycryptodome', 'unidecode', - 'cloudscraper>=1.2.64', + 'cloudscraper>=1.2.71', 'paho-mqtt', 'cryptography' ],