mtrab / pyworxcloud Goto Github PK
View Code? Open in Web Editor NEWPyPI module for integrating with Worx Cloud devices
License: GNU General Public License v3.0
PyPI module for integrating with Worx Cloud devices
License: GNU General Public License v3.0
Hi!
I used your repo and it works fantastic! But I might have made a service script that runs about every 2sec and I got blocked, does anyone know what the limit is?
Thanks in advance!
Best regards Max
Greetings!
Upon testing version 3.04 I got the following error message:
Traceback (most recent call last):
File "C:\Users\MrBG\Downloads\pyworxcloud-3.0.4\pyworxcloud-3.0.4\pyworxcloud\utils\requests.py", line 73, in GET
req.raise_for_status()
File "C:\Users\MrBG\AppData\Local\Programs\Python\Python311\Lib\site-packages\requests\models.py", line 1021, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://api.worxlandroid.com/api/v2/product-items?status=1
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\MrBG\Downloads\pyworxcloud-3.0.4\pyworxcloud-3.0.4\test.py", line 19, in
cloud.connect()
File "C:\Users\MrBG\Downloads\pyworxcloud-3.0.4\pyworxcloud-3.0.4\pyworxcloud_init_.py", line 234, in connect
self.fetch()
File "C:\Users\MrBG\Downloads\pyworxcloud-3.0.4\pyworxcloud-3.0.4\pyworxcloud_init.py", line 496, in _fetch
self._mowers = self._api.get_mowers()
^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\MrBG\Downloads\pyworxcloud-3.0.4\pyworxcloud-3.0.4\pyworxcloud\api.py", line 102, in get_mowers
mowers = GET(
^^^^
File "C:\Users\MrBG\Downloads\pyworxcloud-3.0.4\pyworxcloud-3.0.4\pyworxcloud\utils\requests.py", line 79, in GET
raise AuthorizationError()
pyworxcloud.exceptions.AuthorizationError
Username / Password and manual login verified.
Thank you in advance,
Frank
service: landroid_cloud.config
data:
timeextension: -10
target:
device_id: [XXX]
entity_id: vacuum.[xxx]
Using landroid_cloud.config to set timeextension doesn't work for negative values. Positive values, including zero, works fine. No error, the value just isn't applied on the robot.
no error
I noticed the extension was not giving updates, and going in the logs I found this:
Can this be linked to #58 or, in your opinion, it is different? The event happened roughly 12 hours after I restarted HA.
Best regards
Timeouts from ID gateways are not handled.
I am a user of MTrab/landroid_cloud and it looks like that this upstream project does not yet support the "One time schedule" feature. It's the ability to start the mower for a defined number of hours, up to 12 h on my WR165E. It would be great to have it in MTrab/landroid_cloud and then hopefully in https://github.com/Barma-lej/halandroid. Thank you for this project. ๐
Additional note:
I think the duration of the "One time schedule" is a setting and not a parameter of the specific command. I can update the number of hours without starting the "One time schedule" sequence. In this case, it would mean an additional setting for cfg
+ an additional cmd
code to find and implement.
Official documentation:
https://wiki.worx.com/en/landroid-schedule-1
Screenshot taken from MTrab/landroid_cloud#59 (comment)
I created a python script to read some data from the Worx cloud. This works fine.
Now I also wanted to start my Worx Landroid from this script. But my Landroid is not responding. I also don't get an error.
My script:
from pyworxcloud import WorxCloud
cloud = WorxCloud("XXX", "XXX")
# Initialize connection
auth = cloud.initialize()
if not auth:
# If invalid credentials are used, or something happend during
# authorize, then exit
exit(0)
# Connect to device with index 0 (devices are enumerated 0, 1, 2 ...) and do
# not verify SSL (False)
cloud.connect(0, False)
cloud.update()
print("online: ----")
print(cloud.online)
print("mqtt: ------")
print(cloud._mqtt)
cloud.start()
print("----")
# Read latest states received from the device
# cloud.update()
# print(cloud._raw)
# print(cloud.status)
# print(cloud.battery_percent)
# print(cloud.battery_charging)
Outputs:
online: ----
True
mqtt: ------
<paho.mqtt.client.Client object at 0x10269bcd0>
----
No output for the start
method, nor any reaction from the Landroid.
FYI: print(cloud.battery_charging)
is in comment but this outputs the correct data.
Hi,
First of all - thank you for your great work here!
I've got a question - what is the difference between method update and getStatus. Only getStatus is "bannable"? Can I call update how often I want but there will be new data only if server sends any since the previous call?
When I am doing cloud.connect() with this code:
from pyworxcloud import WorxCloud
import requests
cloud = WorxCloud("[email protected]", "PASS", "worx")
cloud.connect()
I am getting this exception: TypeError: WorxCloud.connect() missing 1 required positional argument: 'dev_id'
I belive that the reason is that I have the work CloudType, but I dont know how to properly declare a "CloudType"
Thanks in advance!
Best regards Max
Hello,
thanks for sharing pyworxcloud!
I intend to use it for smarthomeng.de.
Unfortunately, I fear that combining the two is difficult, as smarthomeng is threaded, whereas pyworxcloud uses asyncio.
I wonder, if it is really required to use asyncio. I see that it is used only:
So, I wonder if it is really required to use asyncio in the library?
Best regards,
Hendrik
Same as #81 just for Landroid.
Apparently the oauth URL have changed, along with some parameters
In the Worx app, the firmware is "3.32.0+1". pyworxcloud seems to parse this as "{:.2f}".format, which fails.
Pyworxcloud version 3.1.14 (+ landroid_cloud version 3.0.5)
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 388, in async_setup
result = await component.async_setup_entry(hass, self)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/landroid_cloud/__init__.py", line 63, in async_setup_entry
result = await _async_setup(hass, entry)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/landroid_cloud/__init__.py", line 206, in _async_setup
await hass.async_add_executor_job(cloud.connect)
File "/usr/local/lib/python3.11/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/pyworxcloud/__init__.py", line 259, in connect
self._fetch()
File "/usr/local/lib/python3.11/site-packages/pyworxcloud/__init__.py", line 611, in _fetch
self._mowers = self._api.get_mowers()
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/pyworxcloud/api.py", line 119, in get_mowers
mower["firmware_version"] = "{:.2f}".format(mower["firmware_version"])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ValueError: Unknown format code 'f' for object of type 'str'
After upgrading to v2.1.2 the setzone call fails.
This is how i call the service:
service: landroid_cloud.setzone
data:
zone: '2'
target:
entity_id: vacuum.rasimir
This is what appears in HA logfile:
2022-06-30 11:29:02 ERROR (MainThread) [homeassistant.helpers.script.websocket_api_script] websocket_api script: Error executing script. Unexpected error for call_service at pos 1: 'DeviceHandler' object has no attribute 'zone_probability'
Traceback (most recent call last):
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/helpers/script.py", line 447, in _async_step
await getattr(self, handler)()
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/helpers/script.py", line 680, in _async_call_service_step
await service_task
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/core.py", line 1704, in async_call
task.result()
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/core.py", line 1741, in _execute_service
await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
File "/home/homeassistant/.homeassistant/custom_components/landroid_cloud/services.py", line 155, in async_call_landroid_service
await api.services[service][ATTR_SERVICE](service_data)
File "/home/homeassistant/.homeassistant/custom_components/landroid_cloud/device_base.py", line 677, in async_set_zone
await self.hass.async_add_executor_job(partial(device.setzone, str(zone)))
File "/usr/lib/python3.9/concurrent/futures/thread.py", line 52, in run
result = self.fn(*self.args, **self.kwargs)
File "/srv/homeassistant/lib/python3.9/site-packages/pyworxcloud/utils/actions.py", line 186, in setzone
current = self.zone_probability
AttributeError: 'DeviceHandler' object has no attribute 'zone_probability'
2022-06-30 11:29:02 ERROR (MainThread) [homeassistant.components.websocket_api.http.connection] [1550688512] Error handling message: Unknown error (unknown_error)
Traceback (most recent call last):
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/components/websocket_api/decorators.py", line 27, in _handle_async_response
await func(hass, connection, msg)
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/components/websocket_api/commands.py", line 636, in handle_execute_script
await script_obj.async_run(msg.get("variables"), context=context)
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/helpers/script.py", line 1513, in async_run
await asyncio.shield(run.async_run())
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/helpers/script.py", line 405, in async_run
await self._async_step(log_exceptions=False)
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/helpers/script.py", line 449, in _async_step
self._handle_exception(
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/helpers/script.py", line 472, in _handle_exception
raise exception
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/helpers/script.py", line 447, in _async_step
await getattr(self, handler)()
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/helpers/script.py", line 680, in _async_call_service_step
await service_task
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/core.py", line 1704, in async_call
task.result()
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/core.py", line 1741, in _execute_service
await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
File "/home/homeassistant/.homeassistant/custom_components/landroid_cloud/services.py", line 155, in async_call_landroid_service
await api.services[service][ATTR_SERVICE](service_data)
File "/home/homeassistant/.homeassistant/custom_components/landroid_cloud/device_base.py", line 677, in async_set_zone
await self.hass.async_add_executor_job(partial(device.setzone, str(zone)))
File "/usr/lib/python3.9/concurrent/futures/thread.py", line 52, in run
result = self.fn(*self.args, **self.kwargs)
File "/srv/homeassistant/lib/python3.9/site-packages/pyworxcloud/utils/actions.py", line 186, in setzone
current = self.zone_probability
AttributeError: 'DeviceHandler' object has no attribute 'zone_probability'
Hi Morten,
some of us are actually planning to use pyworxcloud for a plugin in a Smarthome application. While using pyworxcloud Version: 1.4.11, there is a exception coming up every time the data is polled:
`2022-01-24 11:22:48 ERROR plugins.landroid.poll_device Method plugins.landroid.poll_device exception: 'bool' object is not subscriptable
Traceback (most recent call last):
File "/usr/local/smarthome/lib/scheduler.py", line 670, in _task
obj()
File "/usr/local/smarthome/plugins/landroid/init.py", line 345, in poll_device
self.worx.update()
File "/home/smarthome/.local/lib/python3.9/site-packages/pyworxcloud/init.py", line 299, in update
self._fetch()
File "/home/smarthome/.local/lib/python3.9/site-packages/pyworxcloud/init.py", line 293, in _fetch
for attr, val in products[self._dev_id].items():
TypeError: 'bool' object is not subscriptable`
Appreciate if you could have a look on it.
Regards
Marcus
Hello
Due to issues with the ISP, sometimes the name of servers cannot be resolved.
This however permanently blocks the extension, since from that moment the extension (I assume) doesn't try again to contact the server.
Here is the log entry with that problem.
pyworxcloud - log.txt
The issue happened on 1st July, and until now (3 days) it has not recovered. No additional log entries are present in the log list in Home Assistant, so I assume the script crashed.
I expect the extension to continue retrying and, when the DNS come back online, resume proper operations
First of all great project - wor(x)ks right away!
Not really an issue just a question:
The season started and to my surprise I see that certificates for mqtt don't work anymore with Worx.
You adapted the code to handle the new process. But all my stuff is based on MQTT means somehow I need to bridge or forward the messages to my mqtt server.
Can you give me a hint where in your code I could add this logic or are there any plans in that direction already?
I see self._forward_on_message is triggered and calls on_update, maybe there?
but don't know where to put in the additional connection part.
After upgrading to v2.1.2 the edgecut service does not do anything at all.
there is no error, no log, no reaction of the mower.
This is how i call the service:
service: landroid_cloud.edgecut
target:
entity_id: vacuum.rasimir
Hi,
after i was able to get pyworxcloud running on windows I tried the setup on a linux ubuntu.
I'm getting the above Error,... Is there an issue with the Versions in combination with paho.mqtt.python?
I installed the latest Versions.
Would love if someone could help.
If you need more Information, let me know.
Thex a lot!!!!
Mark
Sadly, set_mowingzone fails again after fixing edgecut:
might be related to #49
2022-07-04 09:48:06 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/components/script/__init__.py", line 428, in _async_run
return await self.script.async_run(script_vars, context)
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/helpers/script.py", line 1513, in async_run
await asyncio.shield(run.async_run())
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/helpers/script.py", line 405, in async_run
await self._async_step(log_exceptions=False)
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/helpers/script.py", line 449, in _async_step
self._handle_exception(
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/helpers/script.py", line 472, in _handle_exception
raise exception
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/helpers/script.py", line 447, in _async_step
await getattr(self, handler)()
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/helpers/script.py", line 680, in _async_call_service_step
await service_task
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/core.py", line 1704, in async_call
task.result()
File "/srv/homeassistant/lib/python3.9/site-packages/homeassistant/core.py", line 1741, in _execute_service
await cast(Callable[[ServiceCall], Awaitable[None]], handler.job.target)(
File "/home/homeassistant/.homeassistant/custom_components/landroid_cloud/services.py", line 160, in async_call_landroid_service
await api.services[service][ATTR_SERVICE](service_data)
File "/home/homeassistant/.homeassistant/custom_components/landroid_cloud/device_base.py", line 708, in async_set_zone
await self.hass.async_add_executor_job(partial(device.setzone, str(zone)))
File "/usr/lib/python3.9/concurrent/futures/thread.py", line 52, in run
result = self.fn(*self.args, **self.kwargs)
File "/srv/homeassistant/lib/python3.9/site-packages/pyworxcloud/utils/actions.py", line 188, in setzone
while not new_zones[self.mowing_zone] == zone:
AttributeError: 'DeviceHandler' object has no attribute 'mowing_zone'
Hello,
we are using your lovely package for smarthome-ng.
Unfortunately, it is a bit difficult to keep track of the changes that you do. Could you please consider the following:
Thanks and best regards,
Hendrik
This causes MTrab/landroid_cloud#444 (Zone selection not working) in the Home Assistant component. See the discussion there for details.
The requirements.txt file is not aligned with the dependencies in pyproject.toml.
I'm not sure if this is because the requirements.txt file is outdated, but I think that it is better to either align it or to remove it from the repo (of course with a very low priority; after all, very few people will use it).
In addition, I noticed that when I created manually a venv to run the examples I also had to pull the tzdata package; maybe it is an implicit dependency for poetry, but in requirements.txt I had to add it otherwise the python script complained
Thank you
Hi,
not sure if this is the right way to ask this question, but i don't find a better place,....
First of all THX a lot for you work!!!!!
I can already start and stop my mover (worx) but i'm not able to send him to a specific Zone. is there any excample or someone who can help me on that?
I'm using just the phyton script without IO Broaker.
Thx a lot up front!
Mark
Error in version following upgrade from 2.1.0 to 2.1.1 below is environment and current error message
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 339, in async_setup
result = await component.async_setup_entry(hass, self)
File "/config/custom_components/landroid_cloud/__init__.py", line 61, in async_setup_entry
result = await _setup(hass, entry)
File "/config/custom_components/landroid_cloud/__init__.py", line 203, in _setup
await hass.async_add_executor_job(cloud.connect, False, False)
File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/lib/python3.9/site-packages/pyworxcloud/__init__.py", line 224, in connect
self._fetch()
File "/usr/local/lib/python3.9/site-packages/pyworxcloud/__init__.py", line 609, in _fetch
device = DeviceHandler(self._api, product)
File "/usr/local/lib/python3.9/site-packages/pyworxcloud/utils/devices.py", line 36, in __init__
self.__mapinfo(api, product)
File "/usr/local/lib/python3.9/site-packages/pyworxcloud/utils/devices.py", line 84, in __mapinfo
self.warranty = Warranty(data)
File "/usr/local/lib/python3.9/site-packages/pyworxcloud/utils/warranty.py", line 20, in __init__
self["expires_at"] = string_to_time(
File "/usr/local/lib/python3.9/site-packages/pyworxcloud/helpers/time_format.py", line 38, in string_to_time
datetime.strptime(dt_string, format)
TypeError: strptime() argument 1 must be str, not None
Zone mapping renders an error when key "last_status" is missing in dat dictionary.
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 387, in async_setup
result = await component.async_setup_entry(hass, self)
File "/config/custom_components/landroid_cloud/__init__.py", line 63, in async_setup_entry
result = await _async_setup(hass, entry)
File "/config/custom_components/landroid_cloud/__init__.py", line 206, in _async_setup
await hass.async_add_executor_job(cloud.connect)
File "/usr/local/lib/python3.10/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/lib/python3.10/site-packages/pyworxcloud/__init__.py", line 235, in connect
self._fetch()
File "/usr/local/lib/python3.10/site-packages/pyworxcloud/__init__.py", line 516, in _fetch
device = DeviceHandler(self._api, mower)
File "/usr/local/lib/python3.10/site-packages/pyworxcloud/utils/devices.py", line 46, in __init__
self.__mapinfo(api, mower)
File "/usr/local/lib/python3.10/site-packages/pyworxcloud/utils/devices.py", line 100, in __mapinfo
self.zone = Zone(data)
File "/usr/local/lib/python3.10/site-packages/pyworxcloud/utils/zone.py", line 22, in __init__
self["index"] = data["last_status"]["payload"]["dat"]["lz"]
KeyError: 'lz'
Reported in MTrab/landroid_cloud#372
LandXcape stuck with initializing. Loggin in on cloud and find the robot, but entities just showing initializing. Cant start
The system cannot restart because the configuration is not valid: Component error: landroid_cloud - Exception importing custom_components.landroid_cloud
now i cannot restart anymore
Hey!
Awesome thing youve created! Works fantastic! I am curious if theres an easy way to get the current status of the mower, like "mowing" or "paused". Can you do it with this repo?
Thanks in advance!
Best regards Max
I updated your landroid-integration to the latest version (skipped a few...) and am getting the following error on startup. I deleted the mower, removed the integration from hacs and re-installed everything. Stil getting the same error. any idea what goes wrong? I am using the current version of HA (2022.6.7). Mower is a landxcape LX 790i.
error setting up entry Landxcape [email protected] for landroid_cloud
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 339, in async_setup
result = await component.async_setup_entry(hass, self)
File "/config/custom_components/landroid_cloud/__init__.py", line 64, in async_setup_entry
result = await _async_setup(hass, entry)
File "/config/custom_components/landroid_cloud/__init__.py", line 205, in _async_setup
await hass.async_add_executor_job(cloud.connect, False, False)
File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/lib/python3.9/site-packages/pyworxcloud/__init__.py", line 225, in connect
self._fetch()
File "/usr/local/lib/python3.9/site-packages/pyworxcloud/__init__.py", line 619, in _fetch
device = DeviceHandler(self._api, product)
File "/usr/local/lib/python3.9/site-packages/pyworxcloud/utils/devices.py", line 37, in __init__
self.__mapinfo(api, product)
File "/usr/local/lib/python3.9/site-packages/pyworxcloud/utils/devices.py", line 90, in __mapinfo
self.warranty = Warranty(data)
File "/usr/local/lib/python3.9/site-packages/pyworxcloud/utils/warranty.py", line 20, in __init__
self["expires_at"] = string_to_time(
File "/usr/local/lib/python3.9/site-packages/pyworxcloud/helpers/time_format.py", line 34, in string_to_time
timezone = pytz.timezone(tz)
File "/usr/local/lib/python3.9/site-packages/pytz/__init__.py", line 168, in timezone
raise UnknownTimeZoneError(None)
pytz.exceptions.UnknownTimeZoneError: None
Worx hosts their cloud API server with Cloudflare, and appears to have enabled Cloudflare Turnstile to intercept connection attempts from flagged IP addresses. How those IP addresses are flagged is unclear. The effect is that, for some requestors, instead of directly connecting to the API, HTTP status 403 is returned, with an error page that's full of Javascript, with the intention that a normal browser would successfully execute a challenge and be forwarded to the actual API endpoint. Unfortunately, this interception will of course result in an exception here:
pyworxcloud/pyworxcloud/utils/requests.py
Lines 56 to 70 in eb4a38f
Solving it programmatically in this library might be possible, but would be pretty clunky, for example by running a JS engine to process the challenge. Instead, I'm hoping that with your open dialog with Worx, you might be able to find a way to work through it -- whether using specific headers to identify this library and bypass Turnstile, or some other approach mutually agreeable with them.
For reference, I'm attaching logs showing the results of curl -v https://id.worx.com/login
from a client that's being intercepted by Turnstile, and one that is allowed to connect unimpeded.
worx-clear.log
worx-cloudfare-turnstile.log
Hello Marlene,
thanks for your work on updating to v3!
I have one issue though:
I (and the target audience) do not have python 3.10. I have "patched" pyworxcloud to accept 3.9 and it seems to work. At least:
cloud.connect()
print(vars(cloud))
cloud.disconnect()
Can you tell me whether 3.10 is really needed?
Best regards,
Hendrik
Ladroid doesn't appear in Landroid_cloud version: 2.3.0
Logger: root
Source: /usr/src/homeassistant/homeassistant/bootstrap.py:330
First occurred: 17:06:14 (1 occurrences)
Last logged: 17:06:14
Uncaught thread exception
Traceback (most recent call last):
File "/usr/local/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
self.run()
File "/usr/local/lib/python3.10/threading.py", line 953, in run
self._target(*self._args, **self._kwargs)
File "/usr/local/lib/python3.10/site-packages/paho/mqtt/client.py", line 3591, in _thread_main
self.loop_forever(retry_first_connection=True)
File "/usr/local/lib/python3.10/site-packages/paho/mqtt/client.py", line 1756, in loop_forever
rc = self._loop(timeout)
File "/usr/local/lib/python3.10/site-packages/paho/mqtt/client.py", line 1164, in _loop
rc = self.loop_read()
File "/usr/local/lib/python3.10/site-packages/paho/mqtt/client.py", line 1556, in loop_read
rc = self._packet_read()
File "/usr/local/lib/python3.10/site-packages/paho/mqtt/client.py", line 2439, in _packet_read
rc = self._packet_handle()
File "/usr/local/lib/python3.10/site-packages/paho/mqtt/client.py", line 3033, in _packet_handle
return self._handle_publish()
File "/usr/local/lib/python3.10/site-packages/paho/mqtt/client.py", line 3327, in _handle_publish
self._handle_on_message(message)
File "/usr/local/lib/python3.10/site-packages/paho/mqtt/client.py", line 3570, in _handle_on_message
on_message(self, self._userdata, message)
File "/usr/local/lib/python3.10/site-packages/pyworxcloud/__init__.py", line 363, in _forward_on_message
self._decode_data(device)
File "/usr/local/lib/python3.10/site-packages/pyworxcloud/__init__.py", line 556, in _decode_data
device.schedules.update_progress_and_next(
File "/usr/local/lib/python3.10/site-packages/pyworxcloud/utils/schedules.py", line 196, in update_progress_and_next
self["daily_progress"] = info.calculate_progress()
File "/usr/local/lib/python3.10/site-packages/pyworxcloud/utils/schedules.py", line 114, in calculate_progress
if self.__now >= start and self.__now < end:
TypeError: can't compare offset-naive and offset-aware datetimes
battery_level: null
battery_icon: mdi:battery-unknown
accessories: null
battery:
cycles:
total: 832
current: 0
reset_at: null
reset_time: null
temperature: 23.5
voltage: 19.26
percent: 100
charging: false
blades:
total_on: 74489
reset_at: 61657
reset_time: '2022-04-19T07:04:53+02:00'
current_on: 12832
error:
id: 5
description: rain delay
firmware:
auto_upgrade: false
version: 3.26
locked: false
mac_address: xxxxxxxxxxx
model: Landroid M500
online: true
orientation:
pitch: 0
roll: 0
yaw: 0
rain_sensor:
delay: 60
triggered: true
remaining: 60
schedule:
time_extension: 0
active: true
auto_schedule:
settings: {}
enabled: null
primary:
monday:
start: '11:00'
end: '12:30'
duration: 90
boundary: false
tuesday:
start: '11:00'
end: '12:30'
duration: 90
boundary: false
wednesday:
start: '11:00'
end: '12:30'
duration: 90
boundary: true
thursday:
start: '11:00'
end: '12:30'
duration: 90
boundary: false
friday:
start: '11:00'
end: '12:30'
duration: 90
boundary: false
saturday:
start: '11:00'
end: '12:30'
duration: 90
boundary: false
sunday:
start: '11:00'
end: '12:30'
duration: 90
boundary: true
secondary:
monday:
start: '18:00'
end: '19:30'
duration: 90
boundary: false
tuesday:
start: '18:00'
end: '19:30'
duration: 90
boundary: false
wednesday:
start: '18:00'
end: '19:30'
duration: 90
boundary: false
thursday:
start: '18:00'
end: '19:30'
duration: 90
boundary: false
friday:
start: '18:00'
end: '19:30'
duration: 90
boundary: false
saturday:
start: '18:00'
end: '19:30'
duration: 90
boundary: false
sunday:
start: '18:00'
end: '19:30'
duration: 90
boundary: false
serial_number: xxxxxxxxxxxxx
status_info:
id: 1
description: home
time_zone: Europe/Berlin
zone:
current: 0
next: 0
index: 7
indicies:
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- 0
starting_point:
- 0
- 0
- 0
- 0
capabilities: null
mqtt_connected: true
supported_landroid_features: 0
daily_progress: null
next_scheduled_start: null
device_class: landroid_cloud__state
friendly_name: Mower
supported_features: 12500
It does not seem as the MQTT connection is retried when it for some reason has gone offline.
I tried to install v3 in home assistant, via the landroid_cloud integration - but it failed to install.
It seems the issue is due to awscrt, and by association awsiot which provides the mqtt capability.
Is awscrt (via awsiotsdk) required? I am able to manually install awsiot, but when I try install awsiotsdk, it pulls in awscrt and I get the following:
Collecting awscrt
Using cached awscrt-0.16.10.tar.gz (21.9 MB)
Preparing metadata (setup.py): started
Preparing metadata (setup.py): finished with status 'done'
Building wheels for collected packages: awscrt
Building wheel for awscrt (setup.py): started
Building wheel for awscrt (setup.py): finished with status 'error'
error: subprocess-exited-with-error
ร python setup.py bdist_wheel did not run successfully.
โ exit code: 1
โฐโ> [67 lines of output]
running bdist_wheel
running build
running build_py
creating build
creating build/lib.linux-x86_64-cpython-310
creating build/lib.linux-x86_64-cpython-310/awscrt
copying awscrt/websocket.py -> build/lib.linux-x86_64-cpython-310/awscrt
copying awscrt/s3.py -> build/lib.linux-x86_64-cpython-310/awscrt
copying awscrt/mqtt5.py -> build/lib.linux-x86_64-cpython-310/awscrt
copying awscrt/mqtt.py -> build/lib.linux-x86_64-cpython-310/awscrt
copying awscrt/io.py -> build/lib.linux-x86_64-cpython-310/awscrt
copying awscrt/http.py -> build/lib.linux-x86_64-cpython-310/awscrt
copying awscrt/exceptions.py -> build/lib.linux-x86_64-cpython-310/awscrt
copying awscrt/crypto.py -> build/lib.linux-x86_64-cpython-310/awscrt
copying awscrt/common.py -> build/lib.linux-x86_64-cpython-310/awscrt
copying awscrt/checksums.py -> build/lib.linux-x86_64-cpython-310/awscrt
copying awscrt/auth.py -> build/lib.linux-x86_64-cpython-310/awscrt
copying awscrt/_test.py -> build/lib.linux-x86_64-cpython-310/awscrt
copying awscrt/init.py -> build/lib.linux-x86_64-cpython-310/awscrt
creating build/lib.linux-x86_64-cpython-310/awscrt/eventstream
copying awscrt/eventstream/rpc.py -> build/lib.linux-x86_64-cpython-310/awscrt/eventstream
copying awscrt/eventstream/init.py -> build/lib.linux-x86_64-cpython-310/awscrt/eventstream
running build_ext
Traceback (most recent call last):
File "", line 2, in
File "", line 34, in
File "/tmp/pip-install-i36yyhey/awscrt_dc0d744314454142b16be4fa750afda1/setup.py", line 348, in
setuptools.setup(
File "/usr/local/lib/python3.10/site-packages/setuptools/init.py", line 87, in setup
return distutils.core.setup(**attrs)
File "/usr/local/lib/python3.10/site-packages/setuptools/_distutils/core.py", line 177, in setup
return run_commands(dist)
File "/usr/local/lib/python3.10/site-packages/setuptools/_distutils/core.py", line 193, in run_commands
dist.run_commands()
File "/usr/local/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 968, in run_commands
self.run_command(cmd)
File "/usr/local/lib/python3.10/site-packages/setuptools/dist.py", line 1229, in run_command
super().run_command(command)
File "/usr/local/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 987, in run_command
cmd_obj.run()
File "/usr/local/lib/python3.10/site-packages/wheel/bdist_wheel.py", line 299, in run
self.run_command('build')
File "/usr/local/lib/python3.10/site-packages/setuptools/_distutils/cmd.py", line 317, in run_command
self.distribution.run_command(command)
File "/usr/local/lib/python3.10/site-packages/setuptools/dist.py", line 1229, in run_command
super().run_command(command)
File "/usr/local/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 987, in run_command
cmd_obj.run()
File "/usr/local/lib/python3.10/site-packages/setuptools/command/build.py", line 24, in run
super().run()
File "/usr/local/lib/python3.10/site-packages/setuptools/_distutils/command/build.py", line 131, in run
self.run_command(cmd_name)
File "/usr/local/lib/python3.10/site-packages/setuptools/_distutils/cmd.py", line 317, in run_command
self.distribution.run_command(command)
File "/usr/local/lib/python3.10/site-packages/setuptools/dist.py", line 1229, in run_command
super().run_command(command)
File "/usr/local/lib/python3.10/site-packages/setuptools/_distutils/dist.py", line 987, in run_command
cmd_obj.run()
File "/tmp/pip-install-i36yyhey/awscrt_dc0d744314454142b16be4fa750afda1/setup.py", line 255, in run
self._build_dependencies(dep_build_dir, dep_install_path)
File "/tmp/pip-install-i36yyhey/awscrt_dc0d744314454142b16be4fa750afda1/setup.py", line 247, in _build_dependencies
self._build_dependencies_impl(build_dir, install_path)
File "/tmp/pip-install-i36yyhey/awscrt_dc0d744314454142b16be4fa750afda1/setup.py", line 158, in _build_dependencies_impl
cmake = get_cmake_path()
File "/tmp/pip-install-i36yyhey/awscrt_dc0d744314454142b16be4fa750afda1/setup.py", line 121, in get_cmake_path
raise Exception("CMake must be installed to build from source.")
Exception: CMake must be installed to build from source.
[end of output]
note: This error originates from a subprocess, and is likely not a problem with pip.
ERROR: Failed building wheel for awscrt
so it appears to need cmake, which is not part of HA
Can the dependency on awscrt be removed, if it is not strictly required for awsiot to function ?
Hello Marlene,
with 1.4.19 update() is deprecated. But example.py still uses it.
Could you please update example.py?
Best regards,
Hendrik
Hi,
I try to use the youre testfile with the setCallback function and it prints the new status very well.
But I'm not able to revere to the variables within the registered function.
Can you give me a tip how i can do that?
Here is the function part of whot I'm trying to do:
def receive_data(
name: str, device: DeviceHandler # pylint: disable=unused-argument
) -> None:
"""Callback function when the MQTT broker sends new data."""
print("Got data on MQTT from " + name)
#logTimestamp = str(datetime.now())
#logText = str(vars(cloud))
landroidLog = open('landroidLog.txt','a')
landroidLog.write(vars(cloud))
A big thx up front and kind regards,
Mark
/Dear @MTrab ,
I think I've found a situation in which the JSON sent from the Positech cloud is missing the key : DATA.MODULES.4G.GPS .
if this happens an exception is thrown :
Exception in thread Thread-1 (_thread_main):
Traceback (most recent call last):
File "/usr/local/lib/python3.11/threading.py", line 1045, in _bootstrap_inner
self.run()
File "/usr/local/lib/python3.11/threading.py", line 982, in run
self._target(*self._args, **self._kwargs)
File "/usr/local/lib/python3.11/site-packages/paho/mqtt/client.py", line 3591, in _thread_main
self.loop_forever(retry_first_connection=True)
File "/usr/local/lib/python3.11/site-packages/paho/mqtt/client.py", line 1756, in loop_forever
rc = self._loop(timeout)
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/paho/mqtt/client.py", line 1164, in _loop
rc = self.loop_read()
^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/paho/mqtt/client.py", line 1556, in loop_read
rc = self._packet_read()
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/paho/mqtt/client.py", line 2439, in _packet_read
rc = self._packet_handle()
^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/paho/mqtt/client.py", line 3033, in _packet_handle
return self._handle_publish()
^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/paho/mqtt/client.py", line 3330, in _handle_publish
self._handle_on_message(message)
File "/usr/local/lib/python3.11/site-packages/paho/mqtt/client.py", line 3570, in _handle_on_message
on_message(self, self._userdata, message)
File "/code/pyworxcloud/utils/mqtt.py", line 149, in _forward_on_message
self._on_update(msg)
File "/code/pyworxcloud/__init__.py", line 395, in _on_update
self._decode_data(device)
File "/code/pyworxcloud/__init__.py", line 475, in _decode_data
data["dat"]["modules"]["4G"]["gps"]["coo"][0],
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^
this error seems to stop the connection to the MQTT server , thus interrupting data receive.
as you can see the library correctly issue a force update, but no data is received:
2024-05-29T05:48:22.652964462Z 2024-05-29 07:48:22,652 [mqtt.py] [ping] [DEBUG] [239] Sending '{"id": xxxxxx, "uuid": "xxxxxxxxxxxxx", "tm": "2024-05-29T07:48:22Z", "cmd": 0}' on topic 'KR/MW/KR173E/xxxxxxxxxxxx/v1/commandIn'
2024-05-29T05:48:22.652257769Z 2024-05-29 07:48:22,652 [__init__.py] [_force_refresh] [DEBUG] [341] Forcing refresh for 'RTK KR173E'
2024-05-29T05:48:22.652825783Z 2024-05-29 07:48:22,652 [__init__.py] [update] [DEBUG] [730] Trying to refresh 'xxxxxxxxxxxxx'
2024-05-29T05:48:22.652881468Z 2024-05-29 07:48:22,652 [mqtt.py] [format_message] [DEBUG] [287] Formatting message '{'cmd': 0}' to '{'id': 21893, 'uuid': 'xxxxxxxxxxxxxx', 'tm': '2024-05-29T07:48:22Z', 'cmd': 0}'
I suggest to add Key verification to the code at line 471:
# Check for extra module availability
if "modules" in data["dat"]:
if "4G" in data["dat"]["modules"]:
if "gps" in data["dat"]["modules"]["4G"]:
device.gps = Location(
data["dat"]["modules"]["4G"]["gps"]["coo"][0],
data["dat"]["modules"]["4G"]["gps"]["coo"][1],
)
Yesterdays commit (e290a63) breaks the library for me:
My last_status is None:
File "/usr/local/lib/python3.10/site-packages/pyworxcloud/utils/zone.py", line 22, in __init__
self["index"] = data["last_status"]["payload"]["dat"]["lz"]
TypeError: 'NoneType' object is not subscriptable
Capability data: { .......... 'last_status': None, 'model': {'code': 'WR105SI.1', .............. }
Hello,
I am trying the simple example from the wiki.
2022-10-24 11:59:33,957 [__init__.py] [connect] [DEBUG] [222] Fetching basic API data
2022-10-24 11:59:34,458 [__init__.py] [connect] [DEBUG] [224] Done fetching basic API data
2022-10-24 11:59:34,458 [__init__.py] [connect] [DEBUG] [226] Setting up MQTT handler
2022-10-24 11:59:34,459 [__init__.py] [connect] [DEBUG] [241] Done setting up MQTT handler, setting MQTT config.
2022-10-24 11:59:34,459 [__init__.py] [connect] [DEBUG] [267] Done setting MQTT config, fetching certificate.
2022-10-24 11:59:34,831 [__init__.py] [connect] [DEBUG] [271] Done fetching certificate, setting TLS.
2022-10-24 11:59:34,831 [__init__.py] [connect] [DEBUG] [276] Done setting TLS, beginning MQTT connect.
2022-10-24 11:59:34,965 [__init__.py] [connect] [DEBUG] [279] MQTT connect done, starting loop
2022-10-24 11:59:34,966 [__init__.py] [connect] [DEBUG] [282] MQTT loop started
2022-10-24 11:59:34,966 [__init__.py] [connect] [DEBUG] [285] Converting date and time string
2022-10-24 11:59:34,967 [__init__.py] [connect] [DEBUG] [290] Connection tasks all done
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/lib/python3.9/threading.py", line 980, in _bootstrap_inner
self.run()
File "/usr/local/lib/python3.9/threading.py", line 917, in run
self._target(*self._args, **self._kwargs)
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3591, in _thread_main
self.loop_forever(retry_first_connection=True)
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1756, in loop_forever
rc = self._loop(timeout)
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1164, in _loop
rc = self.loop_read()
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 1558, in loop_read
return self._loop_rc_handle(rc)
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 2350, in _loop_rc_handle
self._do_on_disconnect(rc, properties)
File "/usr/local/lib/python3.9/site-packages/paho/mqtt/client.py", line 3475, in _do_on_disconnect
on_disconnect(self, self._userdata, rc)
File "/usr/local/lib/python3.9/site-packages/pyworxcloud/__init__.py", line 627, in _on_disconnect
raise MQTTException(
pyworxcloud.exceptions.MQTTException: Unexpected MQTT disconnect - were you perhaps banned?
2022-10-24 11:59:35,194 [__init__.py] [_decode_data] [DEBUG] [371] Data decoding for M started
2022-10-24 11:59:35,194 [__init__.py] [_decode_data] [DEBUG] [374] Found JSON decoded data: {'id': ...
The JSON data seems correct.
What could be the issue?
Best regards,
Hendrik
Same as #81 just for Kress.
Apparently the oauth URL have changed, along with some parameters
Module tries to generate a new connection with an invalid token when multiple mowers is found in one account.
Trying to login to a Landxcape account results in an 404 error.
Looks like they have changed something in the URLs for the Landxcape devices.
404 Client Error: Not Found for url: https://api.landxcape-services.com/api/v2/oauth/token
Configured for Landxcape through GUI
During initialization an unhandled exception occurs in pyworxcloud.utils.warranty because the data
input argument has None
for the timezone
.
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/config_entries.py", line 353, in async_setup
result = await component.async_setup_entry(hass, self)
File "/config/custom_components/landroid_cloud/__init__.py", line 66, in async_setup_entry
result = await _async_setup(hass, entry)
File "/config/custom_components/landroid_cloud/__init__.py", line 208, in _async_setup
await hass.async_add_executor_job(cloud.connect, False, False)
File "/usr/local/lib/python3.10/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/lib/python3.10/site-packages/pyworxcloud/__init__.py", line 226, in connect
self._fetch()
File "/usr/local/lib/python3.10/site-packages/pyworxcloud/__init__.py", line 638, in _fetch
device = DeviceHandler(self._api, product)
File "/usr/local/lib/python3.10/site-packages/pyworxcloud/utils/devices.py", line 37, in __init__
self.__mapinfo(api, product)
File "/usr/local/lib/python3.10/site-packages/pyworxcloud/utils/devices.py", line 90, in __mapinfo
self.warranty = Warranty(data)
File "/usr/local/lib/python3.10/site-packages/pyworxcloud/utils/warranty.py", line 27, in __init__
< datetime.now().astimezone(pytz.timezone(data["time_zone"]))
File "/usr/local/lib/python3.10/site-packages/pytz/__init__.py", line 168, in timezone
raise UnknownTimeZoneError(None)
pytz.exceptions.UnknownTimeZoneError: None
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.