pymammotion 0.4.0a9__py3-none-any.whl → 0.4.0b1__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.
- pymammotion/data/state_manager.py +150 -124
- pymammotion/mammotion/commands/messages/video.py +2 -5
- pymammotion/mammotion/devices/base.py +0 -9
- pymammotion/mammotion/devices/mammotion_bluetooth.py +9 -0
- pymammotion/mammotion/devices/mammotion_cloud.py +8 -0
- {pymammotion-0.4.0a9.dist-info → pymammotion-0.4.0b1.dist-info}/METADATA +1 -1
- {pymammotion-0.4.0a9.dist-info → pymammotion-0.4.0b1.dist-info}/RECORD +9 -9
- {pymammotion-0.4.0a9.dist-info → pymammotion-0.4.0b1.dist-info}/LICENSE +0 -0
- {pymammotion-0.4.0a9.dist-info → pymammotion-0.4.0b1.dist-info}/WHEEL +0 -0
@@ -21,127 +21,153 @@ logger = logging.getLogger(__name__)
|
|
21
21
|
|
22
22
|
|
23
23
|
class StateManager:
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
self._device.online =
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
24
|
+
"""Manage state."""
|
25
|
+
|
26
|
+
_device: MowingDevice
|
27
|
+
last_updated_at: datetime = datetime.now()
|
28
|
+
|
29
|
+
def __init__(self, device: MowingDevice) -> None:
|
30
|
+
self._device = device
|
31
|
+
self.cloud_gethash_ack_callback: Callable[[NavGetHashListAck], Awaitable[None]] | None = None
|
32
|
+
self.cloud_get_commondata_ack_callback: Callable[[NavGetCommDataAck | SvgMessageAckT], Awaitable[None]] | None = None
|
33
|
+
self.cloud_on_notification_callback: Callable[[tuple[str, Any | None]], Awaitable[None]] | None = None
|
34
|
+
|
35
|
+
# possibly don't need anymore
|
36
|
+
self.cloud_queue_command_callback: Callable[[str, dict[str, Any]], Awaitable[bytes]] | None = None
|
37
|
+
|
38
|
+
self.ble_gethash_ack_callback: Callable[[NavGetHashListAck], Awaitable[None]] | None = None
|
39
|
+
self.ble_get_commondata_ack_callback: Callable[[NavGetCommDataAck | SvgMessageAckT], Awaitable[None]] | None = None
|
40
|
+
self.ble_on_notification_callback: Callable[[tuple[str, Any | None]], Awaitable[None]] | None = None
|
41
|
+
|
42
|
+
# possibly don't need anymore
|
43
|
+
self.ble_queue_command_callback: Callable[[str, dict[str, Any]], Awaitable[bytes]] | None = None
|
44
|
+
self.last_updated_at = datetime.now()
|
45
|
+
|
46
|
+
def get_device(self) -> MowingDevice:
|
47
|
+
"""Get device."""
|
48
|
+
return self._device
|
49
|
+
|
50
|
+
def set_device(self, device: MowingDevice) -> None:
|
51
|
+
"""Set device."""
|
52
|
+
self._device = device
|
53
|
+
|
54
|
+
async def properties(self, properties: ThingPropertiesMessage) -> None:
|
55
|
+
self._device.mqtt_properties = properties
|
56
|
+
|
57
|
+
async def status(self, status: ThingStatusMessage) -> None:
|
58
|
+
if not self._device.online:
|
59
|
+
self._device.online = True
|
60
|
+
self._device.status_properties = status
|
61
|
+
|
62
|
+
@property
|
63
|
+
def online(self) -> bool:
|
64
|
+
return self._device.online
|
65
|
+
|
66
|
+
@online.setter
|
67
|
+
def online(self, value: bool) -> None:
|
68
|
+
self._device.online = value
|
69
|
+
|
70
|
+
async def gethash_ack_callback(self, msg: NavGetHashListAck):
|
71
|
+
if self.cloud_gethash_ack_callback:
|
72
|
+
await self.cloud_gethash_ack_callback(msg)
|
73
|
+
if self.ble_gethash_ack_callback:
|
74
|
+
await self.ble_gethash_ack_callback(msg)
|
75
|
+
|
76
|
+
async def on_notification_callback(self, res: tuple[str, Any | None]):
|
77
|
+
if self.cloud_on_notification_callback:
|
78
|
+
await self.cloud_on_notification_callback(res)
|
79
|
+
if self.ble_on_notification_callback:
|
80
|
+
await self.ble_on_notification_callback(res)
|
81
|
+
|
82
|
+
async def get_commondata_ack_callback(self, comm_data: NavGetCommDataAck | SvgMessageAckT):
|
83
|
+
if self.cloud_get_commondata_ack_callback:
|
84
|
+
await self.cloud_get_commondata_ack_callback(comm_data)
|
85
|
+
if self.ble_get_commondata_ack_callback:
|
86
|
+
await self.ble_get_commondata_ack_callback(comm_data)
|
87
|
+
|
88
|
+
async def notification(self, message: LubaMsg) -> None:
|
89
|
+
"""Handle protobuf notifications."""
|
90
|
+
res = betterproto.which_one_of(message, "LubaSubMsg")
|
91
|
+
self.last_updated_at = datetime.now()
|
92
|
+
|
93
|
+
match res[0]:
|
94
|
+
case "nav":
|
95
|
+
await self._update_nav_data(message)
|
96
|
+
case "sys":
|
97
|
+
await self._update_sys_data(message)
|
98
|
+
case "driver":
|
99
|
+
self._update_driver_data(message)
|
100
|
+
case "net":
|
101
|
+
self._update_net_data(message)
|
102
|
+
case "mul":
|
103
|
+
self._update_mul_data(message)
|
104
|
+
case "ota":
|
105
|
+
self._update_ota_data(message)
|
106
|
+
|
107
|
+
await self.on_notification_callback(res)
|
108
|
+
|
109
|
+
async def _update_nav_data(self, message) -> None:
|
110
|
+
"""Update nav data."""
|
111
|
+
nav_msg = betterproto.which_one_of(message.nav, "SubNavMsg")
|
112
|
+
match nav_msg[0]:
|
113
|
+
case "toapp_gethash_ack":
|
114
|
+
hashlist_ack: NavGetHashListAck = nav_msg[1]
|
115
|
+
self._device.map.update_root_hash_list(hashlist_ack)
|
116
|
+
await self.gethash_ack_callback(nav_msg[1])
|
117
|
+
case "toapp_get_commondata_ack":
|
118
|
+
common_data: NavGetCommDataAck = nav_msg[1]
|
119
|
+
updated = self._device.map.update(common_data)
|
120
|
+
if updated:
|
121
|
+
await self.get_commondata_ack_callback(common_data)
|
122
|
+
case "toapp_svg_msg":
|
123
|
+
common_data: SvgMessageAckT = nav_msg[1]
|
124
|
+
updated = self._device.map.update(common_data)
|
125
|
+
if updated:
|
126
|
+
await self.get_commondata_ack_callback(common_data)
|
127
|
+
|
128
|
+
case "toapp_all_hash_name":
|
129
|
+
hash_names: AppGetAllAreaHashName = nav_msg[1]
|
130
|
+
converted_list = [AreaHashNameList(name=item.name, hash=item.hash) for item in hash_names.hashnames]
|
131
|
+
self._device.map.area_name = converted_list
|
132
|
+
|
133
|
+
async def _update_sys_data(self, message) -> None:
|
134
|
+
"""Update system."""
|
135
|
+
sys_msg = betterproto.which_one_of(message.sys, "SubSysMsg")
|
136
|
+
match sys_msg[0]:
|
137
|
+
case "system_update_buf":
|
138
|
+
self._device.buffer(sys_msg[1])
|
139
|
+
case "toapp_report_data":
|
140
|
+
self._device.update_report_data(sys_msg[1])
|
141
|
+
case "mow_to_app_info":
|
142
|
+
self._device.mow_info(sys_msg[1])
|
143
|
+
case "system_tard_state_tunnel":
|
144
|
+
self._device.run_state_update(sys_msg[1])
|
145
|
+
case "todev_time_ctrl_light":
|
146
|
+
ctrl_light: TimeCtrlLight = sys_msg[1]
|
147
|
+
side_led: SideLight = SideLight.from_dict(ctrl_light.to_dict(casing=betterproto.Casing.SNAKE))
|
148
|
+
self._device.mower_state.side_led = side_led
|
149
|
+
case "device_product_type_info":
|
150
|
+
device_product_type: DeviceProductTypeInfoT = sys_msg[1]
|
151
|
+
self._device.mower_state.model_id = device_product_type.main_product_type
|
152
|
+
|
153
|
+
def _update_driver_data(self, message) -> None:
|
154
|
+
pass
|
155
|
+
|
156
|
+
def _update_net_data(self, message) -> None:
|
157
|
+
net_msg = betterproto.which_one_of(message.net, "NetSubType")
|
158
|
+
match net_msg[0]:
|
159
|
+
case "toapp_wifi_iot_status":
|
160
|
+
wifi_iot_status: WifiIotStatusReport = net_msg[1]
|
161
|
+
self._device.mower_state.product_key = wifi_iot_status.productkey
|
162
|
+
case "toapp_devinfo_resp":
|
163
|
+
toapp_devinfo_resp: DrvDevInfoResp = net_msg[1]
|
164
|
+
for resp in toapp_devinfo_resp.resp_ids:
|
165
|
+
if resp.res == "DRV_RESULT_SUC":
|
166
|
+
self._device.mower_state.swversion = resp.info
|
167
|
+
self._device.device_firmwares.device_version = resp.info
|
168
|
+
|
169
|
+
def _update_mul_data(self, message) -> None:
|
170
|
+
pass
|
171
|
+
|
172
|
+
def _update_ota_data(self, message) -> None:
|
173
|
+
pass
|
@@ -5,6 +5,7 @@ import time
|
|
5
5
|
from pymammotion.mammotion.commands.abstract_message import AbstractMessage
|
6
6
|
from pymammotion.proto import luba_msg_pb2, luba_mul_pb2
|
7
7
|
from pymammotion.proto.luba_msg import MsgAttr, MsgCmdType, MsgDevice
|
8
|
+
from pymammotion.proto.luba_mul import MUL_CAMERA_POSITION
|
8
9
|
from pymammotion.utility.device_type import DeviceType
|
9
10
|
|
10
11
|
|
@@ -25,10 +26,6 @@ class MessageVideo(AbstractMessage, ABC):
|
|
25
26
|
return luba_msg.SerializeToString()
|
26
27
|
|
27
28
|
def device_agora_join_channel_with_position(self, enter_state: int):
|
28
|
-
position = (
|
29
|
-
luba_mul_pb2.MUL_CAMERA_POSITION.ALL
|
30
|
-
if DeviceType.is_yuka(self.get_device_name())
|
31
|
-
else luba_mul_pb2.MUL_CAMERA_POSITION.LEFT
|
32
|
-
)
|
29
|
+
position = MUL_CAMERA_POSITION.ALL if DeviceType.is_yuka(self.get_device_name()) else MUL_CAMERA_POSITION.LEFT
|
33
30
|
mctl_sys = luba_mul_pb2.SocMul(set_video=luba_mul_pb2.MulSetVideo(position=position, vi_switch=enter_state))
|
34
31
|
return self.send_order_msg_video(mctl_sys)
|
@@ -1,6 +1,5 @@
|
|
1
1
|
from abc import abstractmethod
|
2
2
|
import asyncio
|
3
|
-
from collections.abc import Awaitable, Callable
|
4
3
|
import logging
|
5
4
|
from typing import Any
|
6
5
|
|
@@ -41,17 +40,9 @@ class MammotionBaseDevice:
|
|
41
40
|
self._state_manager = state_manager
|
42
41
|
self._raw_data = dict()
|
43
42
|
self._raw_mower_data: RawMowerData = RawMowerData()
|
44
|
-
self._state_manager.gethash_ack_callback = self.datahash_response
|
45
|
-
self._state_manager.get_commondata_ack_callback = self.commdata_response
|
46
43
|
self._notify_future: asyncio.Future[bytes] | None = None
|
47
44
|
self._cloud_device = cloud_device
|
48
45
|
|
49
|
-
def set_notification_callback(self, func: Callable[[tuple[str, Any | None]], Awaitable[None]]) -> None:
|
50
|
-
self._state_manager.on_notification_callback = func
|
51
|
-
|
52
|
-
def set_queue_callback(self, func: Callable[[str, dict[str, Any]], Awaitable[bytes]]) -> None:
|
53
|
-
self._state_manager.queue_command_callback = func
|
54
|
-
|
55
46
|
async def datahash_response(self, hash_ack: NavGetHashListAck) -> None:
|
56
47
|
"""Handle datahash responses."""
|
57
48
|
current_frame = hash_ack.current_frame
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import asyncio
|
2
|
+
from collections.abc import Awaitable, Callable
|
2
3
|
import logging
|
3
4
|
from typing import Any, cast
|
4
5
|
from uuid import UUID
|
@@ -89,9 +90,17 @@ class MammotionBaseBLEDevice(MammotionBaseDevice):
|
|
89
90
|
self._operation_lock = asyncio.Lock()
|
90
91
|
self._key: str | None = None
|
91
92
|
self.set_queue_callback(self.queue_command)
|
93
|
+
self._state_manager.ble_gethash_ack_callback = self.datahash_response
|
94
|
+
self._state_manager.ble_get_commondata_ack_callback = self.commdata_response
|
92
95
|
loop = asyncio.get_event_loop()
|
93
96
|
loop.create_task(self.process_queue())
|
94
97
|
|
98
|
+
def set_notification_callback(self, func: Callable[[tuple[str, Any | None]], Awaitable[None]]) -> None:
|
99
|
+
self._state_manager.ble_on_notification_callback = func
|
100
|
+
|
101
|
+
def set_queue_callback(self, func: Callable[[str, dict[str, Any]], Awaitable[bytes]]) -> None:
|
102
|
+
self._state_manager.ble_queue_command_callback = func
|
103
|
+
|
95
104
|
def update_device(self, device: BLEDevice) -> None:
|
96
105
|
"""Update the BLE device."""
|
97
106
|
self.ble_device = device
|
@@ -172,6 +172,8 @@ class MammotionBaseCloudDevice(MammotionBaseDevice):
|
|
172
172
|
self._mqtt.on_ready_event.add_subscribers(self.on_ready)
|
173
173
|
self._mqtt.on_disconnected_event.add_subscribers(self.on_disconnect)
|
174
174
|
self._mqtt.on_connected_event.add_subscribers(self.on_connect)
|
175
|
+
self._state_manager.cloud_gethash_ack_callback = self.datahash_response
|
176
|
+
self._state_manager.cloud_get_commondata_ack_callback = self.commdata_response
|
175
177
|
self.set_queue_callback(self.queue_command)
|
176
178
|
|
177
179
|
if self._mqtt.is_ready:
|
@@ -185,6 +187,12 @@ class MammotionBaseCloudDevice(MammotionBaseDevice):
|
|
185
187
|
if self._ble_sync_task:
|
186
188
|
self._ble_sync_task.cancel()
|
187
189
|
|
190
|
+
def set_notification_callback(self, func: Callable[[tuple[str, Any | None]], Awaitable[None]]) -> None:
|
191
|
+
self._state_manager.cloud_on_notification_callback = func
|
192
|
+
|
193
|
+
def set_queue_callback(self, func: Callable[[str, dict[str, Any]], Awaitable[bytes]]) -> None:
|
194
|
+
self._state_manager.cloud_queue_command_callback = func
|
195
|
+
|
188
196
|
async def on_ready(self) -> None:
|
189
197
|
"""Callback for when MQTT is subscribed to events."""
|
190
198
|
if self.stopped:
|
@@ -43,7 +43,7 @@ pymammotion/data/mqtt/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdr
|
|
43
43
|
pymammotion/data/mqtt/event.py,sha256=r14gzZVxmlGVAwFdZQ1CUsMZFHHwRKnbt2VHnjugP28,5123
|
44
44
|
pymammotion/data/mqtt/properties.py,sha256=pX5JRVmmpVO04CSPm5xAGcSWA_OeLd0JnBagLsfiSEc,3755
|
45
45
|
pymammotion/data/mqtt/status.py,sha256=DuNC3JdewLPKNqNHx76_FPXRvheYSiM-CdiVTCCYY8s,1079
|
46
|
-
pymammotion/data/state_manager.py,sha256=
|
46
|
+
pymammotion/data/state_manager.py,sha256=4NLSzJIfYi2fS_Y8qRgCyAo0eMd3qpmjJ961L_5Iy4o,7009
|
47
47
|
pymammotion/event/__init__.py,sha256=mgATR6vPHACNQ-0zH5fi7NdzeTCDV1CZyaWPmtUusi8,115
|
48
48
|
pymammotion/event/event.py,sha256=bj2RirSIRyBs0QvkcrOtwZWUX_8F3m1sySuHVyKmZLs,2143
|
49
49
|
pymammotion/http/_init_.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -61,14 +61,14 @@ pymammotion/mammotion/commands/messages/navigation.py,sha256=BE5h8xN2XCkcfynb5cQ
|
|
61
61
|
pymammotion/mammotion/commands/messages/network.py,sha256=vUjBvuiBhRkOA4nftqTFw6rFdXNjho-ZA9Y37hL2q5Q,7623
|
62
62
|
pymammotion/mammotion/commands/messages/ota.py,sha256=g937HT_-OQXV6A3zUiZ53b45cOX6y-rzs5m-4b0IcTk,1473
|
63
63
|
pymammotion/mammotion/commands/messages/system.py,sha256=CYf_Ju5nMK9cFd0r5jOzEJ_w4k70PzassdhE8xLeSJU,14371
|
64
|
-
pymammotion/mammotion/commands/messages/video.py,sha256=
|
64
|
+
pymammotion/mammotion/commands/messages/video.py,sha256=JBPyK1C9gZ6B3QcNe3IUTUnn0QWNXR4Pwj9W0qNO9Ps,1304
|
65
65
|
pymammotion/mammotion/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
66
66
|
pymammotion/mammotion/control/joystick.py,sha256=QfBVxM_gxpWsZAGO90whtgxCI2tIZ3TTad9wHIPsU9s,5640
|
67
67
|
pymammotion/mammotion/devices/__init__.py,sha256=f2qQFPgLGmV85W2hSlMUh5BYuht9o_Ar_JEAAMD4fsE,102
|
68
|
-
pymammotion/mammotion/devices/base.py,sha256=
|
68
|
+
pymammotion/mammotion/devices/base.py,sha256=evNKt1PDDGPkm4wleIEC2dtHuyDP_nHRCg35nrQg6qg,10260
|
69
69
|
pymammotion/mammotion/devices/mammotion.py,sha256=-x9hf_M-_3fp5srHGBuMmO5DBsSDnwVGMyEiAEz5dW8,12685
|
70
|
-
pymammotion/mammotion/devices/mammotion_bluetooth.py,sha256=
|
71
|
-
pymammotion/mammotion/devices/mammotion_cloud.py,sha256=
|
70
|
+
pymammotion/mammotion/devices/mammotion_bluetooth.py,sha256=tfD8TIgKVd57Hrr-totXP0-WFSRFYBuoV5Dw0EpvOi4,19509
|
71
|
+
pymammotion/mammotion/devices/mammotion_cloud.py,sha256=nd1Uj6rF8UKHJbHC6nlPRrNQPggPXxfpydT0o0cWbMM,13835
|
72
72
|
pymammotion/mqtt/__init__.py,sha256=Ocs5e-HLJvTuDpVXyECEsWIvwsUaxzj7lZ9mSYutNDY,105
|
73
73
|
pymammotion/mqtt/linkkit/__init__.py,sha256=ENgc3ynd2kd9gMQR3-kgmCu6Ed9Y6XCIzU0zFReUlkk,80
|
74
74
|
pymammotion/mqtt/linkkit/h2client.py,sha256=w9Nvi_nY4CLD_fw-pHtYChwQf7e2TiAGeqkY_sF4cf0,19659
|
@@ -127,7 +127,7 @@ pymammotion/utility/map.py,sha256=GYscVMg2cX3IPlNpCBNHDW0S55yS1WGRf1iHnNZ7TfQ,22
|
|
127
127
|
pymammotion/utility/movement.py,sha256=N75oAoAgFydqoaOedYIxGUHmuTCtPzAOtb-d_29tpfI,615
|
128
128
|
pymammotion/utility/periodic.py,sha256=MbeSb9cfhxzYmdT_RiE0dZe3H9IfbQW_zSqhmSX2RUc,3321
|
129
129
|
pymammotion/utility/rocker_util.py,sha256=6tX7sS87qoQC_tsxbx3NLL-HgS08wtzXiZkhDiz7uo0,7179
|
130
|
-
pymammotion-0.4.
|
131
|
-
pymammotion-0.4.
|
132
|
-
pymammotion-0.4.
|
133
|
-
pymammotion-0.4.
|
130
|
+
pymammotion-0.4.0b1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
131
|
+
pymammotion-0.4.0b1.dist-info/METADATA,sha256=QzBQE6mluKSxxyVSZan9r9lsbv9EYV57h3mw789NUdE,3886
|
132
|
+
pymammotion-0.4.0b1.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
|
133
|
+
pymammotion-0.4.0b1.dist-info/RECORD,,
|
File without changes
|
File without changes
|