Skip to content

Commit

Permalink
Fix for the fix (#18)
Browse files Browse the repository at this point in the history
* add base api url support

* fix tests

* Lint format

* bump version

* Fixed selected option not being written to url variable

* Bump version

* Fixed URL format

* bump version

* reversed URL changes

* Update setup.py

---------

Co-authored-by: Luiz Bon <[email protected]>
  • Loading branch information
jeloneal and luizbon authored Jan 13, 2024
1 parent 7f0513a commit 48e405b
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.13.1
current_version = 0.13.3
commit = True
tag = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\.dev(?P<dev>.*))?
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

setuptools.setup(
name="OctoPrint-PSUControl-Meross",
version="0.13.1",
version="0.13.3",
description="Adds Meross Smart Plug support to OctoPrint-PSUControl",
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
Expand All @@ -25,6 +25,6 @@
entry_points={
"octoprint.plugin": ["psucontrol_meross = octoprint_psucontrol_meross"]
},
install_requires=["OctoPrint>=1.7.3", "meross-iot>=0.4.5.4"],
install_requires=["OctoPrint>=1.7.3", "meross-iot>=0.4.6.0"],
python_requires=">=3.7.3",
)
15 changes: 9 additions & 6 deletions src/octoprint_psucontrol_meross/meross_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ async def logout(self):
await self.api_client.async_logout()
self.api_client = None

async def login(self, user: str, password: str, raise_exc: bool):
async def login(self, api_base_url: str, user: str, password: str, raise_exc: bool):
expected_session_key = self._cache.get_session_name_key(user, password)
self._logger.debug(
f"login called with user {user!r} "
Expand All @@ -126,7 +126,7 @@ async def login(self, user: str, password: str, raise_exc: bool):
self._logger.info(f"Performing full auth login for the user {user!r}.")
try:
self.api_client = await MerossHttpClient.async_from_user_password(
email=user, password=password
api_base_url=api_base_url, email=user, password=password
)
except ANY_MEROSS_IOT_EXC:
self._logger.exception("Error when trying to log in.")
Expand Down Expand Up @@ -236,7 +236,7 @@ async def get_device_handles(self, dev_ids: Sequence[str]):
]
)
out = []
for (device_hanle, (dev_uuid, dev_channel)) in zip(devices, uuid_channel_pairs):
for device_hanle, (dev_uuid, dev_channel) in zip(devices, uuid_channel_pairs):
if not device_hanle:
self._logger.error(f"Device {dev_uuid!r} not found.")
continue
Expand All @@ -247,7 +247,7 @@ async def set_devices_states(self, dev_ids: Sequence[str], state: bool):
assert self.is_authenticated, "Must be authenticated"
dev_handles = await self.get_device_handles(dev_ids)
futures = []
for (device, channel) in dev_handles:
for device, channel in dev_handles:
if state:
the_future = device.async_turn_on(channel=channel)
else:
Expand Down Expand Up @@ -288,7 +288,9 @@ def __init__(self, cache_file: Path, logger):
cache_file=cache_file, logger=self._logger.getChild("async_client")
)

