pymammotion 0.4.0a2__py3-none-any.whl → 0.5.51__py3-none-any.whl
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/__init__.py +5 -4
- pymammotion/aliyun/client.py +235 -0
- pymammotion/aliyun/cloud_gateway.py +312 -64
- pymammotion/aliyun/model/aep_response.py +1 -2
- pymammotion/aliyun/model/dev_by_account_response.py +170 -23
- pymammotion/aliyun/model/login_by_oauth_response.py +2 -3
- pymammotion/aliyun/model/regions_response.py +3 -3
- pymammotion/aliyun/model/session_by_authcode_response.py +2 -2
- pymammotion/aliyun/model/thing_response.py +12 -0
- pymammotion/aliyun/regions.py +62 -0
- pymammotion/aliyun/tea/core.py +297 -0
- pymammotion/bluetooth/ble.py +7 -9
- pymammotion/bluetooth/ble_message.py +10 -14
- pymammotion/const.py +3 -0
- pymammotion/data/model/__init__.py +1 -2
- pymammotion/data/model/device.py +95 -27
- pymammotion/data/model/device_config.py +4 -4
- pymammotion/data/model/device_info.py +35 -0
- pymammotion/data/model/device_limits.py +10 -10
- pymammotion/data/model/enums.py +12 -2
- pymammotion/data/model/errors.py +12 -0
- pymammotion/data/model/events.py +14 -0
- pymammotion/data/model/generate_geojson.py +521 -0
- pymammotion/data/model/generate_route_information.py +2 -2
- pymammotion/data/model/hash_list.py +370 -57
- pymammotion/data/model/location.py +4 -4
- pymammotion/data/model/mowing_modes.py +17 -1
- pymammotion/data/model/raw_data.py +2 -10
- pymammotion/data/model/region_data.py +10 -11
- pymammotion/data/model/report_info.py +31 -5
- pymammotion/data/model/work.py +27 -0
- pymammotion/data/mower_state_manager.py +316 -0
- pymammotion/data/mqtt/event.py +73 -28
- pymammotion/data/mqtt/mammotion_properties.py +257 -0
- pymammotion/data/mqtt/properties.py +93 -78
- pymammotion/data/mqtt/status.py +18 -17
- pymammotion/event/event.py +27 -6
- pymammotion/homeassistant/__init__.py +3 -0
- pymammotion/homeassistant/mower_api.py +484 -0
- pymammotion/homeassistant/rtk_api.py +54 -0
- pymammotion/http/encryption.py +5 -6
- pymammotion/http/http.py +574 -28
- pymammotion/http/model/__init__.py +0 -0
- pymammotion/{aliyun/model/stream_subscription_response.py → http/model/camera_stream.py} +14 -2
- pymammotion/http/model/http.py +129 -4
- pymammotion/http/model/response_factory.py +61 -0
- pymammotion/http/model/rtk.py +16 -0
- pymammotion/mammotion/commands/abstract_message.py +7 -5
- pymammotion/mammotion/commands/mammotion_command.py +30 -1
- pymammotion/mammotion/commands/messages/basestation.py +43 -0
- pymammotion/mammotion/commands/messages/driver.py +61 -29
- pymammotion/mammotion/commands/messages/media.py +68 -15
- pymammotion/mammotion/commands/messages/navigation.py +61 -25
- pymammotion/mammotion/commands/messages/network.py +17 -23
- pymammotion/mammotion/commands/messages/ota.py +18 -18
- pymammotion/mammotion/commands/messages/system.py +32 -49
- pymammotion/mammotion/commands/messages/video.py +15 -16
- pymammotion/mammotion/devices/__init__.py +27 -3
- pymammotion/mammotion/devices/base.py +40 -131
- pymammotion/mammotion/devices/mammotion.py +436 -201
- pymammotion/mammotion/devices/mammotion_bluetooth.py +57 -47
- pymammotion/mammotion/devices/mammotion_cloud.py +134 -105
- pymammotion/mammotion/devices/mammotion_mower_ble.py +49 -0
- pymammotion/mammotion/devices/mammotion_mower_cloud.py +39 -0
- pymammotion/mammotion/devices/managers/managers.py +81 -0
- pymammotion/mammotion/devices/mower_device.py +124 -0
- pymammotion/mammotion/devices/mower_manager.py +107 -0
- pymammotion/mammotion/devices/rtk_ble.py +89 -0
- pymammotion/mammotion/devices/rtk_cloud.py +113 -0
- pymammotion/mammotion/devices/rtk_device.py +50 -0
- pymammotion/mammotion/devices/rtk_manager.py +122 -0
- pymammotion/mqtt/__init__.py +2 -1
- pymammotion/mqtt/aliyun_mqtt.py +232 -0
- pymammotion/mqtt/linkkit/__init__.py +5 -0
- pymammotion/mqtt/linkkit/h2client.py +585 -0
- pymammotion/mqtt/linkkit/linkkit.py +3023 -0
- pymammotion/mqtt/mammotion_mqtt.py +176 -169
- pymammotion/mqtt/mqtt_models.py +66 -0
- pymammotion/proto/__init__.py +4839 -4
- pymammotion/proto/basestation.proto +8 -0
- pymammotion/proto/basestation_pb2.py +11 -9
- pymammotion/proto/basestation_pb2.pyi +16 -2
- pymammotion/proto/dev_net.proto +79 -55
- pymammotion/proto/dev_net_pb2.py +60 -56
- pymammotion/proto/dev_net_pb2.pyi +49 -6
- pymammotion/proto/luba_msg.proto +2 -1
- pymammotion/proto/luba_msg_pb2.py +6 -6
- pymammotion/proto/luba_msg_pb2.pyi +1 -0
- pymammotion/proto/luba_mul.proto +62 -1
- pymammotion/proto/luba_mul_pb2.py +38 -22
- pymammotion/proto/luba_mul_pb2.pyi +94 -7
- pymammotion/proto/mctrl_driver.proto +44 -4
- pymammotion/proto/mctrl_driver_pb2.py +26 -14
- pymammotion/proto/mctrl_driver_pb2.pyi +66 -11
- pymammotion/proto/mctrl_nav.proto +93 -52
- pymammotion/proto/mctrl_nav_pb2.py +75 -67
- pymammotion/proto/mctrl_nav_pb2.pyi +142 -56
- pymammotion/proto/mctrl_ota.proto +40 -2
- pymammotion/proto/mctrl_ota_pb2.py +23 -13
- pymammotion/proto/mctrl_ota_pb2.pyi +67 -4
- pymammotion/proto/mctrl_pept.proto +8 -3
- pymammotion/proto/mctrl_pept_pb2.py +8 -6
- pymammotion/proto/mctrl_pept_pb2.pyi +14 -6
- pymammotion/proto/mctrl_sys.proto +325 -86
- pymammotion/proto/mctrl_sys_pb2.py +162 -98
- pymammotion/proto/mctrl_sys_pb2.pyi +451 -25
- pymammotion/proto/message_pool.py +3 -0
- pymammotion/proto/py.typed +0 -0
- pymammotion/utility/constant/device_constant.py +29 -5
- pymammotion/utility/datatype_converter.py +13 -12
- pymammotion/utility/device_config.py +522 -130
- pymammotion/utility/device_type.py +218 -21
- pymammotion/utility/map.py +238 -51
- pymammotion/utility/mur_mur_hash.py +159 -0
- {pymammotion-0.4.0a2.dist-info → pymammotion-0.5.51.dist-info}/METADATA +26 -31
- pymammotion-0.5.51.dist-info/RECORD +152 -0
- {pymammotion-0.4.0a2.dist-info → pymammotion-0.5.51.dist-info}/WHEEL +1 -1
- pymammotion/aliyun/cloud_service.py +0 -65
- pymammotion/data/model/plan.py +0 -58
- pymammotion/data/state_manager.py +0 -129
- pymammotion/proto/basestation.py +0 -59
- pymammotion/proto/common.py +0 -12
- pymammotion/proto/dev_net.py +0 -381
- pymammotion/proto/luba_msg.py +0 -81
- pymammotion/proto/luba_mul.py +0 -76
- pymammotion/proto/mctrl_driver.py +0 -100
- pymammotion/proto/mctrl_nav.py +0 -664
- pymammotion/proto/mctrl_ota.py +0 -48
- pymammotion/proto/mctrl_pept.py +0 -41
- pymammotion/proto/mctrl_sys.py +0 -574
- pymammotion-0.4.0a2.dist-info/RECORD +0 -131
- /pymammotion/http/{_init_.py → __init__.py} +0 -0
- {pymammotion-0.4.0a2.dist-info → pymammotion-0.5.51.dist-info/licenses}/LICENSE +0 -0
pymammotion/__init__.py
CHANGED
|
@@ -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
|
|
@@ -35,8 +35,9 @@ if __name__ == "__main__":
|
|
|
35
35
|
CLIENT_ID = os.environ.get("CLIENT_ID")
|
|
36
36
|
IOT_TOKEN = os.environ.get("IOT_TOKEN")
|
|
37
37
|
REGION = os.environ.get("REGION")
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
mammotion_http = MammotionHTTP()
|
|
39
|
+
cloud_client = CloudIOTGateway(mammotion_http)
|
|
40
|
+
luba = AliyunMQTT(
|
|
40
41
|
iot_token=IOT_TOKEN or "",
|
|
41
42
|
region_id=REGION or "",
|
|
42
43
|
product_key=PRODUCT_KEY or "",
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
from datetime import UTC, datetime
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
from Tea.exceptions import UnretryableException
|
|
5
|
+
from Tea.request import TeaRequest
|
|
6
|
+
|
|
7
|
+
from pymammotion.aliyun.tea.core import TeaCore
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
from typing import Dict
|
|
11
|
+
except ImportError:
|
|
12
|
+
pass
|
|
13
|
+
|
|
14
|
+
from alibabacloud_apigateway_util.client import Client as APIGatewayUtilClient
|
|
15
|
+
from alibabacloud_tea_util.client import Client as UtilClient
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class Client:
|
|
19
|
+
"""test"""
|
|
20
|
+
|
|
21
|
+
_app_key = None # type: str
|
|
22
|
+
_app_secret = None # type: str
|
|
23
|
+
_protocol = None # type: str
|
|
24
|
+
_user_agent = None # type: str
|
|
25
|
+
_read_timeout = None # type: int
|
|
26
|
+
_connect_timeout = None # type: int
|
|
27
|
+
_http_proxy = None # type: str
|
|
28
|
+
_https_proxy = None # type: str
|
|
29
|
+
_no_proxy = None # type: str
|
|
30
|
+
_max_idle_conns = None # type: int
|
|
31
|
+
_domain = None # type: str
|
|
32
|
+
|
|
33
|
+
def __init__(self, config) -> None:
|
|
34
|
+
self._domain = config.domain
|
|
35
|
+
self._app_key = config.app_key
|
|
36
|
+
self._app_secret = config.app_secret
|
|
37
|
+
self._protocol = config.protocol
|
|
38
|
+
self._read_timeout = config.read_timeout
|
|
39
|
+
self._connect_timeout = config.connect_timeout
|
|
40
|
+
self._http_proxy = config.http_proxy
|
|
41
|
+
self._https_proxy = config.https_proxy
|
|
42
|
+
self._no_proxy = config.no_proxy
|
|
43
|
+
self._max_idle_conns = config.max_idle_conns
|
|
44
|
+
|
|
45
|
+
def do_request(self, pathname, protocol, method, header, body, runtime):
|
|
46
|
+
"""Send request
|
|
47
|
+
|
|
48
|
+
@type pathname: str
|
|
49
|
+
@param pathname: the url path
|
|
50
|
+
|
|
51
|
+
@type protocol: str
|
|
52
|
+
@param protocol: http or https
|
|
53
|
+
|
|
54
|
+
@type method: str
|
|
55
|
+
@param method: example GET
|
|
56
|
+
|
|
57
|
+
@type header: Dict[str, str]
|
|
58
|
+
@param header: request header
|
|
59
|
+
|
|
60
|
+
@type body: iot_api_gateway_models.IoTApiRequest
|
|
61
|
+
@param body: the object of IoTApiRequest
|
|
62
|
+
|
|
63
|
+
@type runtime: util_models.RuntimeOptions
|
|
64
|
+
@param runtime: which controls some details of call api, such as retry times
|
|
65
|
+
|
|
66
|
+
@rtype: TeaResponse
|
|
67
|
+
@return: the response
|
|
68
|
+
"""
|
|
69
|
+
body.validate()
|
|
70
|
+
runtime.validate()
|
|
71
|
+
_runtime = {
|
|
72
|
+
"timeouted": "retry",
|
|
73
|
+
"readTimeout": UtilClient.default_number(runtime.read_timeout, self._read_timeout),
|
|
74
|
+
"connectTimeout": UtilClient.default_number(runtime.connect_timeout, self._connect_timeout),
|
|
75
|
+
"httpProxy": UtilClient.default_string(runtime.http_proxy, self._http_proxy),
|
|
76
|
+
"httpsProxy": UtilClient.default_string(runtime.https_proxy, self._https_proxy),
|
|
77
|
+
"noProxy": UtilClient.default_string(runtime.no_proxy, self._no_proxy),
|
|
78
|
+
"maxIdleConns": UtilClient.default_number(runtime.max_idle_conns, self._max_idle_conns),
|
|
79
|
+
"retry": {
|
|
80
|
+
"retryable": runtime.autoretry,
|
|
81
|
+
"maxAttempts": UtilClient.default_number(runtime.max_attempts, 3),
|
|
82
|
+
},
|
|
83
|
+
"backoff": {
|
|
84
|
+
"policy": UtilClient.default_string(runtime.backoff_policy, "yes"),
|
|
85
|
+
"period": UtilClient.default_number(runtime.backoff_period, 1),
|
|
86
|
+
},
|
|
87
|
+
"ignoreSSL": runtime.ignore_ssl,
|
|
88
|
+
}
|
|
89
|
+
_last_request = None
|
|
90
|
+
_last_exception = None
|
|
91
|
+
_now = time.time()
|
|
92
|
+
_retry_times = 0
|
|
93
|
+
while TeaCore.allow_retry(_runtime.get("retry"), _retry_times, _now):
|
|
94
|
+
if _retry_times > 0:
|
|
95
|
+
_backoff_time = TeaCore.get_backoff_time(_runtime.get("backoff"), _retry_times)
|
|
96
|
+
if _backoff_time > 0:
|
|
97
|
+
TeaCore.sleep(_backoff_time)
|
|
98
|
+
_retry_times = _retry_times + 1
|
|
99
|
+
try:
|
|
100
|
+
_request = TeaRequest()
|
|
101
|
+
_request.protocol = UtilClient.default_string(self._protocol, protocol)
|
|
102
|
+
_request.method = UtilClient.default_string(method, "POST")
|
|
103
|
+
_request.pathname = pathname
|
|
104
|
+
_request.headers = TeaCore.merge(
|
|
105
|
+
{
|
|
106
|
+
"host": self._domain,
|
|
107
|
+
"date": datetime.now(UTC).strftime("%a, %d %b %Y %H:%M:%S GMT"),
|
|
108
|
+
"x-ca-nonce": UtilClient.get_nonce(),
|
|
109
|
+
"x-ca-key": self._app_key,
|
|
110
|
+
"x-ca-signaturemethod": "HmacSHA256",
|
|
111
|
+
"accept": "application/json",
|
|
112
|
+
"user-agent": self.get_user_agent(),
|
|
113
|
+
},
|
|
114
|
+
header,
|
|
115
|
+
)
|
|
116
|
+
if UtilClient.empty(body.id):
|
|
117
|
+
body.id = UtilClient.get_nonce()
|
|
118
|
+
if not UtilClient.is_unset(body):
|
|
119
|
+
_request.headers["content-type"] = "application/octet-stream"
|
|
120
|
+
_request.headers["content-md5"] = APIGatewayUtilClient.get_content_md5(
|
|
121
|
+
UtilClient.to_jsonstring(TeaCore.to_map(body))
|
|
122
|
+
)
|
|
123
|
+
_request.body = UtilClient.to_jsonstring(TeaCore.to_map(body))
|
|
124
|
+
_request.headers["x-ca-signature"] = APIGatewayUtilClient.get_signature(_request, self._app_secret)
|
|
125
|
+
_last_request = _request
|
|
126
|
+
_response = TeaCore.do_action(_request, _runtime)
|
|
127
|
+
if _response.body.get("code") == 20056:
|
|
128
|
+
raise Exception("Gateway timeout.")
|
|
129
|
+
|
|
130
|
+
return _response
|
|
131
|
+
except Exception as e:
|
|
132
|
+
if TeaCore.is_retryable(e):
|
|
133
|
+
_last_exception = e
|
|
134
|
+
continue
|
|
135
|
+
raise e
|
|
136
|
+
raise UnretryableException(_last_request, _last_exception)
|
|
137
|
+
|
|
138
|
+
async def async_do_request(self, pathname, protocol, method, header, body, runtime):
|
|
139
|
+
"""Send request
|
|
140
|
+
|
|
141
|
+
@type pathname: str
|
|
142
|
+
@param pathname: the url path
|
|
143
|
+
|
|
144
|
+
@type protocol: str
|
|
145
|
+
@param protocol: http or https
|
|
146
|
+
|
|
147
|
+
@type method: str
|
|
148
|
+
@param method: example GET
|
|
149
|
+
|
|
150
|
+
@type header: Dict[str, str]
|
|
151
|
+
@param header: request header
|
|
152
|
+
|
|
153
|
+
@type body: iot_api_gateway_models.IoTApiRequest
|
|
154
|
+
@param body: the object of IoTApiRequest
|
|
155
|
+
|
|
156
|
+
@type runtime: util_models.RuntimeOptions
|
|
157
|
+
@param runtime: which controls some details of call api, such as retry times
|
|
158
|
+
|
|
159
|
+
@rtype: TeaResponse
|
|
160
|
+
@return: the response
|
|
161
|
+
"""
|
|
162
|
+
body.validate()
|
|
163
|
+
runtime.validate()
|
|
164
|
+
_runtime = {
|
|
165
|
+
"timeouted": "retry",
|
|
166
|
+
"readTimeout": UtilClient.default_number(runtime.read_timeout, self._read_timeout),
|
|
167
|
+
"connectTimeout": UtilClient.default_number(runtime.connect_timeout, self._connect_timeout),
|
|
168
|
+
"httpProxy": UtilClient.default_string(runtime.http_proxy, self._http_proxy),
|
|
169
|
+
"httpsProxy": UtilClient.default_string(runtime.https_proxy, self._https_proxy),
|
|
170
|
+
"noProxy": UtilClient.default_string(runtime.no_proxy, self._no_proxy),
|
|
171
|
+
"maxIdleConns": UtilClient.default_number(runtime.max_idle_conns, self._max_idle_conns),
|
|
172
|
+
"retry": {
|
|
173
|
+
"retryable": runtime.autoretry,
|
|
174
|
+
"maxAttempts": UtilClient.default_number(runtime.max_attempts, 3),
|
|
175
|
+
},
|
|
176
|
+
"backoff": {
|
|
177
|
+
"policy": UtilClient.default_string(runtime.backoff_policy, "yes"),
|
|
178
|
+
"period": UtilClient.default_number(runtime.backoff_period, 1),
|
|
179
|
+
},
|
|
180
|
+
"ignoreSSL": runtime.ignore_ssl,
|
|
181
|
+
}
|
|
182
|
+
_last_request = None
|
|
183
|
+
_last_exception = None
|
|
184
|
+
_now = time.time()
|
|
185
|
+
_retry_times = 0
|
|
186
|
+
while TeaCore.allow_retry(_runtime.get("retry"), _retry_times, _now):
|
|
187
|
+
if _retry_times > 0:
|
|
188
|
+
_backoff_time = TeaCore.get_backoff_time(_runtime.get("backoff"), _retry_times)
|
|
189
|
+
if _backoff_time > 0:
|
|
190
|
+
await TeaCore.sleep_async(_backoff_time)
|
|
191
|
+
_retry_times = _retry_times + 1
|
|
192
|
+
try:
|
|
193
|
+
_request = TeaRequest()
|
|
194
|
+
_request.protocol = UtilClient.default_string(self._protocol, protocol)
|
|
195
|
+
_request.method = UtilClient.default_string(method, "POST")
|
|
196
|
+
_request.pathname = pathname
|
|
197
|
+
_request.headers = TeaCore.merge(
|
|
198
|
+
{
|
|
199
|
+
"host": self._domain,
|
|
200
|
+
"date": UtilClient.get_date_utcstring(),
|
|
201
|
+
"x-ca-nonce": UtilClient.get_nonce(),
|
|
202
|
+
"x-ca-key": self._app_key,
|
|
203
|
+
"x-ca-signaturemethod": "HmacSHA256",
|
|
204
|
+
"accept": "application/json",
|
|
205
|
+
"user-agent": self.get_user_agent(),
|
|
206
|
+
},
|
|
207
|
+
header,
|
|
208
|
+
)
|
|
209
|
+
if UtilClient.empty(body.id):
|
|
210
|
+
body.id = UtilClient.get_nonce()
|
|
211
|
+
if not UtilClient.is_unset(body):
|
|
212
|
+
_request.headers["content-type"] = "application/octet-stream"
|
|
213
|
+
_request.headers["content-md5"] = APIGatewayUtilClient.get_content_md5(
|
|
214
|
+
UtilClient.to_jsonstring(TeaCore.to_map(body))
|
|
215
|
+
)
|
|
216
|
+
_request.body = UtilClient.to_jsonstring(TeaCore.to_map(body))
|
|
217
|
+
_request.headers["x-ca-signature"] = APIGatewayUtilClient.get_signature(_request, self._app_secret)
|
|
218
|
+
_last_request = _request
|
|
219
|
+
_response = await TeaCore.async_do_action(_request, _runtime)
|
|
220
|
+
return _response
|
|
221
|
+
except Exception as e:
|
|
222
|
+
if TeaCore.is_retryable(e):
|
|
223
|
+
_last_exception = e
|
|
224
|
+
continue
|
|
225
|
+
raise e
|
|
226
|
+
raise UnretryableException(_last_request, _last_exception)
|
|
227
|
+
|
|
228
|
+
def get_user_agent(self):
|
|
229
|
+
"""Get user agent
|
|
230
|
+
|
|
231
|
+
@rtype: str
|
|
232
|
+
@return: user agent
|
|
233
|
+
"""
|
|
234
|
+
user_agent = UtilClient.get_user_agent(self._user_agent)
|
|
235
|
+
return user_agent
|