Quick start

We (developers) all know how important is to get things working fast. In this section, you can find some quick-reference recipies that can be used for start working straight forward.

Note

Immediately getting hands dirty with code is OK for quick demos. However, you should really read the entire documentation carefully in order to avoid gotchas. After all, someone has taken the effort of writing, why would you not read it?

Listing devices

Listing Meross devices
 1import asyncio
 2import os
 3
 4from meross_iot.http_api import MerossHttpClient
 5from meross_iot.manager import MerossManager
 6
 7EMAIL = os.environ.get('MEROSS_EMAIL') or "YOUR_MEROSS_CLOUD_EMAIL"
 8PASSWORD = os.environ.get('MEROSS_PASSWORD') or "YOUR_MEROSS_CLOUD_PASSWORD"
 9
10
11async def main():
12    # Setup the HTTP client API from user-password
13    http_api_client = await MerossHttpClient.async_from_user_password(email=EMAIL, password=PASSWORD, api_base_url="https://iot.meross.com")
14
15    # Setup and start the device manager
16    manager = MerossManager(http_client=http_api_client)
17    await manager.async_init()
18
19    # Discover devices.
20    await manager.async_device_discovery()
21    meross_devices = manager.find_devices()
22
23    # Print them
24    print("I've found the following devices:")
25    for dev in meross_devices:
26        print(f"- {dev.name} ({dev.type}): {dev.online_status}")
27
28    # Close the manager and logout from http_api
29    manager.close()
30    await http_api_client.async_logout()
31
32if __name__ == '__main__':
33    if os.name == 'nt':
34        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
35    loop = asyncio.get_event_loop()
36    loop.run_until_complete(main())
37    loop.stop()

In order to discover meross devices, you need to setup a MerossManager. That class is the one in charge of handling mqtt and http calls to respective endpoints. It also keeps track of discovered devices and allows you to discover new ones.

Once the manager has been created and started via async_init(), you can look for devices via the the async_device_discovery() method. This method will query the HTTP API for getting the UUIDs (alongside other info) of the Meross devices registered with your account. To see the latest discovered devices cached by the MerossManager you can use the find_device(). You should not invoke async_device_discovery() too frequently as doing so might trigger some alert/banning from Meross API.

The find_device() method supports some filtering arguments to search for specific devices. Have a look at the following method signature for more details.

Controlling switches

Toggling smart switches
 1import asyncio
 2import os
 3import os
 4from meross_iot.http_api import MerossHttpClient
 5from meross_iot.manager import MerossManager
 6
 7EMAIL = os.environ.get('MEROSS_EMAIL') or "YOUR_MEROSS_CLOUD_EMAIL"
 8PASSWORD = os.environ.get('MEROSS_PASSWORD') or "YOUR_MEROSS_CLOUD_PASSWORD"
 9
10
11async def main():
12    # Setup the HTTP client API from user-password
13    http_api_client = await MerossHttpClient.async_from_user_password(email=EMAIL, password=PASSWORD, api_base_url="https://iot.meross.com")
14
15    # Setup and start the device manager
16    manager = MerossManager(http_client=http_api_client)
17    await manager.async_init()
18
19    # Retrieve all the MSS310 devices that are registered on this account
20    await manager.async_device_discovery()
21    plugs = manager.find_devices(device_type="mss310")
22
23    if len(plugs) < 1:
24        print("No MSS310 plugs found...")
25    else:
26        # Turn it on channel 0
27        # Note that channel argument is optional for MSS310 as they only have one channel
28        dev = plugs[0]
29
30        # Update device status: this is needed only the very first time we play with this device (or if the
31        #  connection goes down)
32        await dev.async_update()
33
34        print(f"Turning on {dev.name}...")
35        await dev.async_turn_on(channel=0)
36        print("Waiting a bit before turing it off")
37        await asyncio.sleep(5)
38        print(f"Turing off {dev.name}")
39        await dev.async_turn_off(channel=0)
40
41    # Close the manager and logout from http_api
42    manager.close()
43    await http_api_client.async_logout()
44
45if __name__ == '__main__':
46    if os.name == 'nt':
47        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
48    loop = asyncio.get_event_loop()
49    loop.run_until_complete(main())
50    loop.stop()

