Skip to content

Commit

Permalink
- Using the latest API Endpoints from Meross, version 0.4.6.0
Browse files Browse the repository at this point in the history
- Fix logging errors
- Fix deprecated constants usage
  • Loading branch information
albertogeniola committed Jan 27, 2024
1 parent 050fa3b commit 4e37c03
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 63 deletions.
22 changes: 18 additions & 4 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,40 @@
"version": "0.2.0",
"configurations": [
{
"name": "RPI - DEBUG HA",
"name": "RPI - (MEROSSIOT_BETA) DEBUG HA",
"type": "python",
"request": "attach",
"port": 6789,
"host": "192.168.1.22",
"host": "192.168.41.10",
"justMyCode": false,
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "/usr/src/homeassistant"
},
{
"localRoot": "Z:/custom_components/meross_cloud/config_flow.py",
"remoteRoot": "/config/custom_components/meross_cloud/config_flow.py"
"localRoot": "Z:/custom_components/meross_cloud/",
"remoteRoot": "/config/custom_components/meross_cloud/"
}
//{
// "localRoot": "c:\\Users\\Alberto Geniola\\source\\repos\\meross-homeassistant\\custom_components\\meross_cloud",
// "remoteRoot": "/config/custom_components/meross_cloud"
//}
]
},
{
"name": "RPI - (MEROSSIOT_HACS) DEBUG HA",
"type": "python",
"request": "attach",
"port": 6789,
"host": "192.168.41.10",
"justMyCode": false,
"pathMappings": [
{
"localRoot": "c:\\Users\\Alberto Geniola\\source\\repos\\meross-homeassistant\\custom_components\\meross_cloud",
"remoteRoot": "/config/custom_components/meross_cloud"
}
]
}
]
}
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

<!--next-version-placeholder-->

# 1.2.11 (2024-01-27)
- Using the latest API Endpoints from Meross, version 0.4.6.0
- Fix logging errors
- Fix deprecated constants usage

