pymammotion 0.5.34__tar.gz → 0.5.40__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pymammotion might be problematic. Click here for more details.
- pymammotion-0.5.40/.gitignore +237 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/PKG-INFO +25 -31
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/__init__.py +3 -3
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/aliyun/cloud_gateway.py +106 -18
- pymammotion-0.5.40/pymammotion/aliyun/model/dev_by_account_response.py +225 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/device.py +1 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/device_config.py +1 -1
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/enums.py +3 -1
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/generate_route_information.py +2 -2
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/hash_list.py +105 -33
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/region_data.py +4 -4
- pymammotion-0.5.34/pymammotion/data/state_manager.py → pymammotion-0.5.40/pymammotion/data/mower_state_manager.py +17 -7
- pymammotion-0.5.40/pymammotion/homeassistant/__init__.py +3 -0
- pymammotion-0.5.40/pymammotion/homeassistant/mower_api.py +446 -0
- pymammotion-0.5.40/pymammotion/homeassistant/rtk_api.py +54 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/http/http.py +115 -4
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/http/model/http.py +77 -2
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/http/model/response_factory.py +10 -4
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mammotion/commands/mammotion_command.py +6 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mammotion/commands/messages/navigation.py +10 -6
- pymammotion-0.5.40/pymammotion/mammotion/devices/__init__.py +29 -0
- pymammotion-0.5.40/pymammotion/mammotion/devices/base.py +163 -0
- pymammotion-0.5.40/pymammotion/mammotion/devices/mammotion.py +529 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mammotion/devices/mammotion_bluetooth.py +7 -5
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mammotion/devices/mammotion_cloud.py +22 -74
- pymammotion-0.5.40/pymammotion/mammotion/devices/mammotion_mower_ble.py +49 -0
- pymammotion-0.5.40/pymammotion/mammotion/devices/mammotion_mower_cloud.py +39 -0
- pymammotion-0.5.40/pymammotion/mammotion/devices/managers/managers.py +81 -0
- pymammotion-0.5.40/pymammotion/mammotion/devices/mower_device.py +121 -0
- pymammotion-0.5.40/pymammotion/mammotion/devices/mower_manager.py +107 -0
- pymammotion-0.5.40/pymammotion/mammotion/devices/rtk_ble.py +89 -0
- pymammotion-0.5.40/pymammotion/mammotion/devices/rtk_cloud.py +113 -0
- pymammotion-0.5.40/pymammotion/mammotion/devices/rtk_device.py +50 -0
- pymammotion-0.5.40/pymammotion/mammotion/devices/rtk_manager.py +122 -0
- pymammotion-0.5.40/pymammotion/mqtt/__init__.py +6 -0
- pymammotion-0.5.34/pymammotion/mqtt/mammotion_mqtt.py → pymammotion-0.5.40/pymammotion/mqtt/aliyun_mqtt.py +8 -8
- pymammotion-0.5.40/pymammotion/mqtt/mammotion_mqtt.py +170 -0
- pymammotion-0.5.40/pymammotion/mqtt/mqtt_models.py +66 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/__init__.py +1 -1
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/mctrl_nav.proto +1 -1
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/mctrl_nav_pb2.py +1 -1
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/mctrl_nav_pb2.pyi +4 -4
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/mctrl_sys.proto +1 -1
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/utility/device_type.py +88 -3
- pymammotion-0.5.40/pymammotion/utility/mur_mur_hash.py +159 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pyproject.toml +60 -62
- pymammotion-0.5.34/pymammotion/aliyun/model/dev_by_account_response.py +0 -47
- pymammotion-0.5.34/pymammotion/mammotion/devices/__init__.py +0 -5
- pymammotion-0.5.34/pymammotion/mammotion/devices/base.py +0 -285
- pymammotion-0.5.34/pymammotion/mammotion/devices/mammotion.py +0 -372
- pymammotion-0.5.34/pymammotion/mqtt/__init__.py +0 -5
- pymammotion-0.5.34/pymammotion/utility/mur_mur_hash.py +0 -114
- {pymammotion-0.5.34 → pymammotion-0.5.40}/LICENSE +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/README.md +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/aliyun/__init__.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/aliyun/client.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/aliyun/model/aep_response.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/aliyun/model/connect_response.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/aliyun/model/login_by_oauth_response.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/aliyun/model/regions_response.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/aliyun/model/session_by_authcode_response.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/aliyun/model/thing_response.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/aliyun/regions.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/aliyun/tea/core.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/aliyun/tmp_constant.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/bluetooth/__init__.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/bluetooth/ble.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/bluetooth/ble_message.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/bluetooth/const.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/bluetooth/data/__init__.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/bluetooth/data/convert.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/bluetooth/data/framectrldata.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/bluetooth/data/notifydata.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/bluetooth/model/__init__.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/bluetooth/model/atomic_integer.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/const.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/__init__.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/__init__.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/account.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/device_info.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/device_limits.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/errors.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/excute_boarder_params.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/execute_boarder.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/location.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/mowing_modes.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/rapid_state.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/raw_data.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/report_info.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/model/work.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/mqtt/__init__.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/mqtt/event.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/mqtt/properties.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/data/mqtt/status.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/event/__init__.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/event/event.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/http/__init__.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/http/_init_.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/http/encryption.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/http/model/__init__.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/http/model/camera_stream.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/http/model/rtk.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mammotion/__init__.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mammotion/commands/__init__.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mammotion/commands/abstract_message.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mammotion/commands/messages/__init__.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mammotion/commands/messages/basestation.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mammotion/commands/messages/driver.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mammotion/commands/messages/media.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mammotion/commands/messages/network.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mammotion/commands/messages/ota.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mammotion/commands/messages/system.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mammotion/commands/messages/video.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mammotion/control/__init__.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mammotion/control/joystick.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mqtt/linkkit/__init__.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mqtt/linkkit/h2client.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mqtt/linkkit/linkkit.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/mqtt/mammotion_future.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/basestation.proto +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/basestation_pb2.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/basestation_pb2.pyi +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/common.proto +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/common_pb2.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/common_pb2.pyi +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/dev_net.proto +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/dev_net_pb2.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/dev_net_pb2.pyi +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/luba_msg.proto +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/luba_msg_pb2.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/luba_msg_pb2.pyi +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/luba_mul.proto +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/luba_mul_pb2.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/luba_mul_pb2.pyi +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/mctrl_driver.proto +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/mctrl_driver_pb2.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/mctrl_driver_pb2.pyi +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/mctrl_ota.proto +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/mctrl_ota_pb2.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/mctrl_ota_pb2.pyi +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/mctrl_pept.proto +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/mctrl_pept_pb2.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/mctrl_pept_pb2.pyi +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/mctrl_sys_pb2.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/mctrl_sys_pb2.pyi +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/message_pool.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/proto/py.typed +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/py.typed +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/utility/constant/__init__.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/utility/constant/device_constant.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/utility/conversions.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/utility/datatype_converter.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/utility/device_config.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/utility/map.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/utility/movement.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/utility/periodic.py +0 -0
- {pymammotion-0.5.34 → pymammotion-0.5.40}/pymammotion/utility/rocker_util.py +0 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64
|
|
19
|
+
lib64/
|
|
20
|
+
bin/
|
|
21
|
+
parts/
|
|
22
|
+
sdist/
|
|
23
|
+
var/
|
|
24
|
+
wheels/
|
|
25
|
+
share/python-wheels/
|
|
26
|
+
*.egg-info/
|
|
27
|
+
.installed.cfg
|
|
28
|
+
*.egg
|
|
29
|
+
MANIFEST
|
|
30
|
+
|
|
31
|
+
# PyInstaller
|
|
32
|
+
# Usually these files are written by a python script from a template
|
|
33
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
34
|
+
*.manifest
|
|
35
|
+
*.spec
|
|
36
|
+
|
|
37
|
+
# Installer logs
|
|
38
|
+
pip-log.txt
|
|
39
|
+
pip-delete-this-directory.txt
|
|
40
|
+
|
|
41
|
+
# Unit test / coverage reports
|
|
42
|
+
htmlcov/
|
|
43
|
+
.tox/
|
|
44
|
+
.nox/
|
|
45
|
+
.coverage
|
|
46
|
+
.coverage.*
|
|
47
|
+
.cache
|
|
48
|
+
nosetests.xml
|
|
49
|
+
coverage.xml
|
|
50
|
+
*.cover
|
|
51
|
+
*.py,cover
|
|
52
|
+
.hypothesis/
|
|
53
|
+
.pytest_cache/
|
|
54
|
+
cover/
|
|
55
|
+
|
|
56
|
+
# Translations
|
|
57
|
+
*.mo
|
|
58
|
+
*.pot
|
|
59
|
+
|
|
60
|
+
# Django stuff:
|
|
61
|
+
*.log
|
|
62
|
+
local_settings.py
|
|
63
|
+
db.sqlite3
|
|
64
|
+
db.sqlite3-journal
|
|
65
|
+
|
|
66
|
+
# Flask stuff:
|
|
67
|
+
instance/
|
|
68
|
+
.webassets-cache
|
|
69
|
+
|
|
70
|
+
# Scrapy stuff:
|
|
71
|
+
.scrapy
|
|
72
|
+
|
|
73
|
+
# Sphinx documentation
|
|
74
|
+
docs/_build/
|
|
75
|
+
|
|
76
|
+
# PyBuilder
|
|
77
|
+
.pybuilder/
|
|
78
|
+
target/
|
|
79
|
+
|
|
80
|
+
# Jupyter Notebook
|
|
81
|
+
.ipynb_checkpoints
|
|
82
|
+
|
|
83
|
+
# IPython
|
|
84
|
+
profile_default/
|
|
85
|
+
ipython_config.py
|
|
86
|
+
|
|
87
|
+
# pyenv
|
|
88
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
89
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
90
|
+
# .python-version
|
|
91
|
+
pyvenv.cfg
|
|
92
|
+
|
|
93
|
+
# pipenv
|
|
94
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
95
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
96
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
97
|
+
# install all needed dependencies.
|
|
98
|
+
#Pipfile.lock
|
|
99
|
+
|
|
100
|
+
# poetry
|
|
101
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
102
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
103
|
+
# commonly ignored for libraries.
|
|
104
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
105
|
+
#poetry.lock
|
|
106
|
+
|
|
107
|
+
# pdm
|
|
108
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
109
|
+
#pdm.lock
|
|
110
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
111
|
+
# in version control.
|
|
112
|
+
# https://pdm.fming.dev/#use-with-ide
|
|
113
|
+
.pdm.toml
|
|
114
|
+
|
|
115
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
116
|
+
__pypackages__/
|
|
117
|
+
|
|
118
|
+
# Celery stuff
|
|
119
|
+
celerybeat-schedule
|
|
120
|
+
celerybeat.pid
|
|
121
|
+
|
|
122
|
+
# SageMath parsed files
|
|
123
|
+
*.sage.py
|
|
124
|
+
|
|
125
|
+
# Environments
|
|
126
|
+
.env
|
|
127
|
+
.venv
|
|
128
|
+
env/
|
|
129
|
+
venv/
|
|
130
|
+
ENV/
|
|
131
|
+
env.bak/
|
|
132
|
+
venv.bak/
|
|
133
|
+
|
|
134
|
+
# Spyder project settings
|
|
135
|
+
.spyderproject
|
|
136
|
+
.spyproject
|
|
137
|
+
|
|
138
|
+
# Rope project settings
|
|
139
|
+
.ropeproject
|
|
140
|
+
|
|
141
|
+
# mkdocs documentation
|
|
142
|
+
/site
|
|
143
|
+
|
|
144
|
+
# mypy
|
|
145
|
+
.mypy_cache/
|
|
146
|
+
.dmypy.json
|
|
147
|
+
dmypy.json
|
|
148
|
+
|
|
149
|
+
# Pyre type checker
|
|
150
|
+
.pyre/
|
|
151
|
+
|
|
152
|
+
# pytype static type analyzer
|
|
153
|
+
.pytype/
|
|
154
|
+
|
|
155
|
+
# Cython debug symbols
|
|
156
|
+
cython_debug/
|
|
157
|
+
|
|
158
|
+
# PyCharm
|
|
159
|
+
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
|
160
|
+
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
|
161
|
+
|
|
162
|
+
# User-specific stuff
|
|
163
|
+
.idea/**/workspace.xml
|
|
164
|
+
.idea/**/tasks.xml
|
|
165
|
+
.idea/**/usage.statistics.xml
|
|
166
|
+
.idea/**/dictionaries
|
|
167
|
+
.idea/**/shelf
|
|
168
|
+
|
|
169
|
+
# AWS User-specific
|
|
170
|
+
.idea/**/aws.xml
|
|
171
|
+
|
|
172
|
+
# Generated files
|
|
173
|
+
.idea/**/contentModel.xml
|
|
174
|
+
|
|
175
|
+
# Sensitive or high-churn files
|
|
176
|
+
.idea/**/dataSources/
|
|
177
|
+
.idea/**/dataSources.ids
|
|
178
|
+
.idea/**/dataSources.local.xml
|
|
179
|
+
.idea/**/sqlDataSources.xml
|
|
180
|
+
.idea/**/dynamic.xml
|
|
181
|
+
.idea/**/uiDesigner.xml
|
|
182
|
+
.idea/**/dbnavigator.xml
|
|
183
|
+
|
|
184
|
+
# Gradle
|
|
185
|
+
.idea/**/gradle.xml
|
|
186
|
+
.idea/**/libraries
|
|
187
|
+
|
|
188
|
+
# Gradle and Maven with auto-import
|
|
189
|
+
# When using Gradle or Maven with auto-import, you should exclude module files,
|
|
190
|
+
# since they will be recreated, and may cause churn. Uncomment if using
|
|
191
|
+
# auto-import.
|
|
192
|
+
# .idea/artifacts
|
|
193
|
+
# .idea/compiler.xml
|
|
194
|
+
# .idea/jarRepositories.xml
|
|
195
|
+
# .idea/modules.xml
|
|
196
|
+
# .idea/*.iml
|
|
197
|
+
# .idea/modules
|
|
198
|
+
# *.iml
|
|
199
|
+
# *.ipr
|
|
200
|
+
|
|
201
|
+
# CMake
|
|
202
|
+
cmake-build-*/
|
|
203
|
+
|
|
204
|
+
# Mongo Explorer plugin
|
|
205
|
+
.idea/**/mongoSettings.xml
|
|
206
|
+
|
|
207
|
+
# File-based project format
|
|
208
|
+
*.iws
|
|
209
|
+
|
|
210
|
+
# IntelliJ
|
|
211
|
+
out/
|
|
212
|
+
|
|
213
|
+
# mpeltonen/sbt-idea plugin
|
|
214
|
+
.idea_modules/
|
|
215
|
+
|
|
216
|
+
# JIRA plugin
|
|
217
|
+
atlassian-ide-plugin.xml
|
|
218
|
+
|
|
219
|
+
# Cursive Clojure plugin
|
|
220
|
+
.idea/replstate.xml
|
|
221
|
+
|
|
222
|
+
# SonarLint plugin
|
|
223
|
+
.idea/sonarlint/
|
|
224
|
+
|
|
225
|
+
# Crashlytics plugin (for Android Studio and IntelliJ)
|
|
226
|
+
com_crashlytics_export_strings.xml
|
|
227
|
+
crashlytics.properties
|
|
228
|
+
crashlytics-build.properties
|
|
229
|
+
fabric.properties
|
|
230
|
+
|
|
231
|
+
# Editor-based Rest Client
|
|
232
|
+
.idea/httpRequests
|
|
233
|
+
|
|
234
|
+
# Android studio 3.1+ serialized cache file
|
|
235
|
+
.idea/caches/build_file_checksums.ser
|
|
236
|
+
scripts.txt
|
|
237
|
+
.idea
|
|
@@ -1,34 +1,29 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: pymammotion
|
|
3
|
-
Version: 0.5.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Requires-Python:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Requires-Dist:
|
|
15
|
-
Requires-Dist:
|
|
16
|
-
Requires-Dist:
|
|
17
|
-
Requires-Dist:
|
|
18
|
-
Requires-Dist:
|
|
19
|
-
Requires-Dist:
|
|
20
|
-
Requires-Dist:
|
|
21
|
-
Requires-Dist:
|
|
22
|
-
Requires-Dist:
|
|
23
|
-
Requires-Dist:
|
|
24
|
-
Requires-Dist:
|
|
25
|
-
Requires-Dist: jsonic
|
|
26
|
-
Requires-Dist:
|
|
27
|
-
Requires-Dist: numpy (>=1.26.0)
|
|
28
|
-
Requires-Dist: orjson (>=3.9.15,<4.0.0)
|
|
29
|
-
Requires-Dist: paho-mqtt (>=2.1.0,<3.0.0)
|
|
30
|
-
Requires-Dist: protobuf (>=4.23.1)
|
|
31
|
-
Requires-Dist: py-jsonic (>=0.0.2,<0.0.3)
|
|
3
|
+
Version: 0.5.40
|
|
4
|
+
Author: jLynx
|
|
5
|
+
Author-email: Michael Arthur <michael@jumblesoft.co.nz>
|
|
6
|
+
License-Expression: GPL-3.0
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Python: <4.0,>=3.12
|
|
9
|
+
Requires-Dist: aiohttp>=3.9.1
|
|
10
|
+
Requires-Dist: alibabacloud-apigateway-util<0.0.3,>=0.0.2
|
|
11
|
+
Requires-Dist: alibabacloud-iot-api-gateway<0.0.5,>=0.0.4
|
|
12
|
+
Requires-Dist: alicloud-gateway-iot<2,>=1.0.0
|
|
13
|
+
Requires-Dist: async-timeout<5,>=4.0.3
|
|
14
|
+
Requires-Dist: betterproto2<0.9,>=0.8.0
|
|
15
|
+
Requires-Dist: bleak-retry-connector>=3.5.0
|
|
16
|
+
Requires-Dist: bleak>=0.21.0
|
|
17
|
+
Requires-Dist: crcmod~=1.7
|
|
18
|
+
Requires-Dist: cryptography>=43.0.1
|
|
19
|
+
Requires-Dist: jsonic<2,>=1.0.0
|
|
20
|
+
Requires-Dist: mashumaro~=3.13
|
|
21
|
+
Requires-Dist: numpy>=1.26.0
|
|
22
|
+
Requires-Dist: orjson<4,>=3.9.15
|
|
23
|
+
Requires-Dist: paho-mqtt<3,>=2.1.0
|
|
24
|
+
Requires-Dist: protobuf>=4.23.1
|
|
25
|
+
Requires-Dist: py-jsonic<0.0.3,>=0.0.2
|
|
26
|
+
Requires-Dist: pyjwt>=2.10.1
|
|
32
27
|
Description-Content-Type: text/markdown
|
|
33
28
|
|
|
34
29
|
# PyMammotion - Python API for Mammotion Mowers [](https://discord.gg/vpZdWhJX8x)
|
|
@@ -97,4 +92,3 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
97
92
|
|
|
98
93
|
The trademarks "Mammotion," "Luba," and "Yuka" referenced herein are registered trademarks of their respective owners. The author of this software repository is not affiliated with, endorsed by, or connected to these trademark owners in any way.
|
|
99
94
|
|
|
100
|
-
|
|
@@ -15,12 +15,12 @@ from pymammotion.bluetooth.ble import MammotionBLE
|
|
|
15
15
|
from pymammotion.http.http import MammotionHTTP
|
|
16
16
|
|
|
17
17
|
# TODO make a working device that will work outside HA too.
|
|
18
|
-
from pymammotion.mqtt import MammotionMQTT
|
|
18
|
+
from pymammotion.mqtt import AliyunMQTT, MammotionMQTT
|
|
19
19
|
|
|
20
20
|
logger = logging.getLogger(__name__)
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
__all__ = ["MammotionBLE", "MammotionHTTP", "MammotionMQTT", "logger"]
|
|
23
|
+
__all__ = ["MammotionBLE", "MammotionHTTP", "AliyunMQTT", "MammotionMQTT", "logger"]
|
|
24
24
|
|
|
25
25
|
|
|
26
26
|
# TODO provide interface to pick between mqtt/cloud/bluetooth
|
|
@@ -37,7 +37,7 @@ if __name__ == "__main__":
|
|
|
37
37
|
REGION = os.environ.get("REGION")
|
|
38
38
|
mammotion_http = MammotionHTTP()
|
|
39
39
|
cloud_client = CloudIOTGateway(mammotion_http)
|
|
40
|
-
luba =
|
|
40
|
+
luba = AliyunMQTT(
|
|
41
41
|
iot_token=IOT_TOKEN or "",
|
|
42
42
|
region_id=REGION or "",
|
|
43
43
|
product_key=PRODUCT_KEY or "",
|
|
@@ -22,7 +22,7 @@ from Tea.exceptions import UnretryableException
|
|
|
22
22
|
from pymammotion.aliyun.client import Client
|
|
23
23
|
from pymammotion.aliyun.model.aep_response import AepResponse
|
|
24
24
|
from pymammotion.aliyun.model.connect_response import ConnectResponse
|
|
25
|
-
from pymammotion.aliyun.model.dev_by_account_response import
|
|
25
|
+
from pymammotion.aliyun.model.dev_by_account_response import ListingDevAccountResponse
|
|
26
26
|
from pymammotion.aliyun.model.login_by_oauth_response import LoginByOAuthResponse
|
|
27
27
|
from pymammotion.aliyun.model.regions_response import RegionResponse
|
|
28
28
|
from pymammotion.aliyun.model.session_by_authcode_response import SessionByAuthCodeResponse
|
|
@@ -103,6 +103,9 @@ class CheckSessionException(Exception):
|
|
|
103
103
|
"""Raise exception when checking session results in a failure."""
|
|
104
104
|
|
|
105
105
|
|
|
106
|
+
EXPIRED_CREDENTIAL_EXCEPTIONS = (CheckSessionException, SetupException)
|
|
107
|
+
|
|
108
|
+
|
|
106
109
|
class CloudIOTGateway:
|
|
107
110
|
"""Class for interacting with Aliyun Cloud IoT Gateway."""
|
|
108
111
|
|
|
@@ -120,7 +123,7 @@ class CloudIOTGateway:
|
|
|
120
123
|
aep_response: AepResponse | None = None,
|
|
121
124
|
session_by_authcode_response: SessionByAuthCodeResponse | None = None,
|
|
122
125
|
region_response: RegionResponse | None = None,
|
|
123
|
-
dev_by_account:
|
|
126
|
+
dev_by_account: ListingDevAccountResponse | None = None,
|
|
124
127
|
) -> None:
|
|
125
128
|
"""Initialize the CloudIOTGateway."""
|
|
126
129
|
self.mammotion_http: MammotionHTTP = mammotion_http
|
|
@@ -146,7 +149,7 @@ class CloudIOTGateway:
|
|
|
146
149
|
)
|
|
147
150
|
|
|
148
151
|
@staticmethod
|
|
149
|
-
def generate_random_string(length: int):
|
|
152
|
+
def generate_random_string(length: int) -> str:
|
|
150
153
|
"""Generate a random string of specified length."""
|
|
151
154
|
characters = string.ascii_letters + string.digits
|
|
152
155
|
return "".join(random.choice(characters) for _ in range(length))
|
|
@@ -165,7 +168,7 @@ class CloudIOTGateway:
|
|
|
165
168
|
logger.error("Couldn't decode message %s", response_body_str)
|
|
166
169
|
return {"code": 22000}
|
|
167
170
|
|
|
168
|
-
def sign(self, data):
|
|
171
|
+
def sign(self, data: dict) -> str:
|
|
169
172
|
"""Generate signature for the given data."""
|
|
170
173
|
keys = ["appKey", "clientId", "deviceSn", "timestamp"]
|
|
171
174
|
concatenated_str = ""
|
|
@@ -180,7 +183,7 @@ class CloudIOTGateway:
|
|
|
180
183
|
hashlib.sha1,
|
|
181
184
|
).hexdigest()
|
|
182
185
|
|
|
183
|
-
async def get_region(self, country_code: str):
|
|
186
|
+
async def get_region(self, country_code: str) -> RegionResponse:
|
|
184
187
|
"""Get the region based on country code and auth code."""
|
|
185
188
|
auth_code = self.mammotion_http.login_info.authorization_code
|
|
186
189
|
|
|
@@ -244,7 +247,7 @@ class CloudIOTGateway:
|
|
|
244
247
|
|
|
245
248
|
return response.body
|
|
246
249
|
|
|
247
|
-
async def aep_handle(self):
|
|
250
|
+
async def aep_handle(self) -> AepResponse:
|
|
248
251
|
"""Handle AEP authentication."""
|
|
249
252
|
aep_domain = self.domain
|
|
250
253
|
|
|
@@ -300,9 +303,9 @@ class CloudIOTGateway:
|
|
|
300
303
|
|
|
301
304
|
logger.debug(response_body_dict)
|
|
302
305
|
|
|
303
|
-
return
|
|
306
|
+
return self._aep_response
|
|
304
307
|
|
|
305
|
-
async def connect(self):
|
|
308
|
+
async def connect(self) -> ConnectResponse:
|
|
306
309
|
"""Connect to the Aliyun Cloud IoT Gateway."""
|
|
307
310
|
region_url = "sdk.openaccount.aliyun.com"
|
|
308
311
|
time_now = time.time()
|
|
@@ -449,7 +452,7 @@ class CloudIOTGateway:
|
|
|
449
452
|
return self._login_by_oauth_response
|
|
450
453
|
raise LoginException(data)
|
|
451
454
|
|
|
452
|
-
async def session_by_auth_code(self):
|
|
455
|
+
async def session_by_auth_code(self) -> SessionByAuthCodeResponse:
|
|
453
456
|
"""Create a session by auth code."""
|
|
454
457
|
config = Config(
|
|
455
458
|
app_key=self._app_key,
|
|
@@ -608,7 +611,8 @@ class CloudIOTGateway:
|
|
|
608
611
|
session_data = session.data
|
|
609
612
|
|
|
610
613
|
if (
|
|
611
|
-
session_data
|
|
614
|
+
session_data is None
|
|
615
|
+
or session_data.identityId is None
|
|
612
616
|
or session_data.refreshTokenExpire is None
|
|
613
617
|
or session_data.iotToken is None
|
|
614
618
|
or session_data.iotTokenExpire is None
|
|
@@ -619,7 +623,7 @@ class CloudIOTGateway:
|
|
|
619
623
|
self._session_by_authcode_response = session
|
|
620
624
|
self._iot_token_issued_at = int(time.time())
|
|
621
625
|
|
|
622
|
-
async def list_binding_by_account(self) ->
|
|
626
|
+
async def list_binding_by_account(self) -> ListingDevAccountResponse:
|
|
623
627
|
"""List bindings by account."""
|
|
624
628
|
config = Config(
|
|
625
629
|
app_key=self._app_key,
|
|
@@ -658,9 +662,9 @@ class CloudIOTGateway:
|
|
|
658
662
|
response_body_dict = self.parse_json_response(response_body_str)
|
|
659
663
|
|
|
660
664
|
if int(response_body_dict.get("code")) != 200:
|
|
661
|
-
raise Exception("Error in creating session: " + response_body_dict["
|
|
665
|
+
raise Exception("Error in creating session: " + response_body_dict["message"])
|
|
662
666
|
|
|
663
|
-
self._devices_by_account_response =
|
|
667
|
+
self._devices_by_account_response = ListingDevAccountResponse.from_dict(response_body_dict)
|
|
664
668
|
return self._devices_by_account_response
|
|
665
669
|
|
|
666
670
|
async def list_binding_by_dev(self, iot_id: str):
|
|
@@ -698,10 +702,94 @@ class CloudIOTGateway:
|
|
|
698
702
|
# Load the JSON string into a dictionary
|
|
699
703
|
response_body_dict = self.parse_json_response(response_body_str)
|
|
700
704
|
|
|
705
|
+
if int(response_body_dict.get("code")) != 200:
|
|
706
|
+
raise Exception("Error in getting shared device list: " + response_body_dict["msg"])
|
|
707
|
+
|
|
708
|
+
self._devices_by_account_response = ListingDevAccountResponse.from_dict(response_body_dict)
|
|
709
|
+
return self._devices_by_account_response
|
|
710
|
+
|
|
711
|
+
async def confirm_share(self, record_list: list[str]) -> bool:
|
|
712
|
+
config = Config(
|
|
713
|
+
app_key=self._app_key,
|
|
714
|
+
app_secret=self._app_secret,
|
|
715
|
+
domain=self._region_response.data.apiGatewayEndpoint,
|
|
716
|
+
)
|
|
717
|
+
|
|
718
|
+
client = Client(config)
|
|
719
|
+
|
|
720
|
+
# build request
|
|
721
|
+
request = CommonParams(
|
|
722
|
+
api_ver="1.0.7",
|
|
723
|
+
language="en-US",
|
|
724
|
+
iot_token=self._session_by_authcode_response.data.iotToken,
|
|
725
|
+
)
|
|
726
|
+
body = IoTApiRequest(
|
|
727
|
+
id=str(uuid.uuid4()),
|
|
728
|
+
params={"agree": 1, "recordIdList": record_list},
|
|
729
|
+
request=request,
|
|
730
|
+
version="1.0",
|
|
731
|
+
)
|
|
732
|
+
|
|
733
|
+
# send request
|
|
734
|
+
response = await client.async_do_request("/uc/confirmShare", "https", "POST", None, body, RuntimeOptions())
|
|
735
|
+
logger.debug(response.status_message)
|
|
736
|
+
logger.debug(response.headers)
|
|
737
|
+
logger.debug(response.status_code)
|
|
738
|
+
logger.debug(response.body)
|
|
739
|
+
|
|
740
|
+
# Decode the response body
|
|
741
|
+
response_body_str = response.body.decode("utf-8")
|
|
742
|
+
|
|
743
|
+
# Load the JSON string into a dictionary
|
|
744
|
+
response_body_dict = self.parse_json_response(response_body_str)
|
|
745
|
+
|
|
746
|
+
if int(response_body_dict.get("code")) != 200:
|
|
747
|
+
raise Exception("Error in accepting share: " + response_body_dict["msg"])
|
|
748
|
+
|
|
749
|
+
return True
|
|
750
|
+
|
|
751
|
+
async def get_shared_notice_list(self):
|
|
752
|
+
### status 0 accepted status -1 ready to be accepted 3 expired
|
|
753
|
+
config = Config(
|
|
754
|
+
app_key=self._app_key,
|
|
755
|
+
app_secret=self._app_secret,
|
|
756
|
+
domain=self._region_response.data.apiGatewayEndpoint,
|
|
757
|
+
)
|
|
758
|
+
|
|
759
|
+
client = Client(config)
|
|
760
|
+
|
|
761
|
+
# build request
|
|
762
|
+
request = CommonParams(
|
|
763
|
+
api_ver="1.0.9",
|
|
764
|
+
language="en-US",
|
|
765
|
+
iot_token=self._session_by_authcode_response.data.iotToken,
|
|
766
|
+
)
|
|
767
|
+
body = IoTApiRequest(
|
|
768
|
+
id=str(uuid.uuid4()),
|
|
769
|
+
params={"pageSize": 100, "pageNo": 1},
|
|
770
|
+
request=request,
|
|
771
|
+
version="1.0",
|
|
772
|
+
)
|
|
773
|
+
|
|
774
|
+
# send request
|
|
775
|
+
response = await client.async_do_request(
|
|
776
|
+
"/uc/getShareNoticeList", "https", "POST", None, body, RuntimeOptions()
|
|
777
|
+
)
|
|
778
|
+
logger.debug(response.status_message)
|
|
779
|
+
logger.debug(response.headers)
|
|
780
|
+
logger.debug(response.status_code)
|
|
781
|
+
logger.debug(response.body)
|
|
782
|
+
|
|
783
|
+
# Decode the response body
|
|
784
|
+
response_body_str = response.body.decode("utf-8")
|
|
785
|
+
|
|
786
|
+
# Load the JSON string into a dictionary
|
|
787
|
+
response_body_dict = self.parse_json_response(response_body_str)
|
|
788
|
+
|
|
701
789
|
if int(response_body_dict.get("code")) != 200:
|
|
702
790
|
raise Exception("Error in creating session: " + response_body_dict["msg"])
|
|
703
791
|
|
|
704
|
-
self._devices_by_account_response =
|
|
792
|
+
self._devices_by_account_response = ListingDevAccountResponse.from_dict(response_body_dict)
|
|
705
793
|
return self._devices_by_account_response
|
|
706
794
|
|
|
707
795
|
async def send_cloud_command(self, iot_id: str, command: bytes) -> str:
|
|
@@ -867,11 +955,11 @@ class CloudIOTGateway:
|
|
|
867
955
|
self.mammotion_http = mammotion_http
|
|
868
956
|
|
|
869
957
|
@property
|
|
870
|
-
def region_response(self) -> RegionResponse:
|
|
958
|
+
def region_response(self) -> RegionResponse | None:
|
|
871
959
|
return self._region_response
|
|
872
960
|
|
|
873
961
|
@property
|
|
874
|
-
def aep_response(self) -> AepResponse:
|
|
962
|
+
def aep_response(self) -> AepResponse | None:
|
|
875
963
|
return self._aep_response
|
|
876
964
|
|
|
877
965
|
@property
|
|
@@ -883,9 +971,9 @@ class CloudIOTGateway:
|
|
|
883
971
|
return self._client_id
|
|
884
972
|
|
|
885
973
|
@property
|
|
886
|
-
def login_by_oauth_response(self) -> LoginByOAuthResponse:
|
|
974
|
+
def login_by_oauth_response(self) -> LoginByOAuthResponse | None:
|
|
887
975
|
return self._login_by_oauth_response
|
|
888
976
|
|
|
889
977
|
@property
|
|
890
|
-
def connect_response(self) -> ConnectResponse:
|
|
978
|
+
def connect_response(self) -> ConnectResponse | None:
|
|
891
979
|
return self._connect_response
|