Skip to content

Commit

Permalink
Improve sniffing and handle unknown namespace edge case
Browse files Browse the repository at this point in the history
  • Loading branch information
albertogeniola committed Jan 11, 2023
1 parent e5a23a1 commit 890c374
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.4.5.8
0.4.5.9
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -190,8 +190,9 @@ Anyway, feel free to contribute via donations!
</p>

## 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.

<details>
<summary>Older</summary>
Expand Down
12 changes: 8 additions & 4 deletions meross_iot/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down
28 changes: 16 additions & 12 deletions utilities/meross_sniffer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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")

Expand Down

0 comments on commit 890c374

Please sign in to comment.