Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to read temperatures from mts200b? #267

Closed
Topsham opened this issue Dec 13, 2022 · 10 comments
Closed

How to read temperatures from mts200b? #267

Topsham opened this issue Dec 13, 2022 · 10 comments
Labels
no-stale question Further information is requested waiting validation Waiting for user's validation/approval/test

Comments

@Topsham
Copy link

Topsham commented Dec 13, 2022

Thanks for all the great work Albert. I am very new to Python but I have successfully used your code to connect to my mts100v3 valves to read the actual and set temperatures to display on a tkinter house plan and I was hoping to get the same info in a similar way from some mts200b wall stats I also have. But when applying the same
temp = await dev.async_get_temperature()
to a mts200b I get

'mts200b:7.0.0:7.6.3' object has no attribute 'async_get_temperature'

I only want to read the actual and set temps from the mts200b and not control them in any way. Is there a similar command to do this do you know?

Many thanks

@albertogeniola
Copy link
Owner

albertogeniola commented Dec 13, 2022

Hi!

The MTS200 Thermostat should implement the Thermostat Mixin, which implements the following signature.

    def current_temperature_celsius(self-> Optional[float]:

You should be able to get the currently sampled temperature with the following method:

# dev = ...
temp = dev.current_temperature_celsius()

I am not sure about the MTS200b version, but there are good chance it works as well.
Give it a try and let me know if that works as intended.

@albertogeniola albertogeniola added question Further information is requested waiting validation Waiting for user's validation/approval/test labels Dec 13, 2022
@Topsham
Copy link
Author

Topsham commented Dec 14, 2022

Alberto

I am still getting
AttributeError: 'mts200b:7.0.0:7.6.3' object has no attribute 'current_temperature_celsius'

However I am maybe missing something else given I am a bit of a newbie? Below is my full code (with mysql db updating removed). It prints the results for the mts100v3 perfectly well but then gives above error when it gets to the mts200b.

-- coding: utf-8 --

#!/usr/bin/python3

import asyncio
from time import sleep

from meross_iot.http_api import MerossHttpClient
from meross_iot.manager import MerossManager
import mariadb as mdb

Parameters

EMAIL = "***" # Meross account log in
PASSWORD = "
"

async def main():
http_api_client = await MerossHttpClient.async_from_user_password(email=EMAIL, password=PASSWORD)
manager = MerossManager(http_client=http_api_client)
await manager.async_init()

Discover devices.

await manager.async_device_discovery()
meross_devices = manager.find_devices()

# Print them
print("I've found the following devices:")
for dev in meross_devices:
    print(f"- {dev.name} ({dev.type}): {dev.online_status}")
    if dev.type == 'mts100v3':
        await dev.async_update()
        temp = await dev.async_get_temperature()
        print(f"Current ambient temperature = {temp} °C, "
              f"Target Temperature = {dev.target_temperature}, "
              f"mode = {dev.mode},"
              f"heating = {dev.is_heating}")



    if dev.type == 'mts200b':
        await dev.async_update()
        temp = await dev.async_get_current_temperature_celsius()
        print(f"Current ambient temperature = {temp} °C, "
              f"Target Temperature = {dev.target_temperature}, "
              f"mode = {dev.mode},"
              f"heating = {dev.is_heating}")


manager.close()
await http_api_client.async_logout()

if name == 'main':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()

@Topsham
Copy link
Author

Topsham commented Dec 18, 2022

Hi again Alberto
Firstly my apologies for the previous poor code formatting (I am new to Github). I have now used your example.py to try and get the current temperature from my mts200b stats but I get:

Traceback (most recent call last):
  File "/home/pi/myexample.py", line 43, in <module>
    loop.run_until_complete(main())
  File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
    return future.result()
  File "/home/pi/myexample.py", line 32, in main
    temp = dev.current_temperature_celsius()
AttributeError: 'mts200b:7.0.0:7.6.3' object has no attribute 'current_temperature_celsius'

Could it be that the mts200b is different from the mts200 and if so would it help if I sent you some sniffing data?

Thanks

# -*- coding: utf-8 -*-
#!/usr/bin/python3
# myexample.py

import asyncio
from time import sleep

from meross_iot.http_api import MerossHttpClient
from meross_iot.manager import MerossManager
import mariadb as mdb

EMAIL = "**********"
PASSWORD = "*********"

async def main():
    http_api_client = await MerossHttpClient.async_from_user_password(email=EMAIL, password=PASSWORD)
    manager = MerossManager(http_client=http_api_client)
    await manager.async_init()

    # Retrieve all the Mts200b devices that are registered on this account
    await manager.async_device_discovery()
    sensors = manager.find_devices(device_type="mts200b")

    if len(sensors) < 1:
        print("No mts200b found...")
    else:
        dev = sensors[0]

        await dev.async_update()

        # Access read cached data
        temp = dev.current_temperature_celsius()
        print(temp)

    manager.close()
    await http_api_client.async_logout()



if __name__ == '__main__':

    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()

@albertogeniola
Copy link
Owner

Hi,
that might be possibile.
Can you inspect the _abilities attribute of the dev variable? Something like this should work:

# ... omissis
dev = sensors[0]
print(dev._abilities) # This will print the device abilities
print(dir(dev)) # This will print the device available methods/attributes
print(dev) # This will print some more info about the instance itself

Would you mind attaching that output?

@albertogeniola albertogeniola added no-stale and removed waiting validation Waiting for user's validation/approval/test labels Dec 29, 2022
@Topsham
Copy link
Author

Topsham commented Dec 29, 2022

Hi Alberto - below is the output that produces. At present I am only interested in getting the current and set temperatures but being able to adjust the set temperature (not the schedule) would be a bonus!

------- Manager Discovery ended -------

{'Appliance.Config.Key': {}, 'Appliance.Config.WifiList': {}, 'Appliance.Config.Wifi': {}, 'Appliance.Config.WifiX': {}, 'Appliance.Config.Trace': {}, 'Appliance.Config.Info': {}, 'Appliance.System.All': {}, 'Appliance.System.Hardware': {}, 'Appliance.System.Firmware': {}, 'Appliance.System.Debug': {}, 'Appliance.System.Online': {}, 'Appliance.System.Time': {}, 'Appliance.System.Clock': {}, 'Appliance.System.Ability': {}, 'Appliance.System.Runtime': {}, 'Appliance.System.Report': {}, 'Appliance.System.Position': {}, 'Appliance.Mcu.Firmware': {}, 'Appliance.Control.Multiple': {'maxCmdNum': 5}, 'Appliance.Control.Bind': {}, 'Appliance.Control.Unbind': {}, 'Appliance.Control.Upgrade': {}, 'Appliance.Control.PhysicalLock': {}, 'Appliance.Control.Thermostat.HoldAction': {}, 'Appliance.Control.Thermostat.Mode': {}, 'Appliance.Control.Thermostat.Calibration': {}, 'Appliance.Control.Thermostat.DeadZone': {}, 'Appliance.Control.Thermostat.Frost': {}, 'Appliance.Control.Thermostat.Overheat': {}, 'Appliance.Control.Thermostat.WindowOpened': {}, 'Appliance.Control.Thermostat.Schedule': {}, 'Appliance.Control.Screen.Brightness': {}, 'Appliance.Control.Thermostat.Sensor': {}, 'Appliance.Digest.TriggerX': {}, 'Appliance.Digest.TimerX': {}}

['annotations', 'class', 'delattr', 'dict', 'dir', 'doc', 'eq', 'format', 'ge', 'getattribute', 'gt', 'hash', 'init', 'init_subclass', 'le', 'lt', 'module', 'ne', 'new', 'reduce', 'reduce_ex', 'repr', 'setattr', 'sizeof', 'str', 'subclasshook', 'weakref', '_abilities', '_abilities_spec', '_align_temp', '_channels', '_execute_command', '_fire_push_notification_event', '_fwversion', '_hwversion', '_inner_ip', '_last_full_update_ts', '_manager', '_mqtt_host', '_mqtt_port', '_name', '_online', '_parse_channels', '_push_coros', '_thermostat_state_by_channel', '_timeout', '_type', '_update_mode', '_uuid', 'abilities', 'async_handle_push_notification', 'async_handle_update', 'async_set_thermostat_config', 'async_update', 'channels', 'check_full_update_done', 'default_command_timeout', 'dismiss', 'firmware_version', 'get_thermostat_state', 'hardware_version', 'internal_id', 'lan_ip', 'last_full_update_timestamp', 'lookup_channel', 'mqtt_host', 'mqtt_port', 'name', 'online_status', 'register_push_notification_handler_coroutine', 'type', 'unregister_push_notification_handler_coroutine', 'update_from_http_state', 'uuid']

Hall (mts200b, HW 7.0.0, FW 7.6.5, class: mts200b:7.0.0:7.6.5)
INFO:Manager stop requested.
INFO:Disconnection detected. Reason: 0
INFO:Logout succeeded.

@albertogeniola
Copy link
Owner

albertogeniola commented Dec 30, 2022

Ok, my bad.
You should already be able to retrieve the info you are looking for. Try the following:

# -*- coding: utf-8 -*-
#!/usr/bin/python3
# myexample.py

import asyncio
from time import sleep

from meross_iot.http_api import MerossHttpClient
from meross_iot.manager import MerossManager
import mariadb as mdb

EMAIL = "**********"
PASSWORD = "*********"

async def main():
    http_api_client = await MerossHttpClient.async_from_user_password(email=EMAIL, password=PASSWORD)
    manager = MerossManager(http_client=http_api_client)
    await manager.async_init()

    # Retrieve all the Mts200b devices that are registered on this account
    await manager.async_device_discovery()
    sensors = manager.find_devices(device_type="mts200b")

    if len(sensors) < 1:
        print("No mts200b found...")
    else:
        dev = sensors[0]

        await dev.async_update()

        # Access read cached data
        state = dev.get_thermostat_state()  # Added this line!
        temp = state.current_temperature_celsius
        print(temp)

    manager.close()
    await http_api_client.async_logout()



if __name__ == '__main__':

    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()

Note: the sampled temperature is "cached". If you want to access every time an updated value, be sure to invoke the await dev.async_update() method just before the invocation of get_thermostat_state() and its current_temperature_celsius property.

Let me know if that works!

@albertogeniola albertogeniola added the waiting validation Waiting for user's validation/approval/test label Dec 30, 2022
@Topsham
Copy link
Author

Topsham commented Dec 31, 2022

Hi Alberto
Yes that works and

target_temp = state.target_temperature_celsius

also works.

I have tried several variations to get if dev.is_heating but they do not work. It's not too important for me, but maybe you know it??
Grazie Mille

@Topsham
Copy link
Author

Topsham commented Jan 5, 2023

Hi Alberto
Was all working fine as above but did an update/upgrade today and am now getting the following error:

 await manager.async_device_discovery()
  File "/usr/local/lib/python3.9/dist-packages/meross_iot/manager.py", line 331, in async_device_discovery
    http_devices = await self._http_client.async_list_devices()
  File "/usr/local/lib/python3.9/dist-packages/meross_iot/http_api.py", line 417, in async_list_devices
    return [HttpDeviceInfo.from_dict(x) for x in result]
  File "/usr/local/lib/python3.9/dist-packages/meross_iot/http_api.py", line 417, in <listcomp>
    return [HttpDeviceInfo.from_dict(x) for x in result]
  File "/usr/local/lib/python3.9/dist-packages/meross_iot/model/shared.py", line 27, in from_dict
    obj = cls(**new_dict)
TypeError: __init__() missing 1 required positional argument: 'skill_number'

@albertogeniola
Copy link
Owner

Hi,
That was not your fault but a change performed by Meross engineers on their side: that broke our library. See #274.

You just need to upgrade to the latest available version and that should be fine.

Let me know!

@Topsham
Copy link
Author

Topsham commented Dec 2, 2023

Hi Aberto

In order to flag if the MTS200b is heating I have so far just been comparing the current and target temperatures but this is of course not really accurate depending on the switching differential set for each stat. I have tried

 if dev.type == 'mts200b':


            await dev.async_update()
            state = (dev.get_thermostat_state())
            temp = state.current_temperature_celsius
            tar  = state.target_temperature_celsius
            heating = state.is_heating
            print (heating)
            print (temp)
            print (tar)

but I get "AttributeError: 'ThermostatState' object has no attribute 'is_heating'"

Do you happen to know the attribute name for this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-stale question Further information is requested waiting validation Waiting for user's validation/approval/test
Projects
None yet
Development

No branches or pull requests

2 participants