Skip to content

Commit

Permalink
Merge pull request #412 from krahabb/dev_5_0
Browse files Browse the repository at this point in the history
Release Moonlight.0.3
  • Loading branch information
krahabb authored Mar 18, 2024
2 parents 8a65f61 + c0fdefb commit 5c16dea
Show file tree
Hide file tree
Showing 14 changed files with 135 additions and 159 deletions.
1 change: 1 addition & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"python.analysis.autoSearchPaths": false,
"python.formatting.provider": "black",
"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
"python.experiments.optOutFrom": ["pythonTestAdapter"],
"editor.formatOnPaste": false,
"editor.formatOnSave": true,
"editor.formatOnType": true,
Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@
"tests"
],
"[python]": {
"editor.defaultFormatter": "ms-python.vscode-pylance"
"editor.defaultFormatter": "ms-python.black-formatter"
}
}
15 changes: 8 additions & 7 deletions custom_components/meross_lan/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,10 +338,6 @@ def get(hass: HomeAssistant) -> MerossApi:
Loggable.hass = hass

async def _async_unload_merossapi(_event) -> None:
for device in MerossApi.active_devices():
await device.async_shutdown()
for profile in MerossApi.active_profiles():
await profile.async_shutdown()
await api.async_terminate()
Loggable.api = None # type: ignore
Loggable.hass = None # type: ignore
Expand Down Expand Up @@ -446,10 +442,10 @@ async def _async_device_request(device: MerossDevice):
await MerossHttpClient(
host,
key or self.key,
async_get_clientsession(self.hass),
None,
self, # type: ignore (self almost duck-compatible with logging.Logger)
self.VERBOSE,
).async_request_message(request)
).async_request_raw(request.json())
or {}
)
except Exception as exception:
Expand Down Expand Up @@ -498,7 +494,12 @@ def attach_mqtt(self, device: MerossDevice):
async def async_terminate(self):
"""complete shutdown when HA exits. See self.async_shutdown for differences"""
self.hass.services.async_remove(mlc.DOMAIN, mlc.SERVICE_REQUEST)
for device in MerossApi.active_devices():
await device.async_shutdown()
for profile in MerossApi.active_profiles():
await profile.async_shutdown()
await super().async_shutdown()
await MerossHttpClient.async_shutdown_session()
self._mqtt_connection = None

def build_device(self, device_id: str, config_entry: ConfigEntry) -> MerossDevice:
Expand Down Expand Up @@ -648,7 +649,7 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry):
await api.entry_update_listener(hass, config_entry)
await api.async_setup_entry(hass, config_entry)
return True

case _:
raise ConfigEntryError(
f"Unknown configuration type (entry_id:{config_entry.entry_id} title:'{config_entry.title}')"
Expand Down
3 changes: 1 addition & 2 deletions custom_components/meross_lan/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
from homeassistant.const import CONF_ERROR
from homeassistant.data_entry_flow import FlowHandler, callback
from homeassistant.helpers import config_validation as cv, device_registry as dr
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.selector import selector
import voluptuous as vol

Expand Down Expand Up @@ -441,7 +440,7 @@ async def _async_http_discovery(
self._httpclient = _httpclient = MerossHttpClient(
host,
key,
async_get_clientsession(self.hass),
None,
api, # type: ignore (api almost duck-compatible with logging.Logger)
api.VERBOSE,
)
Expand Down
2 changes: 1 addition & 1 deletion custom_components/meross_lan/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@
"/appliance/+/publish"
],
"requirements": [],
"version": "5.0.2"
"version": "5.0.3"
}
75 changes: 33 additions & 42 deletions custom_components/meross_lan/meross_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@
import weakref
from zoneinfo import ZoneInfo

from aiohttp import ServerDisconnectedError
import aiohttp
from homeassistant.core import callback
from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.util import dt as dt_util
import voluptuous as vol

Expand Down Expand Up @@ -1039,7 +1038,7 @@ async def async_http_request_raw(
self.TRACE_TX,
)
try:
response = await http.async_request_message(request)
response = await http.async_request_raw(request.json())
self.device_response_size_min = max(
self.device_response_size_min, len(response.json())
)
Expand Down Expand Up @@ -1104,13 +1103,13 @@ async def async_http_request_raw(
ProtocolSensor.ATTR_HTTP
)
elif namespace is mc.NS_APPLIANCE_CONTROL_UNBIND:
if isinstance(exception, ServerDisconnectedError):
if isinstance(exception, aiohttp.ServerDisconnectedError):
# this is expected when issuing the UNBIND
# so this is an indication we're dead
self._set_offline()
return None
elif namespace is mc.NS_APPLIANCE_CONTROL_MULTIPLE:
if isinstance(exception, ServerDisconnectedError):
if isinstance(exception, aiohttp.ServerDisconnectedError):
# this happens (instead of JSONDecodeError)
# on my msl120. I guess the (older) fw behaves
# differently than those responding incomplete json.
Expand All @@ -1129,8 +1128,14 @@ async def async_http_request_raw(
)
return None

