diff --git a/.version b/.version index 825db90..c3317ad 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.4.5.8 \ No newline at end of file +0.4.5.9 \ No newline at end of file diff --git a/README.md b/README.md index 312acfe..ef54f4f 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Due to the popularity of the library, I've decided to list it publicly on the Pi So, the installation is as simple as typing the following command: ```bash -pip install meross_iot==0.4.5.8 +pip install meross_iot==0.4.5.9 ``` ## Usage & Full Documentation @@ -190,8 +190,9 @@ Anyway, feel free to contribute via donations!

## Changelog -#### 0.4.5.8 +#### 0.4.5.9 - Improve meross_sniffer utility: add support to collect messages spoofing the hardware device on meross cloud. +- Allow string namespace value for execute_command within manager.
Older diff --git a/meross_iot/manager.py b/meross_iot/manager.py index 8cfbba6..45893b2 100644 --- a/meross_iot/manager.py +++ b/meross_iot/manager.py @@ -791,7 +791,7 @@ async def async_execute_cmd( mqtt_port: int, destination_device_uuid: str, method: str, - namespace: Namespace, + namespace: Union[Namespace, str], payload: dict, timeout: float = DEFAULT_COMMAND_TIMEOUT, override_transport_mode: TransportMode = None @@ -855,7 +855,7 @@ async def _async_execute_cmd_http(self, device_ip: str, destination_device_uuid: str, method: str, - namespace: Namespace, + namespace: Union[Namespace,str], payload: dict, timeout: float = 10.0): # Send the message over the network @@ -921,7 +921,7 @@ async def _notify_connection_drop(self): pushn = OnlinePushNotification(originating_device_uuid=d.uuid, raw_data={'online': {'status': -1}}) await self._handle_and_dispatch_push_notification(pushn) - def _build_mqtt_message(self, method: str, namespace: Namespace, payload: dict, destination_device_uuid: str): + def _build_mqtt_message(self, method: str, namespace: Union[Namespace, str], payload: dict, destination_device_uuid: str): """ Sends a message to the Meross MQTT broker, respecting the protocol payload. @@ -951,12 +951,16 @@ def _build_mqtt_message(self, method: str, namespace: Namespace, payload: dict, md5_hash.update(strtohash.encode("utf8")) signature = md5_hash.hexdigest().lower() + if not isinstance(namespace, Namespace) and not isinstance(namespace, str): + raise ValueError("Namespace parameter must be a Namespace enum or a string.") + namespace_val = namespace.value if isinstance(namespace, Namespace) else namespace + data = { "header": { "from": self._client_response_topic, "messageId": messageId, # Example: "122e3e47835fefcd8aaf22d13ce21859" "method": method, # Example: "GET", - "namespace": namespace.value, # Example: "Appliance.System.All", + "namespace": namespace_val, # Example: "Appliance.System.All", "payloadVersion": 1, "sign": signature, # Example: "b4236ac6fb399e70c3d61e98fcb68b74", "timestamp": timestamp, diff --git a/utilities/meross_sniffer.py b/utilities/meross_sniffer.py index 956dc37..0fdf4b7 100644 --- a/utilities/meross_sniffer.py +++ b/utilities/meross_sniffer.py @@ -222,18 +222,22 @@ async def _async_sniff(device_sniffer: FakeDeviceSniffer, zip_obj: ZipFile, mero # Attempt now to retrieve a response simulating that command to the real device print("Replicating the same message to the device in order to catch the real response...") - response = await meross_manager.async_execute_cmd( - mqtt_hostname=selected_device.get_mqtt_host(), - mqtt_port=selected_device.get_mqtt_port(), - destination_device_uuid=selected_device.uuid, - method=method, - namespace=Namespace(namespace), - payload=payload, - timeout=5.0, - override_transport_mode=TransportMode.MQTT_ONLY - ) - f.write(f"\nResponse: \n") - f.write(json.dumps(response)) + try: + response = await meross_manager.async_execute_cmd( + mqtt_hostname=selected_device.get_mqtt_host(), + mqtt_port=selected_device.get_mqtt_port(), + destination_device_uuid=selected_device.uuid, + method=method, + namespace=namespace, + payload=payload, + timeout=5.0, + override_transport_mode=TransportMode.MQTT_ONLY + ) + f.write(f"\nResponse: \n") + f.write(json.dumps(response)) + except Exception as e: + l.exception("An error occurred while collecting a response from the device simulating the latest message. No response will be catched.") + print("Skipping response collection.") print(f"Waiting up to 30 seconds for messages...") zip_obj.write(f.name, f"sniffed_commands.txt")