# 1.2.10 (2023-10-15)
- Using the latest API Endpoints from Meross
- Supporting energy sensor for plugs (#460, thanks to @benoitm974)
Expand Down
4 changes: 2 additions & 2 deletions custom_components/meross_cloud/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ async def async_setup_entry(hass: HomeAssistantType, config_entry: ConfigEntry):
_LOGGER.info("Loaded %s: %s", CONF_HTTP_ENDPOINT, http_api_endpoint)

email = config_entry.data.get(CONF_USERNAME)
_LOGGER.info("Loaded %s: %s", CONF_USERNAME, http_api_endpoint)
_LOGGER.info("Loaded %s: %s", CONF_USERNAME, email)

password = config_entry.data.get(CONF_PASSWORD)
_LOGGER.info("Loaded %s: %s", CONF_PASSWORD, "******")
Expand All @@ -404,7 +404,7 @@ async def async_setup_entry(hass: HomeAssistantType, config_entry: ConfigEntry):
_LOGGER.warning("Skip MQTT cert validation option set to: %s", mqtt_skip_cert_validation)

mqtt_override_address = config_entry.data.get(CONF_OVERRIDE_MQTT_ENDPOINT)
_LOGGER.info("Override MQTT address set to: %s", "no" if mqtt_override_address else "yes -> %s" % mqtt_override_address)
_LOGGER.info("Override MQTT address set to: %s", "no" if mqtt_override_address is None else "yes -> %s" % mqtt_override_address)

# Make sure we have all the needed requirements
if http_api_endpoint is None or HTTP_API_RE.fullmatch(http_api_endpoint) is None:
Expand Down
47 changes: 22 additions & 25 deletions custom_components/meross_cloud/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,9 @@
from meross_iot.model.http.device import HttpDeviceInfo

# Conditional import for switch device
from homeassistant.const import UnitOfTemperature
from homeassistant.components.climate import ClimateEntity
from homeassistant.components.climate import SUPPORT_TARGET_TEMPERATURE, SUPPORT_PRESET_MODE, HVAC_MODE_OFF, \
HVAC_MODE_HEAT
from homeassistant.components.climate.const import HVAC_MODE_AUTO, HVAC_MODE_COOL, CURRENT_HVAC_IDLE, CURRENT_HVAC_HEAT, \
CURRENT_HVAC_OFF, CURRENT_HVAC_COOL, ClimateEntityFeature, HVACMode, HVACAction
from homeassistant.const import TEMP_CELSIUS
from homeassistant.components.climate import ClimateEntityFeature, HVACMode, HVACAction
from homeassistant.helpers.typing import HomeAssistantType
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from . import MerossDevice
Expand All @@ -39,21 +36,21 @@ def __init__(self,

# For now, we assume that every Meross Thermostat supports the following modes.
# This might be improved in the future by looking at the device abilities via get_abilities()
self._flags = SUPPORT_TARGET_TEMPERATURE | SUPPORT_PRESET_MODE
self._flags = ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.PRESET_MODE

async def async_set_hvac_mode(self, hvac_mode: str) -> None:
# Turn on the device if not already on
if hvac_mode == HVAC_MODE_OFF:
if hvac_mode == HVACMode.OFF:
await self._device.async_turn_off()
return
elif not self._device.is_on():
await self._device.async_turn_on()

if hvac_mode == HVAC_MODE_HEAT:
if hvac_mode == HVACMode.HEAT:
await self._device.async_set_mode(ThermostatV3Mode.HEAT)
elif hvac_mode == HVAC_MODE_AUTO:
elif hvac_mode == HVACMode.AUTO:
await self._device.async_set_mode(ThermostatV3Mode.AUTO)
elif hvac_mode == HVAC_MODE_COOL:
elif hvac_mode == HVACMode.COOL:
await self._device.async_set_mode(ThermostatV3Mode.COOL)
else:
_LOGGER.warning(f"Unsupported mode for this device ({self.name}): {hvac_mode}")
Expand All @@ -67,7 +64,7 @@ async def async_set_temperature(self, **kwargs):

@property
def temperature_unit(self) -> str:
return TEMP_CELSIUS
return UnitOfTemperature.CELSIUS

@property
def current_temperature(self) -> Optional[float]:
Expand All @@ -92,37 +89,37 @@ def min_temp(self) -> Optional[float]:
@property
def hvac_mode(self) -> str:
if not self._device.is_on():
return HVAC_MODE_OFF
return HVACMode.OFF
elif self._device.mode == ThermostatV3Mode.AUTO:
return HVAC_MODE_AUTO
return HVACMode.AUTO
elif self._device.mode == ThermostatV3Mode.HEAT:
return HVAC_MODE_HEAT
return HVACMode.HEAT
elif self._device.mode == ThermostatV3Mode.COOL:
return HVAC_MODE_COOL
return HVACMode.COOL
elif self._device.mode == ThermostatV3Mode.ECONOMY:
return HVAC_MODE_AUTO
return HVACMode.AUTO
elif self._device.mode == ThermostatV3Mode.CUSTOM:
if self._device.last_sampled_temperature < self._device.target_temperature:
return HVAC_MODE_HEAT
return HVACMode.HEAT
else:
return HVAC_MODE_COOL
return HVACMode.COOL
else:
raise ValueError("Unsupported thermostat mode reported.")

@property
def hvac_action(self) -> Optional[str]:
if not self._device.is_on():
return CURRENT_HVAC_OFF
return HVACAction.OFF
elif self._device.is_heating:
return CURRENT_HVAC_HEAT
elif self._device.mode == HVAC_MODE_COOL:
return CURRENT_HVAC_COOL
return HVACAction.HEATING
elif self._device.mode == HVACAction.COOLING:
return HVACAction.COOLING
else:
return CURRENT_HVAC_IDLE
return HVACAction.IDLE

@property
def hvac_modes(self) -> List[str]:
return [HVAC_MODE_OFF, HVAC_MODE_AUTO, HVAC_MODE_HEAT, HVAC_MODE_COOL]
return [HVACMode.OFF, HVACMode.AUTO, HVACMode.HEAT, HVACMode.COOL]

@property
def preset_mode(self) -> Optional[str]:
Expand Down Expand Up @@ -185,7 +182,7 @@ async def async_set_temperature(self, **kwargs):
@property
def temperature_unit(self) -> str:
# TODO: Check if there is a way for retrieving the Merasurement Unit from the library
return TEMP_CELSIUS
return UnitOfTemperature.CELSIUS

@property
def current_temperature(self) -> Optional[float]:
Expand Down
11 changes: 5 additions & 6 deletions custom_components/meross_cloud/cover.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
from meross_iot.model.http.device import HttpDeviceInfo

# Conditional Light import with backwards compatibility
from homeassistant.components.cover import CoverEntity, SUPPORT_STOP
from homeassistant.components.cover import DEVICE_CLASS_GARAGE, DEVICE_CLASS_SHUTTER, SUPPORT_OPEN, SUPPORT_CLOSE
from homeassistant.components.cover import CoverEntity, CoverEntityFeature, CoverDeviceClass
from homeassistant.helpers.typing import HomeAssistantType
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from . import MerossDevice
Expand Down Expand Up @@ -56,12 +55,12 @@ def close_cover(self, **kwargs: Any) -> None:
@property
def device_class(self):
"""Return the class of this device, from component DEVICE_CLASSES."""
return DEVICE_CLASS_GARAGE
return CoverDeviceClass.GARAGE

@property
def supported_features(self):
"""Flag supported features."""
return SUPPORT_OPEN | SUPPORT_CLOSE
return CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE

@property
def is_closed(self):
Expand Down Expand Up @@ -122,14 +121,14 @@ def stop_cover(self, **kwargs) -> None:
@property
def device_class(self):
"""Return the class of this device, from component DEVICE_CLASSES."""
return DEVICE_CLASS_SHUTTER
return CoverDeviceClass.SHUTTER

@property
def supported_features(self):
"""Flag supported features."""
# So far, the Roller Shutter RST100 supports position, but it looks like it is fake and not reliable.
# So we don't support that on HA neither.
return SUPPORT_OPEN | SUPPORT_CLOSE | SUPPORT_STOP
return CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE | CoverEntityFeature.STOP

@property
def is_closed(self):
Expand Down
4 changes: 2 additions & 2 deletions custom_components/meross_cloud/fan.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from meross_iot.model.enums import SprayMode
from meross_iot.model.http.device import HttpDeviceInfo

from homeassistant.components.fan import FanEntity, SUPPORT_PRESET_MODE
from homeassistant.components.fan import FanEntity, FanEntityFeature
from homeassistant.helpers.typing import HomeAssistantType
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from . import MerossDevice
Expand Down Expand Up @@ -70,7 +70,7 @@ def turn_off(self, **kwargs: Any) -> None:

@property
def supported_features(self) -> int:
return SUPPORT_PRESET_MODE
return FanEntityFeature.PRESET_MODE

@property
def is_on(self) -> Optional[bool]:
Expand Down
4 changes: 2 additions & 2 deletions custom_components/meross_cloud/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
"issue_tracker": "https://github.com/albertogeniola/meross-homeassistant",
"dependencies": ["persistent_notification"],
"codeowners": ["@albertogeniola"],
"requirements": ["meross_iot==0.4.6.0rc2"],
"requirements": ["meross_iot==0.4.6.0"],
"config_flow": true,
"quality_scale": "platinum",
"iot_class": "cloud_push",
"version": "1.2.10"
"version": "1.2.11"
}
41 changes: 19 additions & 22 deletions custom_components/meross_cloud/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,8 @@
from meross_iot.model.exception import CommandTimeoutError
from meross_iot.model.http.device import HttpDeviceInfo

from homeassistant.components.sensor import STATE_CLASS_MEASUREMENT, STATE_CLASS_TOTAL_INCREASING
from homeassistant.components.sensor import SensorEntity
from homeassistant.const import DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS, DEVICE_CLASS_HUMIDITY, \
DEVICE_CLASS_POWER, POWER_WATT, DEVICE_CLASS_CURRENT, DEVICE_CLASS_VOLTAGE, DEVICE_CLASS_ENERGY
from homeassistant.const import PERCENTAGE
from homeassistant.components.sensor import SensorStateClass, SensorEntity, SensorDeviceClass
from homeassistant.const import PERCENTAGE, UnitOfTemperature, UnitOfPower
from homeassistant.helpers.typing import StateType, HomeAssistantType
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from . import MerossDevice
Expand Down Expand Up @@ -67,10 +64,10 @@ class Ms100TemperatureSensorWrapper(GenericSensorWrapper):
def __init__(self, device: Ms100Sensor, device_list_coordinator: DataUpdateCoordinator[Dict[str, HttpDeviceInfo]],
channel: int = 0):
super().__init__(
sensor_class=DEVICE_CLASS_TEMPERATURE,
measurement_unit=TEMP_CELSIUS,
sensor_class=SensorDeviceClass.TEMPERATURE,
measurement_unit=UnitOfTemperature.CELSIUS,
device_method_or_property='last_sampled_temperature',
state_class=STATE_CLASS_MEASUREMENT,
state_class=SensorStateClass.MEASUREMENT,
device=device,
device_list_coordinator=device_list_coordinator,
channel=channel)
Expand All @@ -79,10 +76,10 @@ def __init__(self, device: Ms100Sensor, device_list_coordinator: DataUpdateCoord
class Ms100HumiditySensorWrapper(GenericSensorWrapper):
def __init__(self, device: Ms100Sensor, device_list_coordinator: DataUpdateCoordinator[Dict[str, HttpDeviceInfo]],
channel: int = 0):
super().__init__(sensor_class=DEVICE_CLASS_HUMIDITY,
super().__init__(sensor_class=SensorDeviceClass.HUMIDITY,
measurement_unit=PERCENTAGE,
device_method_or_property='last_sampled_humidity',
state_class=STATE_CLASS_MEASUREMENT,
state_class=SensorStateClass.MEASUREMENT,
device=device,
device_list_coordinator=device_list_coordinator,
channel=channel)
Expand All @@ -93,10 +90,10 @@ class Mts100TemperatureSensorWrapper(GenericSensorWrapper):

def __init__(self, device: Mts100v3Valve,
device_list_coordinator: DataUpdateCoordinator[Dict[str, HttpDeviceInfo]]):
super().__init__(sensor_class=DEVICE_CLASS_TEMPERATURE,
measurement_unit=TEMP_CELSIUS,
super().__init__(sensor_class=SensorDeviceClass.TEMPERATURE,
measurement_unit=UnitOfTemperature.CELSIUS,
device_method_or_property='last_sampled_temperature',
state_class=STATE_CLASS_MEASUREMENT,
state_class=SensorStateClass.MEASUREMENT,
device_list_coordinator=device_list_coordinator,
device=device)

Expand Down Expand Up @@ -126,10 +123,10 @@ class PowerSensorWrapper(GenericSensorWrapper):

def __init__(self, device: ElectricitySensorDevice,
device_list_coordinator: DataUpdateCoordinator[Dict[str, HttpDeviceInfo]], channel: int = 0):
super().__init__(sensor_class=DEVICE_CLASS_POWER,
measurement_unit=POWER_WATT,
super().__init__(sensor_class=SensorDeviceClass.POWER,
measurement_unit=UnitOfPower.WATT,
device_method_or_property='get_last_sample',
state_class=STATE_CLASS_MEASUREMENT,
state_class=SensorStateClass.MEASUREMENT,
device=device,
device_list_coordinator=device_list_coordinator,
channel=channel)
Expand Down Expand Up @@ -169,10 +166,10 @@ class CurrentSensorWrapper(GenericSensorWrapper):

def __init__(self, device: ElectricitySensorDevice,
device_list_coordinator: DataUpdateCoordinator[Dict[str, HttpDeviceInfo]], channel: int = 0):
super().__init__(sensor_class=DEVICE_CLASS_CURRENT,
super().__init__(sensor_class=SensorDeviceClass.CURRENT,
measurement_unit="A",
device_method_or_property='get_last_sample',
state_class=STATE_CLASS_MEASUREMENT,
state_class=SensorStateClass.MEASUREMENT,
device=device,
device_list_coordinator=device_list_coordinator,
channel=channel)
Expand Down Expand Up @@ -213,10 +210,10 @@ class VoltageSensorWrapper(GenericSensorWrapper):

def __init__(self, device: ElectricitySensorDevice,
device_list_coordinator: DataUpdateCoordinator[Dict[str, HttpDeviceInfo]], channel: int = 0):
super().__init__(sensor_class=DEVICE_CLASS_VOLTAGE,
super().__init__(sensor_class=SensorDeviceClass.VOLTAGE,
measurement_unit="V",
device_method_or_property='get_last_sample',
state_class=STATE_CLASS_MEASUREMENT,
state_class=SensorStateClass.MEASUREMENT,
device=device,
device_list_coordinator=device_list_coordinator,
channel=channel)
Expand Down Expand Up @@ -256,10 +253,10 @@ class EnergySensorWrapper(GenericSensorWrapper):

def __init__(self, device: EnergySensorDevice,
device_list_coordinator: DataUpdateCoordinator[Dict[str, HttpDeviceInfo]], channel: int = 0):
super().__init__(sensor_class=DEVICE_CLASS_ENERGY,
super().__init__(sensor_class=SensorDeviceClass.ENERGY,
measurement_unit="kWh",
device_method_or_property='async_get_daily_power_consumption',
state_class=STATE_CLASS_TOTAL_INCREASING,
state_class=SensorStateClass.TOTAL_INCREASING,
device=device,
device_list_coordinator=device_list_coordinator,
channel=channel)
Expand Down

0 comments on commit 4e37c03

Please sign in to comment.