merossiot Python Library

repository·0.4.X.X·Indexed 19 days ago

https://github.com/albertogeniola/merossiot

A Python library for interfacing with Meross IoT devices, including switches, bulbs, garage door openers, and sensors. It supports device discovery, control, and data retrieval via MQTT and HTTP. The library provides a variety of mixins for specific device types (e.g., LightMixin, ElectricityMixin, ThermostatModeMixin) and includes the meross_sniffer tool for capturing low-level device data.

Tokens
7.4K
Snippets
35
Records
42
Agent score
68%

What's inside merossiot

  1. Operate garage door openers with GarageOpenerMixin

    0.4.X.X

    Garage door functionality is implemented via meross_iot.controller.mixins.garage.GarageOpenerMixin.

    Important Behavior Notes:

    • Most openers simply simulate a button press.
    • Door state is monitored by a separate proximity sensor.
    • The sensor typically only reports if the door is 'closed' or 'not closed'.
    • When opening the door, the sensor may report 'door opened' almost immediately after the motor starts, even before the door is fully open.

    Warning: Operating garage doors involves physical movement and may be dangerous. Use this capability at your own risk.

    # Example of operating a door opener (based on examples/cover.py)
    await device.async_open()
    await device.async_close()
  2. Important usage warnings and limitations

    0.4.X.X

    Unofficial Support

    This library is unofficial and unsupported by Meross. It was developed by analyzing network traffic between the Meross App and Meross backends (HTTP API and MQTT broker).

    Production Suitability

    Do not use this library for production environments. There is no warranty that Meross will not change its protocols or explicitly block access.

    Rate Limiting Risks

    Meross has introduced rate-limiting features. Using this library may lead to account limitations or bans. If you are building 3rd party plugins (e.g., for home automation frameworks) using this library, you should inform the end-users of these risks.

  3. Prerequisites for using MerossIot

    0.4.X.X
    The merossiot library is designed for Python developers and is built heavily around the asyncio pattern. To use this library effectively, you must have a solid understanding of asynchronous programming in Python (Python 3.5+ async patterns). Without familiarity with asyncio, performing basic tasks with the library will be difficult.
  4. How Meross device pairing works

    0.4.X.X

    The pairing process involves transitioning a device from Access Point (AP) mode to a connected state on a domestic Wi-Fi network using an MQTT broker.

    1. AP Mode: The device creates an open Wi-Fi network named Meross_<STR1>_<STR2>.
    2. MQTT Configuration: The client app sends a POST request to the device's IP at /config with the Appliance.Config.Key namespace. This provides the MQTT_HOST, MQTT_PORT, userId, and a secret key.
    3. Wi-Fi Configuration: The client app sends a second POST request to /config with the Appliance.Config.Wifi namespace, containing the ssid and password (both Base64 encoded).
    4. Connection: The device reboots, connects to the Wi-Fi, and then attempts to connect to the MQTT broker.
    # Step 1: Configure MQTT credentials
    POST /config HTTP/1.1
    Host: <PLUG_IP_ADDRESS>
    Content-Type: application/json
    
    {
        "header": {
            "from": "{{FROM_DEVICE}}",
            "messageId": "{{MESSAGE_ID}}",
            "timestamp": {{TIMESTAMP}},
            "sign": "{{SIGNATURE}}",
            "method": "SET",
            "namespace": "Appliance.Config.Key",
            "triggerSrc": "Android",
            "uuid": "{{TARGET_DEVICE_UUID}}"
        },
        "payload": {
            "key": {
                "gateway": {
                    "host":"{{MQTT_HOST}}",
                    "port":"{{MQTT_PORT}}"
                },
                "key": "{{KEY}}",
                "userId": "{{USER_ID}}"
            }
        }
    }
    
    # Step 2: Configure Wi-Fi credentials
    POST /config HTTP/1.1
    Host: <PLUG_IP_ADDRESS>
    Content-Type: application/json
    
    {
        "header": {
            "from": "http://10.10.10.1/config",
            "messageId": "{{MESSAGE_ID}}",
            "timestamp": {{TIMESTAMP}},
            "sign": "{{SIGNATURE}}",
            "method": "SET",
            "namespace": "Appliance.Config.Wifi"
        },
        "payload": {
            "wifi": {
                "ssid": "{{BASE64_ENCODED_SSID}}",
                "password": "{{BASE64_ENCODED_PASSWORD}}"
            }
        }
    }
  5. Configure logging verbosity

    0.4.X.X

    The library uses the standard Python logging module. You can control the verbosity of the library's output by setting the log level for the meross_iot logger.

    import asyncio
    import os
    import logging
    from meross_iot.http_api import MerossHttpClient
    from meross_iot.manager import MerossManager
    
    # Set the level to WARNING to suppress DEBUG and INFO messages
    meross_root_logger = logging.getLogger("meross_iot")
    meross_root_logger.setLevel(logging.WARNING)
  6. Install meross-iot from source

    0.4.X.X

    If you prefer to install the library manually from the GitHub repository, clone the source, install the required dependencies, and then install the package locally.

    git clone https://github.com/albertogeniola/MerossIot.git
    cd MerossIot
    pip install -r requirements.txt
    pip install .
  7. Discover Meross devices using MerossManager

    0.4.X.X

    To discover Meross devices, you must use the MerossManager class, which handles MQTT and HTTP communication.

    1. Initialize the manager using async_init().
    2. Trigger discovery using async_device_discovery(). This queries the HTTP API for device UUIDs. Warning: Do not call async_device_discovery() too frequently to avoid being banned by the Meross API.
    3. Access discovered devices using find_device() to retrieve items from the manager's local cache.
    # Example of listing devices (based on examples/list.py)
    import asyncio
    from meross_iot.manager import MerossManager
    
    async def main():
        manager = MerossManager(email='...', password='...')
        await manager.async_init()
        await manager.async_device_discovery()
        
        for device in manager.find_devices():
            print(device)
    
    asyncio.run(main())
  8. Use the meross_sniffer tool to collect device data

    0.4.X.X

    If a new Meross device has features not yet supported by the library, you can use the meross_sniffer tool to capture the low-level data exchanged between the Meross App and the device.

    Security Warning

    Always use an ad-hoc Meross account for sniffing. Even though the tool is designed not to gather credentials, the Meross App might send sensitive information over the network. It is strongly advised to change your password or use a dedicated account for this purpose.

    Usage Steps

    1. Prepare Account: Create a new Meross account (or change your current password) and ensure the target device is added to this account and is ONLINE.
    2. Run Sniffer: Execute the command meross_sniffer.
    3. Authenticate: Log in with your Meross credentials.
    4. Select Device: Choose the target device from the list (ensure it reports as ONLINE).
    5. Capture Data: Use the Meross App to interact with the device features you wish to sniff.
    6. Stop & Export: Press ENTER to stop the sniffer. The tool will generate a data.zip file in your current directory.
    7. Contribute: You can upload the data.zip file to GitHub to help implement support for the new features.
    meross_sniffer
  9. Ensure consistent device state using async_update()

    0.4.X.X

    While the library uses MQTT PUSH notifications to keep device status aligned, the initial state fetched might be inconsistent.

    To ensure you have the most accurate data, call the async_update() method on the device object. This fetches the complete, current device state. After the first call, the library will handle subsequent updates via push notifications.

    Best Practice: If your internet connection is lost and then restored, call async_update() to synchronize the state, as the MerossManager may have missed PUSH notifications while disconnected.

    # Example pattern to ensure state consistency
    await device.async_update()
  10. Cache and reload device registry information

    0.4.X.X

    The MerossManager maintains a device registry of discovered devices. To reduce calls to the Meross Cloud and avoid repeated discovery processes, you can export this registry to a file and reload it later.

    1. Exporting: Use manager.dump_device_registry("filename") to save the current registry to a file.
    2. Loading: Use manager.load_devices_from_dump("filename") to populate the manager from a previously saved file. This allows you to bypass the async_device_discovery() step.
    # --- To Dump Registry ---
    manager = MerossManager(http_client=http_api_client)
    await manager.async_init()
    await manager.async_device_discovery()
    manager.dump_device_registry("test.dump")
    
    # --- To Load Registry ---
    manager = MerossManager(http_client=http_api_client)
    await manager.async_init()
    manager.load_devices_from_dump("test.dump")
    print("Registry dump loaded.")