Meross devices that supports toggling and on/off commands implement either the meross_iot.controller.mixins.toggle.ToggleMixin or meross_iot.controller.mixins.toggle.ToggleXMixin. Both classes expose a number of methods to control these devices, such async_turn_off() and async_turn_on().

Refer to the ToggleXMixn for a panoramic around those.

Controlling bulbs

Operating smart bulbs
 1import asyncio
 2import os
 3from random import randint
 4
 5from meross_iot.http_api import MerossHttpClient
 6from meross_iot.manager import MerossManager
 7from meross_iot.model.enums import OnlineStatus
 8
 9EMAIL = os.environ.get('MEROSS_EMAIL') or "YOUR_MEROSS_CLOUD_EMAIL"
10PASSWORD = os.environ.get('MEROSS_PASSWORD') or "YOUR_MEROSS_CLOUD_PASSWORD"
11
12
13async def main():
14    # Setup the HTTP client API from user-password
15    http_api_client = await MerossHttpClient.async_from_user_password(email=EMAIL, password=PASSWORD, api_base_url="https://iot.meross.com")
16
17    # Setup and start the device manager
18    manager = MerossManager(http_client=http_api_client)
19    await manager.async_init()
20
21    # Retrieve the MSL120 devices that are registered on this account
22    await manager.async_device_discovery()
23    plugs = manager.find_devices(device_type="msl120", online_status=OnlineStatus.ONLINE)
24
25    if len(plugs) < 1:
26        print("No online msl120 smart bulbs found...")
27    else:
28        # Let's play with RGB colors. Note that not all light devices will support
29        # rgb capabilities. For this reason, we first need to check for rgb before issuing
30        # color commands.
31        dev = plugs[0]
32
33        # Update device status: this is needed only the very first time we play with this device (or if the
34        #  connection goes down)
35        await dev.async_update()
36        if not dev.get_supports_rgb():
37            print("Unfortunately, this device does not support RGB...")
38        else:
39            # Check the current RGB color
40            current_color = dev.get_rgb_color()
41            print(f"Currently, device {dev.name} is set to color (RGB) = {current_color}")
42            # Randomly chose a new color
43            rgb = randint(0, 255), randint(0, 255), randint(0, 255)
44            print(f"Chosen random color (R,G,B): {rgb}")
45            await dev.async_set_light_color(rgb=rgb)
46            print("Color changed!")
47
48    # Close the manager and logout from http_api
49    manager.close()
50    await http_api_client.async_logout()
51
52if __name__ == '__main__':
53    if os.name == 'nt':
54        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
55    loop = asyncio.get_event_loop()
56    loop.run_until_complete(main())
57    loop.stop()

Smart bulbs implement the meross_iot.controller.mixins.light.LightMixin interface, which handle RGB color settings, as well as luminance and color temperature. More details on this class are available here

Controlling garage door openers

Meross garage door openers are somehow basic: in most cases they only simulate the button-press of the garage door. The door state is instead monitored with a specific sensor, mounted on the garage door. Such sensor is not able to tell you the exact state of the garage door. In fact, it only tells you if the door is closed or not closed (i.e. empty).

When you operate the Meross Garage Opener, it sends the signal to the garage motor, which starts opening/closing. Then, once the door closes, the sensor reports “closing state”, and the door is marked as closed. However, when opening the door, things are quite different: as soon as the motor is operated, the sensor quickly reports “door opened” state as the magnet proximity sensor immediately changes state, even if the door is not completely opened.

Warning

Operating garage door is dangerous and might not be safe. You use this capability at your own risk, absolving the author of this library of all responsibility.

Operating door opener
 1import asyncio
 2import os
 3
 4from meross_iot.controller.mixins.garage import GarageOpenerMixin
 5from meross_iot.http_api import MerossHttpClient
 6from meross_iot.manager import MerossManager
 7
 8EMAIL = os.environ.get('MEROSS_EMAIL') or "YOUR_MEROSS_CLOUD_EMAIL"
 9PASSWORD = os.environ.get('MEROSS_PASSWORD') or "YOUR_MEROSS_CLOUD_PASSWORD"