def login(self, user: str, password: str, raise_exc: bool = False) -> Future:
def login(
self, api_base_url: str, user: str, password: str, raise_exc: bool = False
) -> Future:
"""Login to the meross cloud.
Returns `None` in async mode, or True/False (success state) in sync mode.
Expand All @@ -297,7 +299,8 @@ def login(self, user: str, password: str, raise_exc: bool = False) -> Future:
self._logger.info("No user/password configured, skipping login")
return False
return asyncio.run_coroutine_threadsafe(
self._async_client.login(user, password, raise_exc), self.worker.loop
self._async_client.login(api_base_url, user, password, raise_exc),
self.worker.loop,
)

def list_devices(self):
Expand Down
44 changes: 34 additions & 10 deletions src/octoprint_psucontrol_meross/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,29 @@ def on_settings_initialized(self):
self._logger.info(f"{self.__class__.__name__} loaded.")
self._ensure_meross_login()

def _ensure_meross_login(self, user=None, password=None, raise_exc=False):
def _ensure_meross_login(
self, api_base_url=None, user=None, password=None, raise_exc=False
):
"""Ensures that we are logged in as user/pass
(either provided or values from the settings).
"""
if (not user) and (not password):
if not api_base_url:
api_base_url = self._settings.get(["api_base_url"])
if not user:
user = self._settings.get(["user_email"])
if not password:
password = self._settings.get(["user_password"])
return self.meross.login(user, password, raise_exc=raise_exc)
return self.meross.login(api_base_url, user, password, raise_exc=raise_exc)

def get_settings_defaults(self):
return {
"api_urls": [
{"name": "Asia-Pacific", "url": "iotx-ap.meross.com"},
{"name": "Europe", "url": "iotx-eu.meross.com"},
{"name": "US", "url": "iotx-us.meross.com"},
],
"api_base_url": "iotx-eu.meross.com",
"user_email": "",
"user_password": "",
"target_device_ids": [],
Expand All @@ -45,6 +56,9 @@ def get_settings_defaults(self):
def get_settings_restricted_paths(self):
return {
"admin": [
[
"api_base_url",
],
[
"user_email",
],
Expand All @@ -66,7 +80,7 @@ def on_settings_save(self, data):
return super().on_settings_save(data)

def on_settings_migrate(self, target, current):
for (migrate_from, migrate_to) in zip(
for migrate_from, migrate_to in zip(
range(current, target), range(current + 1, target + 1)
):
if (migrate_from, migrate_to) == (1, 2):
Expand Down Expand Up @@ -121,18 +135,25 @@ def get_assets(self):

def get_api_commands(self):
return {
"try_login": ("user_email", "user_password"),
"list_devices": ("user_email", "user_password"),
"toggle_devices": ("user_email", "user_password", "dev_ids"),
"try_login": ("api_base_url", "user_email", "user_password"),
"list_devices": ("api_base_url", "user_email", "user_password"),
"toggle_devices": (
"api_base_url",
"user_email",
"user_password",
"dev_ids",
),
}

def on_api_command(self, event, payload):
self._logger.debug(f"ON_EVENT {event!r}")
if event == "try_login":

try:
success = self._ensure_meross_login(
payload["user_email"], payload["user_password"], raise_exc=True
payload["api_base_url"],
payload["user_email"],
payload["user_password"],
raise_exc=True,
).result()
except Exception as err:
success = False
Expand All @@ -149,7 +170,10 @@ def on_api_command(self, event, payload):
err = False
try:
self._ensure_meross_login(
payload["user_email"], payload["user_password"], raise_exc=True
payload["api_base_url"],
payload["user_email"],
payload["user_password"],
raise_exc=True,
).result()
rv = self.meross.toggle_device(payload["dev_id"]).result()
except Exception as exc:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ $(function() {
}

self.toggle_device = function() {
var api_base_url = self.settings.api_base_url();
var username = self.settings.user_email();
var password = self.settings.user_password();
var device_ids = self.settings.target_device_ids();
Expand All @@ -126,6 +127,7 @@ $(function() {
"psucontrol_meross",
"toggle_device",
{
"api_base_url": api_base_url,
"user_email": username,
"user_password": password,
"dev_ids": device_ids,
Expand All @@ -144,6 +146,7 @@ $(function() {
}

self.test_meross_cloud_login = function() {
var api_base_url = self.settings.api_base_url();
var username = self.settings.user_email();
var password = self.settings.user_password();

Expand All @@ -157,6 +160,7 @@ $(function() {
"psucontrol_meross",
"try_login",
{
"api_base_url": api_base_url,
"user_email": username,
"user_password": password,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@

<fieldset>
<legend>Meross Cloud</legend>
<div class="control-group">
<label class="control-label" for="settings-psucontrol-meross-url">API URL:</label>
<div class="controls">
<select
id="settings-psucontrol-meross-url"
class="input-block-level"
data-bind="
options: settings.api_urls,
optionsText: 'name',
optionsValue: 'url',
selectedOptions: settings.api_base_url
"
required=""
></select>
</div>
</div>
<div class="control-group">
<label class="control-label" for="settings-psucontrol-meross-login">Login:</label>
<div class="controls">
Expand Down Expand Up @@ -70,4 +86,4 @@
</div>
</div>
</div>
</form>
</form>
4 changes: 2 additions & 2 deletions test/client/test_async_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ async def test_client(
@pytest.mark.asyncio
async def test_login(test_client, mock_meross_iot_http_client, mock_meross_cache):
mock_meross_cache.get_cloud_session_token.return_value = None
await test_client.login("testuser", "password", raise_exc=True)
await test_client.login("api_url", "testuser", "password", raise_exc=True)
mock_meross_iot_http_client.async_from_user_password.assert_called_once_with(
email="testuser", password="password"
api_base_url="api_url", email="testuser", password="password"
)


Expand Down
4 changes: 3 additions & 1 deletion test/test_integration/test_integration_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ def test_on_settings_initialized(
threaded_loop.wait_all_futures()
assert mocked_meross_http_client.async_from_user_password.called
mocked_meross_http_client.async_from_user_password.assert_called_with(
email="settings::user_email::value", password="settings::user_password::value"
api_base_url="settings::api_base_url::value",
email="settings::user_email::value",
password="settings::user_password::value",
)
assert (
mock_shelve_data[
Expand Down

0 comments on commit 48e405b

Please sign in to comment.