if isinstance(exception, asyncio.TimeoutError):
if isinstance(exception, asyncio.TimeoutError) or isinstance(
exception, aiohttp.ServerTimeoutError
):
return None

# for any other exception we could guess the device
# is stalling a bit so we just wait a bit before re-issuing
await asyncio.sleep(0.5)
else:
return None

Expand Down Expand Up @@ -1326,7 +1331,7 @@ async def _async_polling_callback(self, namespace: str):
self._timezone_next_check = (
epoch + PARAM_TIMEZONE_CHECK_NOTOK_PERIOD
)
if self.device_timedelta < PARAM_TIMESTAMP_TOLERANCE:
if abs(self.device_timedelta) < PARAM_TIMESTAMP_TOLERANCE:
with self.exception_warning("_check_device_timerules"):
if self._check_device_timerules():
# timezone trans not good..fix and check again soon
Expand Down Expand Up @@ -1356,7 +1361,9 @@ async def _async_polling_callback(self, namespace: str):
ns_all_response = await self.async_http_request(*ns_all)

if ns_all_response:
self.polling_strategies[mc.NS_APPLIANCE_SYSTEM_ALL].response_size = len(ns_all_response.json())
self.polling_strategies[
mc.NS_APPLIANCE_SYSTEM_ALL
].response_size = len(ns_all_response.json())
await self._async_request_updates(epoch, mc.NS_APPLIANCE_SYSTEM_ALL)
else:
if self._polling_delay < PARAM_HEARTBEAT_PERIOD:
Expand Down Expand Up @@ -1503,11 +1510,7 @@ def _check_protocol(self):
self.sensor_protocol.update_attr_inactive(ProtocolSensor.ATTR_HTTP)
else:
if host := self.host:
self._http = MerossHttpClient(
host,
self.key,
async_get_clientsession(self.hass),
)
self._http = MerossHttpClient(host, self.key)

if conf_protocol is CONF_PROTOCOL_AUTO:
# When using CONF_PROTOCOL_AUTO we try to use our 'preferred' (pref_protocol)
Expand Down Expand Up @@ -1570,21 +1573,19 @@ def _receive(self, epoch: float, message: MerossResponse):
# We ignore delays below PARAM_TIMESTAMP_TOLERANCE since
# we'll always be a bit late in processing
self.device_timestamp = header[mc.KEY_TIMESTAMP]
device_timedelta = epoch - self.device_timestamp
if abs(device_timedelta) > PARAM_TIMESTAMP_TOLERANCE:
if (
abs(self.device_timedelta - device_timedelta)
> PARAM_TIMESTAMP_TOLERANCE
):
# big step so we're not averaging
self.device_timedelta = device_timedelta
else: # average the sampled timedelta
self.device_timedelta = (
4 * self.device_timedelta + device_timedelta
) / 5
self._config_device_timestamp(epoch)
else:
self.device_timedelta = 0
self.device_timedelta = (
9 * self.device_timedelta + (epoch - self.device_timestamp)
) / 10
if abs(self.device_timedelta) > PARAM_TIMESTAMP_TOLERANCE:
if not self._config_device_timestamp(epoch):
if (epoch - self.device_timedelta_log_epoch) > 604800: # 1 week lockout
self.device_timedelta_log_epoch = epoch
self.log(
self.WARNING,
"Incorrect timestamp: %d seconds behind HA (%d on average)",
int(epoch - self.device_timestamp),
int(self.device_timedelta),
)

if self.isEnabledFor(self.DEBUG):
# it appears sometimes the devices
Expand Down Expand Up @@ -1746,11 +1747,7 @@ def _handle_Appliance_System_All(self, header: dict, payload: dict):
if _http := self._http:
_http.host = host
else:
self._http = MerossHttpClient(
host,
self.key,
async_get_clientsession(self.hass),
)
self._http = MerossHttpClient(host, self.key)

if self.conf_protocol is CONF_PROTOCOL_AUTO:
if self._mqtt_active:
Expand Down Expand Up @@ -1814,18 +1811,12 @@ def _config_device_timestamp(self, epoch):
# the procedure too often
self.mqtt_request(*request_push(mc.NS_APPLIANCE_SYSTEM_CLOCK))
self.device_timedelta_config_epoch = epoch
return
return True
if last_config_delay < 30:
# 30 sec 'deadzone' where we allow the timestamp
# transaction to complete (should really be like few seconds)
return
if (epoch - self.device_timedelta_log_epoch) > 604800: # 1 week lockout
self.device_timedelta_log_epoch = epoch
self.log(
self.WARNING,
"Incorrect timestamp: %d seconds behind HA",
int(self.device_timedelta),
)
return True
return False

def _check_device_timerules(self) -> bool:
"""
Expand Down
Loading

0 comments on commit 5c16dea

Please sign in to comment.