10
11
12async def main():
13    # Setup the HTTP client API from user-password
14    http_api_client = await MerossHttpClient.async_from_user_password(email=EMAIL, password=PASSWORD, api_base_url="https://iot.meross.com")
15
16    # Setup and start the device manager
17    manager = MerossManager(http_client=http_api_client)
18    await manager.async_init()
19
20    # Retrieve all the devices that implement the garage-door opening mixin
21    await manager.async_device_discovery()
22    openers = manager.find_devices(device_class=GarageOpenerMixin, device_type="msg100")
23
24    if len(openers) < 1:
25        print("No garage opener found...")
26    else:
27        dev = openers[0]
28
29        # Update device status: this is needed only the very first time we play with this device (or if the
30        #  connection goes down)
31        await dev.async_update()
32
33        # Check current door status
34        open_status = dev.get_is_open()
35        if open_status:
36            print(f"Door {dev.name} is open")
37        else:
38            print(f"Door {dev.name} is closed")
39
40        # To open the door, uncomment the following:
41        #print(f"Opening door {dev.name}...")
42        #await dev.async_open(channel=0)
43        #print("Door opened!")
44        #
45        # Wait a bit before closing it again
46        #await asyncio.sleep(5)
47        #
48        #print(f"Closing door {dev.name}...")
49        #await dev.async_close()
50        # print(f"Door closed!")
51
52    # Close the manager and logout from http_api
53    manager.close()
54    await http_api_client.async_logout()
55
56if __name__ == '__main__':
57    if os.name == 'nt':
58        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
59    loop = asyncio.get_event_loop()
60    loop.run_until_complete(main())
61    loop.stop()

Garage door functionality is implemented by the meross_iot.controller.mixins.garage.GarageOpenerMixin. Have a look at here for more details.

Reading sensors

Meross devices might be equipped with sensors. Some devices (like temperature and humidity sensor) are readonly, configuring themselves as proper sensor devices. Others, as the MSS310, the Thermostat valve or the garage openers are instead actuators that offer some data reading capabilities. For this reason, there is no “general” sensor mixin class; on the contrary, you should rely on the capabilities offered by other mixins.

The following example will show you how to read power consumption data from a MSS310 plug, which implements both the meross_iot.controller.mixins.electricity.ElectricityMixin and the meross_iot.controller.mixins.consumption.ConsumptionXMixin.

Reading power consumption
 1import asyncio
 2import os
 3
 4from meross_iot.controller.mixins.electricity import ElectricityMixin
 5from meross_iot.http_api import MerossHttpClient
 6from meross_iot.manager import MerossManager
 7
 8EMAIL = os.environ.get('MEROSS_EMAIL') or "YOUR_MEROSS_CLOUD_EMAIL"
 9PASSWORD = os.environ.get('MEROSS_PASSWORD') or "YOUR_MEROSS_CLOUD_PASSWORD"
10
11
12async def main():
13    # Setup the HTTP client API from user-password
14    http_api_client = await MerossHttpClient.async_from_user_password(email=EMAIL, password=PASSWORD, api_base_url="https://iot.meross.com")
15
16    # Setup and start the device manager
17    manager = MerossManager(http_client=http_api_client)
18    await manager.async_init()
19
20    # Retrieve all the devices that implement the electricity mixin
21    await manager.async_device_discovery()
22    devs = manager.find_devices(device_class=ElectricityMixin)
23
24    if len(devs) < 1:
25        print("No electricity-capable device found...")
26    else:
27        dev = devs[0]
28
29        # Update device status: this is needed only the very first time we play with this device (or if the
30        #  connection goes down)
31        await dev.async_update()
32
33        # Read the electricity power/voltage/current
34        instant_consumption = await dev.async_get_instant_metrics()
35        print(f"Current consumption data: {instant_consumption}")
36
37    # Close the manager and logout from http_api
38    manager.close()
39    await http_api_client.async_logout()
40
41if __name__ == '__main__':
42    if os.name == 'nt':
43        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
44    loop = asyncio.get_event_loop()
45    loop.run_until_complete(main())
46    loop.stop()

In this case, the core of the script is the method async_get_instant_metrics() which reads the current electricity data from the device. More details on the electricity mixin are available here

For reading data from the MS100 temperature and humidity sensor, you can rely on the following snippet.

