pymammotion 0.2.8__py3-none-any.whl → 0.2.10__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/aliyun/cloud_gateway.py +1 -1
- pymammotion/mammotion/devices/mammotion.py +56 -12
- pymammotion/mqtt/mammotion_mqtt.py +3 -2
- {pymammotion-0.2.8.dist-info → pymammotion-0.2.10.dist-info}/METADATA +1 -1
- {pymammotion-0.2.8.dist-info → pymammotion-0.2.10.dist-info}/RECORD +7 -7
- {pymammotion-0.2.8.dist-info → pymammotion-0.2.10.dist-info}/LICENSE +0 -0
- {pymammotion-0.2.8.dist-info → pymammotion-0.2.10.dist-info}/WHEEL +0 -0
|
@@ -71,7 +71,7 @@ class CloudIOTGateway:
|
|
|
71
71
|
|
|
72
72
|
converter = DatatypeConverter()
|
|
73
73
|
|
|
74
|
-
def __init__(self, connect_response: ConnectResponse | None, login_by_oauth_response: LoginByOAuthResponse | None, aep_response: AepResponse | None, session_by_authcode_response: SessionByAuthCodeResponse | None, region_response: RegionResponse | None, dev_by_account: ListingDevByAccountResponse | None):
|
|
74
|
+
def __init__(self, connect_response: ConnectResponse | None = None, login_by_oauth_response: LoginByOAuthResponse | None = None, aep_response: AepResponse | None = None, session_by_authcode_response: SessionByAuthCodeResponse | None = None, region_response: RegionResponse | None = None, dev_by_account: ListingDevByAccountResponse | None = None):
|
|
75
75
|
"""Initialize the CloudIOTGateway."""
|
|
76
76
|
self._app_key = APP_KEY
|
|
77
77
|
self._app_secret = APP_SECRET
|
|
@@ -198,10 +198,11 @@ class MammotionDevices:
|
|
|
198
198
|
async def create_devices(ble_device: BLEDevice,
|
|
199
199
|
cloud_credentials: Credentials | None = None,
|
|
200
200
|
preference: ConnectionPreference = ConnectionPreference.BLUETOOTH):
|
|
201
|
-
cloud_client = await Mammotion.login(cloud_credentials.account_id or cloud_credentials.email, cloud_credentials.password)
|
|
202
201
|
mammotion = Mammotion(ble_device, preference)
|
|
203
202
|
|
|
204
203
|
if cloud_credentials:
|
|
204
|
+
cloud_client = await Mammotion.login(cloud_credentials.account_id or cloud_credentials.email,
|
|
205
|
+
cloud_credentials.password)
|
|
205
206
|
await mammotion.initiate_cloud_connection(cloud_client)
|
|
206
207
|
|
|
207
208
|
return mammotion
|
|
@@ -235,7 +236,7 @@ class Mammotion(object):
|
|
|
235
236
|
return
|
|
236
237
|
|
|
237
238
|
self.cloud_client = cloud_client
|
|
238
|
-
self.mqtt = MammotionMQTT(region_id=cloud_client.
|
|
239
|
+
self.mqtt = MammotionMQTT(region_id=cloud_client._region_response.data.regionId,
|
|
239
240
|
product_key=cloud_client._aep_response.data.productKey,
|
|
240
241
|
device_name=cloud_client._aep_response.data.deviceName,
|
|
241
242
|
device_secret=cloud_client._aep_response.data.deviceSecret,
|
|
@@ -332,8 +333,9 @@ class MammotionBaseDevice:
|
|
|
332
333
|
|
|
333
334
|
_mower: MowingDevice
|
|
334
335
|
_state_manager: StateManager
|
|
336
|
+
_cloud_device: Device | None = None
|
|
335
337
|
|
|
336
|
-
def __init__(self, device: MowingDevice) -> None:
|
|
338
|
+
def __init__(self, device: MowingDevice, cloud_device: Device | None = None) -> None:
|
|
337
339
|
"""Initialize MammotionBaseDevice."""
|
|
338
340
|
self.loop = asyncio.get_event_loop()
|
|
339
341
|
self._raw_data = LubaMsg().to_dict(casing=betterproto.Casing.SNAKE)
|
|
@@ -342,12 +344,13 @@ class MammotionBaseDevice:
|
|
|
342
344
|
self._state_manager.gethash_ack_callback = self.datahash_response
|
|
343
345
|
self._state_manager.get_commondata_ack_callback = self.commdata_response
|
|
344
346
|
self._notify_future: asyncio.Future[bytes] | None = None
|
|
347
|
+
self._cloud_device = cloud_device
|
|
345
348
|
|
|
346
349
|
async def datahash_response(self, hash_ack: NavGetHashListAck):
|
|
347
350
|
"""Handle datahash responses."""
|
|
348
351
|
result_hash = 0
|
|
349
352
|
while hash_ack.data_couple[0] != result_hash:
|
|
350
|
-
data = await self.
|
|
353
|
+
data = await self.queue_command("synchronize_hash_data", hash_num=hash_ack.data_couple[0])
|
|
351
354
|
msg = LubaMsg().parse(data)
|
|
352
355
|
if betterproto.serialized_on_wire(msg.nav.toapp_get_commondata_ack):
|
|
353
356
|
result_hash = msg.nav.toapp_get_commondata_ack.hash
|
|
@@ -365,7 +368,7 @@ class MammotionBaseDevice:
|
|
|
365
368
|
return
|
|
366
369
|
result_hash = 0
|
|
367
370
|
while data_hash != result_hash:
|
|
368
|
-
data = await self.
|
|
371
|
+
data = await self.queue_command("synchronize_hash_data", hash_num=data_hash)
|
|
369
372
|
msg = LubaMsg().parse(data)
|
|
370
373
|
if betterproto.serialized_on_wire(msg.nav.toapp_get_commondata_ack):
|
|
371
374
|
result_hash = msg.nav.toapp_get_commondata_ack.hash
|
|
@@ -377,7 +380,7 @@ class MammotionBaseDevice:
|
|
|
377
380
|
region_data.type = common_data.type
|
|
378
381
|
region_data.total_frame = total_frame
|
|
379
382
|
region_data.current_frame = current_frame
|
|
380
|
-
await self.
|
|
383
|
+
await self.queue_command("get_regional_data", regional_data=region_data)
|
|
381
384
|
|
|
382
385
|
def _update_raw_data(self, data: bytes) -> None:
|
|
383
386
|
"""Update raw and model data from notifications."""
|
|
@@ -475,6 +478,10 @@ class MammotionBaseDevice:
|
|
|
475
478
|
"""Get the LubaMsg of the device."""
|
|
476
479
|
return self._mower
|
|
477
480
|
|
|
481
|
+
@abstractmethod
|
|
482
|
+
async def queue_command(self, key: str, **kwargs: any) -> bytes:
|
|
483
|
+
"""Queue commands to mower."""
|
|
484
|
+
|
|
478
485
|
@abstractmethod
|
|
479
486
|
async def _send_command(self, key: str, retry: int | None = None) -> bytes | None:
|
|
480
487
|
"""Send command to device and read response."""
|
|
@@ -505,9 +512,15 @@ class MammotionBaseDevice:
|
|
|
505
512
|
|
|
506
513
|
await self._send_command_with_args("get_hash_response", total_frame=1, current_frame=1)
|
|
507
514
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
515
|
+
if self._cloud_device:
|
|
516
|
+
await self._send_command_with_args(
|
|
517
|
+
"get_area_name_list", device_id=self._cloud_device.deviceName
|
|
518
|
+
)
|
|
519
|
+
if has_field(self._mower.net.toapp_wifi_iot_status):
|
|
520
|
+
await self._send_command_with_args(
|
|
521
|
+
"get_area_name_list", device_id=self._mower.net.toapp_wifi_iot_status.devicename
|
|
522
|
+
)
|
|
523
|
+
|
|
511
524
|
|
|
512
525
|
# sub_cmd 3 is job hashes??
|
|
513
526
|
# sub_cmd 4 is dump location (yuka)
|
|
@@ -586,6 +599,9 @@ class MammotionBaseBLEDevice(MammotionBaseDevice):
|
|
|
586
599
|
130, lambda: asyncio.ensure_future(self.run_periodic_sync_task())
|
|
587
600
|
)
|
|
588
601
|
|
|
602
|
+
async def queue_command(self, key: str, **kwargs: any) -> bytes | None:
|
|
603
|
+
return await self._send_command_with_args(key, **kwargs)
|
|
604
|
+
|
|
589
605
|
async def _send_command_with_args(self, key: str, **kwargs) -> bytes | None:
|
|
590
606
|
"""Send command to device and read response."""
|
|
591
607
|
if self._operation_lock.locked():
|
|
@@ -655,7 +671,7 @@ class MammotionBaseBLEDevice(MammotionBaseDevice):
|
|
|
655
671
|
def rssi(self) -> int:
|
|
656
672
|
"""Return RSSI of device."""
|
|
657
673
|
try:
|
|
658
|
-
return self._mower.
|
|
674
|
+
return self._mower.sys.toapp_report_data.connect.ble_rssi
|
|
659
675
|
finally:
|
|
660
676
|
return 0
|
|
661
677
|
|
|
@@ -938,9 +954,11 @@ class MammotionBaseCloudDevice(MammotionBaseDevice):
|
|
|
938
954
|
mowing_state: MowingDevice
|
|
939
955
|
) -> None:
|
|
940
956
|
"""Initialize MammotionBaseCloudDevice."""
|
|
941
|
-
super().__init__(mowing_state)
|
|
957
|
+
super().__init__(mowing_state, cloud_device)
|
|
942
958
|
self._ble_sync_task = None
|
|
943
959
|
self.is_ready = False
|
|
960
|
+
self.command_queue = asyncio.Queue()
|
|
961
|
+
self.processing_task = asyncio.create_task(self._process_queue())
|
|
944
962
|
self._mqtt_client = mqtt_client
|
|
945
963
|
self.iot_id = cloud_device.iotId
|
|
946
964
|
self.device = cloud_device
|
|
@@ -966,7 +984,7 @@ class MammotionBaseCloudDevice(MammotionBaseDevice):
|
|
|
966
984
|
async def on_ready(self):
|
|
967
985
|
"""Callback for when MQTT is subscribed to events."""
|
|
968
986
|
if self.on_ready_callback:
|
|
969
|
-
self.on_ready_callback()
|
|
987
|
+
await self.on_ready_callback()
|
|
970
988
|
|
|
971
989
|
await self._ble_sync()
|
|
972
990
|
await self.run_periodic_sync_task()
|
|
@@ -998,6 +1016,32 @@ class MammotionBaseCloudDevice(MammotionBaseDevice):
|
|
|
998
1016
|
160, lambda: asyncio.ensure_future(self.run_periodic_sync_task())
|
|
999
1017
|
)
|
|
1000
1018
|
|
|
1019
|
+
async def queue_command(self, key: str, **kwargs: any) -> bytes:
|
|
1020
|
+
# Create a future to hold the result
|
|
1021
|
+
_LOGGER.debug("Queueing command: %s", key)
|
|
1022
|
+
future = asyncio.Future()
|
|
1023
|
+
# Put the command in the queue as a tuple (key, command, future)
|
|
1024
|
+
command_bytes = getattr(self._commands, key)(**kwargs)
|
|
1025
|
+
await self.command_queue.put((key, command_bytes, future))
|
|
1026
|
+
# Wait for the future to be resolved
|
|
1027
|
+
return await future
|
|
1028
|
+
|
|
1029
|
+
async def _process_queue(self):
|
|
1030
|
+
while True:
|
|
1031
|
+
# Get the next item from the queue
|
|
1032
|
+
key, command, future = await self.command_queue.get()
|
|
1033
|
+
try:
|
|
1034
|
+
# Process the command using _execute_command_locked
|
|
1035
|
+
result = await self._execute_command_locked(key, command)
|
|
1036
|
+
# Set the result on the future
|
|
1037
|
+
future.set_result(result)
|
|
1038
|
+
except Exception as ex:
|
|
1039
|
+
# Set the exception on the future if something goes wrong
|
|
1040
|
+
future.set_exception(ex)
|
|
1041
|
+
finally:
|
|
1042
|
+
# Mark the task as done
|
|
1043
|
+
self.command_queue.task_done()
|
|
1044
|
+
|
|
1001
1045
|
async def _on_mqtt_message(self, topic: str, payload: str, iot_id: str) -> None:
|
|
1002
1046
|
"""Handle incoming MQTT messages."""
|
|
1003
1047
|
_LOGGER.debug("MQTT message received on topic %s: %s, iot_id: %s", topic, payload, iot_id)
|
|
@@ -57,7 +57,7 @@ class MammotionMQTT:
|
|
|
57
57
|
).hexdigest()
|
|
58
58
|
|
|
59
59
|
self._client_id = client_id
|
|
60
|
-
self.loop = asyncio.
|
|
60
|
+
self.loop = asyncio.get_running_loop()
|
|
61
61
|
|
|
62
62
|
self._linkkit_client = LinkKit(
|
|
63
63
|
region_id,
|
|
@@ -139,7 +139,8 @@ class MammotionMQTT:
|
|
|
139
139
|
payload = json.loads(payload)
|
|
140
140
|
iot_id = payload.get("params", {}).get("iotId", "")
|
|
141
141
|
if iot_id != "" and self.on_message:
|
|
142
|
-
asyncio.run_coroutine_threadsafe(self.on_message(topic, payload, iot_id), self.loop)
|
|
142
|
+
future = asyncio.run_coroutine_threadsafe(self.on_message(topic, payload, iot_id), self.loop)
|
|
143
|
+
asyncio.wrap_future(future, loop=self.loop)
|
|
143
144
|
|
|
144
145
|
|
|
145
146
|
def _thing_on_connect(self, session_flag, rc, user_data):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
pymammotion/__init__.py,sha256=kmnjdt3AEMejIz5JK7h1tTJj5ZriAgKwZBa3ScA4-Ao,1516
|
|
2
2
|
pymammotion/aliyun/__init__.py,sha256=T1lkX7TRYiL4nqYanG4l4MImV-SlavSbuooC-W-uUGw,29
|
|
3
|
-
pymammotion/aliyun/cloud_gateway.py,sha256=
|
|
3
|
+
pymammotion/aliyun/cloud_gateway.py,sha256=IqmxgjDIgRoZvJvQnwYGOSl4XaCV4MoMKTlfhC9-6Ys,21830
|
|
4
4
|
pymammotion/aliyun/cloud_service.py,sha256=YWcKuKK6iRWy5mTnBYgHxcCusiRGGzQt3spSf7dGDss,2183
|
|
5
5
|
pymammotion/aliyun/dataclass/aep_response.py,sha256=8f6GIP58ve8gd6AL3HBoXxsy0n2q4ygWvjELGnoOnVc,452
|
|
6
6
|
pymammotion/aliyun/dataclass/connect_response.py,sha256=Yz-fEbDzgGPTo5Of2oAjmFkSv08T7ze80pQU4k-gKIU,824
|
|
@@ -58,10 +58,10 @@ pymammotion/mammotion/commands/messages/video.py,sha256=_8lJsU4sLm2CGnc7RDkueA0A
|
|
|
58
58
|
pymammotion/mammotion/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
59
59
|
pymammotion/mammotion/control/joystick.py,sha256=EWV20MMzQuhbLlNlXbsyZKSEpeM7x1CQL7saU4Pn0-g,6165
|
|
60
60
|
pymammotion/mammotion/devices/__init__.py,sha256=T72jt0ejtMjo1rPmn_FeMF3pmp0LLeRRpc9WcDKEYYY,126
|
|
61
|
-
pymammotion/mammotion/devices/mammotion.py,sha256=
|
|
61
|
+
pymammotion/mammotion/devices/mammotion.py,sha256=9JaxzYvaWwcGU-O22sHgQCwKWliQdD9wfbtjIlzQBVk,46958
|
|
62
62
|
pymammotion/mqtt/__init__.py,sha256=Ocs5e-HLJvTuDpVXyECEsWIvwsUaxzj7lZ9mSYutNDY,105
|
|
63
63
|
pymammotion/mqtt/mammotion_future.py,sha256=WKnHqeHiS2Ut-SaDBNOxqh1jDLeTiyLTsJ7PNUexrjk,687
|
|
64
|
-
pymammotion/mqtt/mammotion_mqtt.py,sha256=
|
|
64
|
+
pymammotion/mqtt/mammotion_mqtt.py,sha256=K9TokiQWYJloWu5Hom00g7cfGhWHDSWqbcU9AqW4C9Q,8071
|
|
65
65
|
pymammotion/proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
66
66
|
pymammotion/proto/basestation.proto,sha256=_x5gAz3FkZXS1jtq4GgZgaDCuRU-UV-7HTFdsfQ3zbo,1034
|
|
67
67
|
pymammotion/proto/basestation.py,sha256=js64_N2xQYRxWPRdVNEapO0qe7vBlfYnjW5sE8hi7hw,2026
|
|
@@ -111,7 +111,7 @@ pymammotion/utility/device_type.py,sha256=KYawu2glZMVlPmxRbA4kVFujXz3miHp3rJiOWR
|
|
|
111
111
|
pymammotion/utility/map.py,sha256=aoi-Luzuph02hKynTofMoq3mnPstanx75MDAVv49CuY,2211
|
|
112
112
|
pymammotion/utility/periodic.py,sha256=9wJMfwXPlx6Mbp3Fws7LLTI34ZDKphH1bva_Ggyk32g,3281
|
|
113
113
|
pymammotion/utility/rocker_util.py,sha256=syPL0QN4zMzHiTIkUKS7RXBBptjdbkfNlPddwUD5V3A,7171
|
|
114
|
-
pymammotion-0.2.
|
|
115
|
-
pymammotion-0.2.
|
|
116
|
-
pymammotion-0.2.
|
|
117
|
-
pymammotion-0.2.
|
|
114
|
+
pymammotion-0.2.10.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
115
|
+
pymammotion-0.2.10.dist-info/METADATA,sha256=4FAKtdE368XaqgafLpkOl77gKKxgdkQDME7Lab3yidc,3969
|
|
116
|
+
pymammotion-0.2.10.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
117
|
+
pymammotion-0.2.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|