Reading from sensor
 1import asyncio
 2import os
 3
 4from meross_iot.http_api import MerossHttpClient
 5from meross_iot.manager import MerossManager
 6
 7EMAIL = os.environ.get('MEROSS_EMAIL') or "YOUR_MEROSS_CLOUD_EMAIL"
 8PASSWORD = os.environ.get('MEROSS_PASSWORD') or "YOUR_MEROSS_CLOUD_PASSWORD"
 9
10
11async def main():
12    # Setup the HTTP client API from user-password
13    http_api_client = await MerossHttpClient.async_from_user_password(email=EMAIL, password=PASSWORD, api_base_url="https://iot.meross.com")
14
15    # Setup and start the device manager
16    manager = MerossManager(http_client=http_api_client)
17    await manager.async_init()
18
19    # Retrieve all the MS100 devices that are registered on this account
20    await manager.async_device_discovery()
21    sensors = manager.find_devices(device_type="ms100")
22
23    if len(sensors) < 1:
24        print("No MS100 plugs found...")
25    else:
26        dev = sensors[0]
27
28        # Manually force and update to retrieve the latest temperature sensed from
29        # the device. This ensures we get the most recent data and not a cached value
30        await dev.async_update()
31
32        # Access read cached data
33        temp = dev.last_sampled_temperature
34        humid = dev.last_sampled_humidity
35        time = dev.last_sampled_time
36
37        print(f"Current sampled data on {time.isoformat()}; Temperature={temp}°C, Humidity={humid}%")
38    # Close the manager and logout from http_api
39    manager.close()
40    await http_api_client.async_logout()
41
42if __name__ == '__main__':
43    if os.name == 'nt':
44        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
45    loop = asyncio.get_event_loop()
46    loop.run_until_complete(main())
47    loop.stop()

More details on the specific methods offered by the Ms100 sensor device are documented within the Ms100Sensor class.

Controlling Thermostat

The Meross thermostat valve is operated via meross_iot.controller.subdevice.Mts100v3Valve class.

Operating the smart valve
 1import asyncio
 2import os
 3from random import randint
 4
 5from meross_iot.http_api import MerossHttpClient
 6from meross_iot.manager import MerossManager
 7
 8EMAIL = os.environ.get('MEROSS_EMAIL') or "YOUR_MEROSS_CLOUD_EMAIL"
 9PASSWORD = os.environ.get('MEROSS_PASSWORD') or "YOUR_MEROSS_CLOUD_PASSWORD"
10
11
12async def main():
13    # Setup the HTTP client API from user-password
14    http_api_client = await MerossHttpClient.async_from_user_password(email=EMAIL, password=PASSWORD, api_base_url="https://iot.meross.com")
15
16    # Setup and start the device manager
17    manager = MerossManager(http_client=http_api_client)
18    await manager.async_init()
19
20    # Retrieve all the mts100v3 devices that are registered on this account
21    await manager.async_device_discovery()
22    sensors = manager.find_devices(device_type="mts100v3")
23
24    if len(sensors) < 1:
25        print("No mts100v3 plugs found...")
26    else:
27        dev = sensors[0]
28
29        # Manually force and update to retrieve the latest temperature sensed from
30        # the device (this ensures we get the most recent value rather than a cached one)
31        await dev.async_update()
32
33        # Access read cached data
34        on_off = dev.is_on()
35
36        # Turn on the device if it's not on
37        if not on_off:
38            print(f"Device {dev.name} is off, turning it on...")
39            await dev.async_turn_on()
40
41        temp = await dev.async_get_temperature()
42        print(f"Current ambient temperature = {temp} °C, "
43              f"Target Temperature = {dev.target_temperature}, "
44              f"mode = {dev.mode},"
45              f"heating = {dev.is_heating}")
46
47        # Randomly choose a temperature between min and max
48        new_temp = randint(dev.min_supported_temperature, dev.max_supported_temperature)
49        print(f"Setting target temperature to {new_temp}")
50        await dev.async_set_target_temperature(new_temp)
51
52    # Close the manager and logout from http_api
53    manager.close()
54    await http_api_client.async_logout()
55
56if __name__ == '__main__':
57    if os.name == 'nt':
58        asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
59    loop = asyncio.get_event_loop()
60    loop.run_until_complete(main())
61    loop.stop()
62

For more information about all the properties and methods exposed by the valve class, have a look at Valve reference