pymammotion 0.2.63__py3-none-any.whl → 0.2.65__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/bluetooth/ble_message.py +11 -11
- pymammotion/data/model/hash_list.py +30 -7
- pymammotion/data/state_manager.py +12 -13
- pymammotion/mammotion/devices/base.py +4 -4
- pymammotion/mammotion/devices/mammotion.py +4 -3
- pymammotion/mammotion/devices/mammotion_bluetooth.py +32 -4
- pymammotion/mammotion/devices/mammotion_cloud.py +8 -5
- pymammotion/proto/mctrl_nav.proto +5 -0
- pymammotion/proto/mctrl_nav.py +4 -0
- {pymammotion-0.2.63.dist-info → pymammotion-0.2.65.dist-info}/METADATA +1 -1
- {pymammotion-0.2.63.dist-info → pymammotion-0.2.65.dist-info}/RECORD +13 -13
- {pymammotion-0.2.63.dist-info → pymammotion-0.2.65.dist-info}/LICENSE +0 -0
- {pymammotion-0.2.63.dist-info → pymammotion-0.2.65.dist-info}/WHEEL +0 -0
@@ -141,17 +141,17 @@ class BleMessage:
|
|
141
141
|
# Log.d(TAG, "parseNotification Notification= " + Arrays.toString(response));
|
142
142
|
# }
|
143
143
|
if len(response) >= 4:
|
144
|
-
sequence = int(response[2]) # toInt
|
145
|
-
if sequence != next(self.mReadSequence):
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
144
|
+
# sequence = int(response[2]) # toInt
|
145
|
+
# if sequence != next(self.mReadSequence):
|
146
|
+
# _LOGGER.debug(
|
147
|
+
# "parseNotification read sequence wrong",
|
148
|
+
# sequence,
|
149
|
+
# self.mReadSequence,
|
150
|
+
# )
|
151
|
+
# self.mReadSequence = itertools.count(start=sequence)
|
152
|
+
# this is questionable
|
153
|
+
# self.mReadSequence = sequence
|
154
|
+
# self.mReadSequence_2.incrementAndGet()
|
155
155
|
|
156
156
|
# LogUtil.m7773e(self.mGatt.getDevice().getName() + "打印丢包率", self.mReadSequence_2 + "/" + self.mReadSequence_1);
|
157
157
|
pkt_type = int(response[0]) # toInt
|
@@ -3,7 +3,7 @@ from enum import IntEnum
|
|
3
3
|
|
4
4
|
from mashumaro.mixins.orjson import DataClassORJSONMixin
|
5
5
|
|
6
|
-
from pymammotion.proto.mctrl_nav import NavGetCommDataAck, NavGetHashListAck
|
6
|
+
from pymammotion.proto.mctrl_nav import NavGetCommDataAck, NavGetHashListAck, SvgMessageAckT
|
7
7
|
|
8
8
|
|
9
9
|
class PathType(IntEnum):
|
@@ -13,12 +13,13 @@ class PathType(IntEnum):
|
|
13
13
|
OBSTACLE = 1
|
14
14
|
PATH = 2
|
15
15
|
DUMP = 12
|
16
|
+
SVG = 13
|
16
17
|
|
17
18
|
|
18
19
|
@dataclass
|
19
20
|
class FrameList(DataClassORJSONMixin):
|
20
21
|
total_frame: int
|
21
|
-
data: list[NavGetCommDataAck]
|
22
|
+
data: list[NavGetCommDataAck | SvgMessageAckT]
|
22
23
|
|
23
24
|
|
24
25
|
@dataclass
|
@@ -52,6 +53,7 @@ class HashList(DataClassORJSONMixin):
|
|
52
53
|
path: dict = field(default_factory=dict) # type 2
|
53
54
|
obstacle: dict = field(default_factory=dict) # type 1
|
54
55
|
dump: dict = field(default_factory=dict) # type 12?
|
56
|
+
svg: dict = field(default_factory=dict) # type 13
|
55
57
|
area_name: list[AreaHashNameList] = field(default_factory=list)
|
56
58
|
|
57
59
|
def update_hash_lists(self, hashlist: list[int]) -> None:
|
@@ -59,6 +61,7 @@ class HashList(DataClassORJSONMixin):
|
|
59
61
|
self.path = {hash_id: frames for hash_id, frames in self.path.items() if hash_id in hashlist}
|
60
62
|
self.obstacle = {hash_id: frames for hash_id, frames in self.obstacle.items() if hash_id in hashlist}
|
61
63
|
self.dump = {hash_id: frames for hash_id, frames in self.dump.items() if hash_id in hashlist}
|
64
|
+
self.svg = {hash_id: frames for hash_id, frames in self.svg.items() if hash_id in hashlist}
|
62
65
|
|
63
66
|
@property
|
64
67
|
def hashlist(self) -> list[int]:
|
@@ -72,7 +75,10 @@ class HashList(DataClassORJSONMixin):
|
|
72
75
|
i
|
73
76
|
for obj in self.root_hash_list.data
|
74
77
|
for i in obj.data_couple
|
75
|
-
if i
|
78
|
+
if i
|
79
|
+
not in set(self.area.keys()).union(
|
80
|
+
self.path.keys(), self.obstacle.keys(), self.dump.keys(), self.svg.keys()
|
81
|
+
)
|
76
82
|
]
|
77
83
|
|
78
84
|
def update_root_hash_list(self, hash_list: NavGetHashListAck) -> None:
|
@@ -90,7 +96,7 @@ class HashList(DataClassORJSONMixin):
|
|
90
96
|
def missing_hash_frame(self):
|
91
97
|
return self._find_missing_frames(self.root_hash_list)
|
92
98
|
|
93
|
-
def missing_frame(self, hash_data: NavGetCommDataAck) -> list[int]:
|
99
|
+
def missing_frame(self, hash_data: NavGetCommDataAck | SvgMessageAckT) -> list[int]:
|
94
100
|
if hash_data.type == PathType.AREA:
|
95
101
|
return self._find_missing_frames(self.area.get(hash_data.hash))
|
96
102
|
|
@@ -103,12 +109,16 @@ class HashList(DataClassORJSONMixin):
|
|
103
109
|
if hash_data.type == PathType.DUMP:
|
104
110
|
return self._find_missing_frames(self.dump.get(hash_data.hash))
|
105
111
|
|
106
|
-
|
112
|
+
if hash_data.type == PathType.SVG:
|
113
|
+
return self._find_missing_frames(self.svg.get(hash_data.data_hash))
|
114
|
+
|
115
|
+
def update(self, hash_data: NavGetCommDataAck | SvgMessageAckT) -> bool:
|
107
116
|
"""Update the map data."""
|
108
117
|
if hash_data.type == PathType.AREA:
|
109
118
|
existing_name = next((area for area in self.area_name if area.hash == hash_data.hash), None)
|
110
119
|
if not existing_name:
|
111
|
-
|
120
|
+
name = f"area {len(self.area_name)+1}" if hash_data.area_label is None else hash_data.area_label.label
|
121
|
+
self.area_name.append(AreaHashNameList(name=name, hash=hash_data.hash))
|
112
122
|
return self._add_hash_data(self.area, hash_data)
|
113
123
|
|
114
124
|
if hash_data.type == PathType.OBSTACLE:
|
@@ -120,6 +130,9 @@ class HashList(DataClassORJSONMixin):
|
|
120
130
|
if hash_data.type == PathType.DUMP:
|
121
131
|
return self._add_hash_data(self.dump, hash_data)
|
122
132
|
|
133
|
+
if hash_data.type == PathType.SVG:
|
134
|
+
return self._add_hash_data(self.svg, hash_data)
|
135
|
+
|
123
136
|
@staticmethod
|
124
137
|
def _find_missing_frames(frame_list: FrameList | RootHashList) -> list[int]:
|
125
138
|
if frame_list.total_frame == len(frame_list.data):
|
@@ -131,7 +144,17 @@ class HashList(DataClassORJSONMixin):
|
|
131
144
|
return missing_numbers
|
132
145
|
|
133
146
|
@staticmethod
|
134
|
-
def _add_hash_data(hash_dict: dict, hash_data: NavGetCommDataAck) -> bool:
|
147
|
+
def _add_hash_data(hash_dict: dict, hash_data: NavGetCommDataAck | SvgMessageAckT) -> bool:
|
148
|
+
if isinstance(hash_data, SvgMessageAckT):
|
149
|
+
if hash_dict.get(hash_data.data_hash) is None:
|
150
|
+
hash_dict[hash_data.data_hash] = FrameList(total_frame=hash_data.total_frame, data=[hash_data])
|
151
|
+
return True
|
152
|
+
|
153
|
+
if hash_data not in hash_dict[hash_data.data_hash].data:
|
154
|
+
hash_dict[hash_data.data_hash].data.append(hash_data)
|
155
|
+
return True
|
156
|
+
return False
|
157
|
+
|
135
158
|
if hash_dict.get(hash_data.hash) is None:
|
136
159
|
hash_dict[hash_data.hash] = FrameList(total_frame=hash_data.total_frame, data=[hash_data])
|
137
160
|
return True
|
@@ -6,16 +6,14 @@ from typing import Any, Awaitable, Callable, Optional
|
|
6
6
|
|
7
7
|
import betterproto
|
8
8
|
|
9
|
-
from pymammotion.proto.dev_net import WifiIotStatusReport
|
10
|
-
from pymammotion.aliyun.cloud_gateway import SetupException
|
11
9
|
from pymammotion.data.model.device import MowingDevice
|
12
10
|
from pymammotion.data.model.device_info import SideLight
|
13
11
|
from pymammotion.data.model.hash_list import AreaHashNameList
|
14
12
|
from pymammotion.data.mqtt.properties import ThingPropertiesMessage
|
13
|
+
from pymammotion.proto.dev_net import WifiIotStatusReport
|
15
14
|
from pymammotion.proto.luba_msg import LubaMsg
|
16
|
-
from pymammotion.proto.mctrl_nav import AppGetAllAreaHashName, NavGetCommDataAck, NavGetHashListAck
|
17
|
-
from pymammotion.proto.mctrl_sys import
|
18
|
-
from pymammotion.utility.constant import WorkMode
|
15
|
+
from pymammotion.proto.mctrl_nav import AppGetAllAreaHashName, NavGetCommDataAck, NavGetHashListAck, SvgMessageAckT
|
16
|
+
from pymammotion.proto.mctrl_sys import DeviceProductTypeInfoT, TimeCtrlLight
|
19
17
|
|
20
18
|
logger = logging.getLogger(__name__)
|
21
19
|
|
@@ -29,7 +27,9 @@ class StateManager:
|
|
29
27
|
def __init__(self, device: MowingDevice) -> None:
|
30
28
|
self._device = device
|
31
29
|
self.gethash_ack_callback: Optional[Callable[[NavGetHashListAck], Awaitable[None]]] = None
|
32
|
-
self.get_commondata_ack_callback: Optional[Callable[[NavGetCommDataAck], Awaitable[None]]] =
|
30
|
+
self.get_commondata_ack_callback: Optional[Callable[[NavGetCommDataAck | SvgMessageAckT], Awaitable[None]]] = (
|
31
|
+
None
|
32
|
+
)
|
33
33
|
self.on_notification_callback: Optional[Callable[[], Awaitable[None]]] = None
|
34
34
|
self.queue_command_callback: Optional[Callable[[str, dict[str, Any]], Awaitable[bytes]]] = None
|
35
35
|
self.last_updated_at = datetime.now()
|
@@ -81,6 +81,12 @@ class StateManager:
|
|
81
81
|
updated = self._device.map.update(common_data)
|
82
82
|
if updated:
|
83
83
|
await self.get_commondata_ack_callback(common_data)
|
84
|
+
case "toapp_svg_msg":
|
85
|
+
common_data: SvgMessageAckT = nav_msg[1]
|
86
|
+
updated = self._device.map.update(common_data)
|
87
|
+
if updated:
|
88
|
+
await self.get_commondata_ack_callback(common_data)
|
89
|
+
|
84
90
|
case "toapp_all_hash_name":
|
85
91
|
hash_names: AppGetAllAreaHashName = nav_msg[1]
|
86
92
|
converted_list = [AreaHashNameList(name=item.name, hash=item.hash) for item in hash_names.hashnames]
|
@@ -94,13 +100,6 @@ class StateManager:
|
|
94
100
|
self._device.buffer(sys_msg[1])
|
95
101
|
case "toapp_report_data":
|
96
102
|
self._device.update_report_data(sys_msg[1])
|
97
|
-
if self.queue_command_callback:
|
98
|
-
if self._device.sys.toapp_report_data.dev.sys_status != WorkMode.MODE_WORKING:
|
99
|
-
try:
|
100
|
-
await self.queue_command_callback("get_report_cfg_stop")
|
101
|
-
except SetupException as exc:
|
102
|
-
# can't do anything about it yet
|
103
|
-
logger.debug(exc)
|
104
103
|
case "mow_to_app_info":
|
105
104
|
self._device.mow_info(sys_msg[1])
|
106
105
|
case "system_tard_state_tunnel":
|
@@ -10,7 +10,7 @@ from pymammotion.data.model import RegionData
|
|
10
10
|
from pymammotion.data.model.device import MowingDevice
|
11
11
|
from pymammotion.data.state_manager import StateManager
|
12
12
|
from pymammotion.proto.luba_msg import LubaMsg
|
13
|
-
from pymammotion.proto.mctrl_nav import NavGetCommDataAck, NavGetHashListAck
|
13
|
+
from pymammotion.proto.mctrl_nav import NavGetCommDataAck, NavGetHashListAck, SvgMessageAckT
|
14
14
|
|
15
15
|
_LOGGER = logging.getLogger(__name__)
|
16
16
|
|
@@ -65,7 +65,7 @@ class MammotionBaseDevice:
|
|
65
65
|
current_frame = missing_frames[0] - 1
|
66
66
|
await self.queue_command("get_hash_response", total_frame=hash_ack.total_frame, current_frame=current_frame)
|
67
67
|
|
68
|
-
async def commdata_response(self, common_data: NavGetCommDataAck) -> None:
|
68
|
+
async def commdata_response(self, common_data: NavGetCommDataAck | SvgMessageAckT) -> None:
|
69
69
|
"""Handle common data responses."""
|
70
70
|
total_frame = common_data.total_frame
|
71
71
|
current_frame = common_data.current_frame
|
@@ -84,8 +84,8 @@ class MammotionBaseDevice:
|
|
84
84
|
current_frame = missing_frames[0] - 1
|
85
85
|
|
86
86
|
region_data = RegionData()
|
87
|
-
region_data.hash = common_data.hash
|
88
|
-
region_data.action = common_data.action
|
87
|
+
region_data.hash = common_data.data_hash if isinstance(common_data, SvgMessageAckT) else common_data.hash
|
88
|
+
region_data.action = common_data.action if isinstance(common_data, NavGetCommDataAck) else None
|
89
89
|
region_data.type = common_data.type
|
90
90
|
region_data.total_frame = total_frame
|
91
91
|
region_data.current_frame = current_frame
|
@@ -72,7 +72,7 @@ class MammotionMixedDeviceManager:
|
|
72
72
|
if self.has_cloud() and self.preference == ConnectionPreference.WIFI:
|
73
73
|
return not self.cloud()._mqtt.command_queue.empty()
|
74
74
|
else:
|
75
|
-
return
|
75
|
+
return not self.ble().command_queue.empty()
|
76
76
|
|
77
77
|
def add_ble(self, ble_device: BLEDevice) -> None:
|
78
78
|
if ble_device is not None:
|
@@ -116,8 +116,9 @@ class MammotionDevices:
|
|
116
116
|
def get_device(self, mammotion_device_name: str) -> MammotionMixedDeviceManager:
|
117
117
|
return self.devices.get(mammotion_device_name)
|
118
118
|
|
119
|
-
async def remove_device(self, name) -> None:
|
119
|
+
async def remove_device(self, name: str) -> None:
|
120
120
|
device_for_removal = self.devices.pop(name)
|
121
|
+
loop = asyncio.get_running_loop()
|
121
122
|
if device_for_removal.has_cloud():
|
122
123
|
should_disconnect = {
|
123
124
|
device
|
@@ -125,7 +126,7 @@ class MammotionDevices:
|
|
125
126
|
if device.cloud() is not None and device.cloud()._mqtt == device_for_removal.cloud()._mqtt
|
126
127
|
}
|
127
128
|
if len(should_disconnect) == 0:
|
128
|
-
device_for_removal.cloud().
|
129
|
+
await loop.run_in_executor(None, device_for_removal.cloud().mqtt.disconnect)
|
129
130
|
await device_for_removal.cloud().stop()
|
130
131
|
if device_for_removal.has_ble():
|
131
132
|
await device_for_removal.ble().stop()
|
@@ -83,17 +83,21 @@ class MammotionBaseBLEDevice(MammotionBaseDevice):
|
|
83
83
|
self._disconnect_timer: asyncio.TimerHandle | None = None
|
84
84
|
self._message: BleMessage | None = None
|
85
85
|
self._commands: MammotionCommand = MammotionCommand(device.name)
|
86
|
+
self.command_queue = asyncio.Queue()
|
86
87
|
self._expected_disconnect = False
|
87
88
|
self._connect_lock = asyncio.Lock()
|
88
89
|
self._operation_lock = asyncio.Lock()
|
89
90
|
self._key: str | None = None
|
90
91
|
self.set_queue_callback(self.queue_command)
|
92
|
+
loop = asyncio.get_event_loop()
|
93
|
+
loop.create_task(self.process_queue())
|
91
94
|
|
92
95
|
def update_device(self, device: BLEDevice) -> None:
|
93
96
|
"""Update the BLE device."""
|
94
97
|
self._device = device
|
95
98
|
|
96
99
|
async def _ble_sync(self) -> None:
|
100
|
+
_LOGGER.debug("BLE SYNC")
|
97
101
|
command_bytes = self._commands.send_todev_ble_sync(2)
|
98
102
|
await self._message.post_custom_data_bytes(command_bytes)
|
99
103
|
|
@@ -114,10 +118,35 @@ class MammotionBaseBLEDevice(MammotionBaseDevice):
|
|
114
118
|
async def stop(self) -> None:
|
115
119
|
"""Stop all tasks and disconnect."""
|
116
120
|
self._ble_sync_task.cancel()
|
117
|
-
|
121
|
+
if self._client is not None:
|
122
|
+
await self._client.disconnect()
|
118
123
|
|
119
124
|
async def queue_command(self, key: str, **kwargs: Any) -> bytes | None:
|
120
|
-
|
125
|
+
# Create a future to hold the result
|
126
|
+
_LOGGER.debug("Queueing command: %s", key)
|
127
|
+
future = asyncio.Future()
|
128
|
+
# Put the command in the queue as a tuple (key, command, future)
|
129
|
+
command_bytes = getattr(self._commands, key)(**kwargs)
|
130
|
+
await self.command_queue.put((key, command_bytes, future))
|
131
|
+
# Wait for the future to be resolved
|
132
|
+
return await future
|
133
|
+
# return await self._send_command_with_args(key, **kwargs)
|
134
|
+
|
135
|
+
async def process_queue(self) -> None:
|
136
|
+
while True:
|
137
|
+
# Get the next item from the queue
|
138
|
+
key, command, future = await self.command_queue.get()
|
139
|
+
try:
|
140
|
+
# Process the command using _execute_command_locked
|
141
|
+
result = await self._send_command_locked(key, command)
|
142
|
+
# Set the result on the future
|
143
|
+
future.set_result(result)
|
144
|
+
except Exception as ex:
|
145
|
+
# Set the exception on the future if something goes wrong
|
146
|
+
future.set_exception(ex)
|
147
|
+
finally:
|
148
|
+
# Mark the task as done
|
149
|
+
self.command_queue.task_done()
|
121
150
|
|
122
151
|
async def _send_command_with_args(self, key: str, **kwargs) -> bytes | None:
|
123
152
|
"""Send command to device and read response."""
|
@@ -255,8 +284,7 @@ class MammotionBaseBLEDevice(MammotionBaseDevice):
|
|
255
284
|
)
|
256
285
|
self._reset_disconnect_timer()
|
257
286
|
await self._start_notify()
|
258
|
-
|
259
|
-
await self._message.post_custom_data_bytes(command_bytes)
|
287
|
+
await self._ble_sync()
|
260
288
|
self.schedule_ble_sync()
|
261
289
|
|
262
290
|
async def _send_command_locked(self, key: str, command: bytes) -> bytes:
|
@@ -9,7 +9,7 @@ from typing import Any, Awaitable, Callable, Optional, cast
|
|
9
9
|
import betterproto
|
10
10
|
|
11
11
|
from pymammotion import CloudIOTGateway, MammotionMQTT
|
12
|
-
from pymammotion.aliyun.cloud_gateway import DeviceOfflineException
|
12
|
+
from pymammotion.aliyun.cloud_gateway import DeviceOfflineException
|
13
13
|
from pymammotion.aliyun.model.dev_by_account_response import Device
|
14
14
|
from pymammotion.data.model.device import MowingDevice
|
15
15
|
from pymammotion.data.mqtt.event import ThingEventMessage
|
@@ -182,15 +182,11 @@ class MammotionBaseCloudDevice(MammotionBaseDevice):
|
|
182
182
|
await self.on_ready_callback()
|
183
183
|
except DeviceOfflineException:
|
184
184
|
await self.stop()
|
185
|
-
except SetupException:
|
186
|
-
await self.stop()
|
187
185
|
|
188
186
|
async def on_disconnect(self) -> None:
|
189
187
|
if self._ble_sync_task:
|
190
188
|
self._ble_sync_task.cancel()
|
191
|
-
loop = asyncio.get_event_loop()
|
192
189
|
self._mqtt.disconnect()
|
193
|
-
await loop.run_in_executor(None, self._mqtt.cloud_client.sign_out)
|
194
190
|
|
195
191
|
async def stop(self) -> None:
|
196
192
|
"""Stop all tasks and disconnect."""
|
@@ -199,6 +195,13 @@ class MammotionBaseCloudDevice(MammotionBaseDevice):
|
|
199
195
|
self._mqtt.on_ready_event.remove_subscribers(self.on_ready)
|
200
196
|
self.stopped = True
|
201
197
|
|
198
|
+
async def start(self) -> None:
|
199
|
+
await self._ble_sync()
|
200
|
+
if self._ble_sync_task is None or self._ble_sync_task.cancelled():
|
201
|
+
await self.run_periodic_sync_task()
|
202
|
+
self.stopped = False
|
203
|
+
self.mqtt.connect_async()
|
204
|
+
|
202
205
|
async def _ble_sync(self) -> None:
|
203
206
|
command_bytes = self._commands.send_todev_ble_sync(3)
|
204
207
|
loop = asyncio.get_running_loop()
|
@@ -150,6 +150,10 @@ message NavGetCommData {
|
|
150
150
|
string reserved = 11;
|
151
151
|
}
|
152
152
|
|
153
|
+
message AreaLabel {
|
154
|
+
string label = 1;
|
155
|
+
}
|
156
|
+
|
153
157
|
message NavGetCommDataAck {
|
154
158
|
int32 pver = 1;
|
155
159
|
int32 subCmd = 2;
|
@@ -165,6 +169,7 @@ message NavGetCommDataAck {
|
|
165
169
|
int32 dataLen = 12;
|
166
170
|
repeated CommDataCouple dataCouple = 13;
|
167
171
|
string reserved = 14;
|
172
|
+
AreaLabel areaLabel = 15;
|
168
173
|
}
|
169
174
|
|
170
175
|
message NavReqCoverPath {
|
pymammotion/proto/mctrl_nav.py
CHANGED
@@ -173,6 +173,9 @@ class NavGetCommData(betterproto.Message):
|
|
173
173
|
data_hash: int = betterproto.fixed64_field(10)
|
174
174
|
reserved: str = betterproto.string_field(11)
|
175
175
|
|
176
|
+
@dataclass
|
177
|
+
class AreaLabel(betterproto.Message):
|
178
|
+
label: str = betterproto.string_field(1)
|
176
179
|
|
177
180
|
@dataclass
|
178
181
|
class NavGetCommDataAck(betterproto.Message):
|
@@ -190,6 +193,7 @@ class NavGetCommDataAck(betterproto.Message):
|
|
190
193
|
data_len: int = betterproto.int32_field(12)
|
191
194
|
data_couple: list["CommDataCouple"] = betterproto.message_field(13)
|
192
195
|
reserved: str = betterproto.string_field(14)
|
196
|
+
area_label: AreaLabel = betterproto.message_field(15)
|
193
197
|
|
194
198
|
|
195
199
|
@dataclass
|
@@ -12,7 +12,7 @@ pymammotion/aliyun/model/stream_subscription_response.py,sha256=po765WASQDboVCos
|
|
12
12
|
pymammotion/aliyun/tmp_constant.py,sha256=M4Hq_lrGB3LZdX6R2XohRPFoK1NDnNV-pTJwJcJ9838,6650
|
13
13
|
pymammotion/bluetooth/__init__.py,sha256=LAl8jqZ1fPh-3mLmViNQsP3s814C1vsocYUa6oSaXt0,36
|
14
14
|
pymammotion/bluetooth/ble.py,sha256=YfkfEK3TLJ8BaidjAXfUVFv8reLCu6U_lYa3Bo0pddw,2449
|
15
|
-
pymammotion/bluetooth/ble_message.py,sha256=
|
15
|
+
pymammotion/bluetooth/ble_message.py,sha256=XzsXcKv29GbGAnivYvZLfDOiMVAWsilk70N4TVwFl50,15448
|
16
16
|
pymammotion/bluetooth/const.py,sha256=CCqyHsYbB0BAYjwdhXt_n6eWWxmhlUrAFjvVv57mbvE,1749
|
17
17
|
pymammotion/bluetooth/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
18
|
pymammotion/bluetooth/data/convert.py,sha256=6DMwvzVr9FWCoQFIKSI2poFXjISc_m6X59g8FlVO0-o,800
|
@@ -29,7 +29,7 @@ pymammotion/data/model/enums.py,sha256=EpKmO8yVUZyEnTY4yH0DMMVKYNQM42zpW1maUu0i3
|
|
29
29
|
pymammotion/data/model/excute_boarder_params.py,sha256=9CpUqrygcle1C_1hDW-riLmm4map4ZbE842NXjcomEI,1394
|
30
30
|
pymammotion/data/model/execute_boarder.py,sha256=9rd_h4fbcsXxgnLOd2rO2hWyD1abnTGc47QTEpp8DD0,1103
|
31
31
|
pymammotion/data/model/generate_route_information.py,sha256=MkUBoqGtCAKmiVQ4Q1pEoDVHZs5uLIo7vhfWT4nGbtY,801
|
32
|
-
pymammotion/data/model/hash_list.py,sha256=
|
32
|
+
pymammotion/data/model/hash_list.py,sha256=ZPg5d1hy4bPMgPw5JkHujT06LIoEmXn7qSdQW79FF3A,6257
|
33
33
|
pymammotion/data/model/location.py,sha256=PwmITejfI4pm7PI4rzqSuuHetwle6IJr_CV95435s2M,871
|
34
34
|
pymammotion/data/model/mowing_modes.py,sha256=5TrHSijUyPtIDWpNtgzx_vFQukRJWRz4gIrUaXggKPw,827
|
35
35
|
pymammotion/data/model/plan.py,sha256=mcadkSL7fQXy0iJ0q786I3GEQY4i6kmQXfW6Ri69lcQ,2906
|
@@ -40,7 +40,7 @@ pymammotion/data/mqtt/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdr
|
|
40
40
|
pymammotion/data/mqtt/event.py,sha256=z6j8t-ZOjEeKjFt7S0wV8vV5L0-iHD3RbwI9hCfzGTY,5044
|
41
41
|
pymammotion/data/mqtt/properties.py,sha256=kvphcjrDuJHuX8Az98-wKeFv_rSmu2Fz9YKLGodGSj0,3759
|
42
42
|
pymammotion/data/mqtt/status.py,sha256=zqnlo-MzejEQZszl0i0Wucoc3E76x6UtI9JLxoBnu54,1067
|
43
|
-
pymammotion/data/state_manager.py,sha256=
|
43
|
+
pymammotion/data/state_manager.py,sha256=vtBT28-5DY58hJMi_kqOUKnOq6rJ4fx1zX8yU7N96A8,5357
|
44
44
|
pymammotion/event/__init__.py,sha256=mgATR6vPHACNQ-0zH5fi7NdzeTCDV1CZyaWPmtUusi8,115
|
45
45
|
pymammotion/event/event.py,sha256=UzYnxV5DfvMDK3E06UvSzvzuBbaXOOUwO6xYt_zn9To,2034
|
46
46
|
pymammotion/http/_init_.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -61,10 +61,10 @@ pymammotion/mammotion/commands/messages/video.py,sha256=ne1YSuQChaDFfmHgMO5Jc9_O
|
|
61
61
|
pymammotion/mammotion/control/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
62
62
|
pymammotion/mammotion/control/joystick.py,sha256=QfBVxM_gxpWsZAGO90whtgxCI2tIZ3TTad9wHIPsU9s,5640
|
63
63
|
pymammotion/mammotion/devices/__init__.py,sha256=f2qQFPgLGmV85W2hSlMUh5BYuht9o_Ar_JEAAMD4fsE,102
|
64
|
-
pymammotion/mammotion/devices/base.py,sha256=
|
65
|
-
pymammotion/mammotion/devices/mammotion.py,sha256=
|
66
|
-
pymammotion/mammotion/devices/mammotion_bluetooth.py,sha256=
|
67
|
-
pymammotion/mammotion/devices/mammotion_cloud.py,sha256=
|
64
|
+
pymammotion/mammotion/devices/base.py,sha256=F_L5aDtY6rgRkk7Q4CwilLenTANW6cBe9zIU3a9HRmA,10020
|
65
|
+
pymammotion/mammotion/devices/mammotion.py,sha256=hSO184o1q4ftfLPx9froFPIXk428wGg8Ayw160W3z7c,12482
|
66
|
+
pymammotion/mammotion/devices/mammotion_bluetooth.py,sha256=_epFjX2ePq2lgLGfowLe1CAxYLi-_4Q_jcvy7L5e5ug,18671
|
67
|
+
pymammotion/mammotion/devices/mammotion_cloud.py,sha256=MIBdakx7rvfrIqiVcq5Ry1qkqRVp1ykvU20vFW4Dg58,12006
|
68
68
|
pymammotion/mqtt/__init__.py,sha256=Ocs5e-HLJvTuDpVXyECEsWIvwsUaxzj7lZ9mSYutNDY,105
|
69
69
|
pymammotion/mqtt/mammotion_future.py,sha256=_OWqKOlUGl2yT1xOsXFQYpGd-1zQ63OxqXgy7KRQgYc,710
|
70
70
|
pymammotion/mqtt/mammotion_mqtt.py,sha256=LaySave_hf0gU3crUTLqzpdQtxIwK8vu5DM8F8fbU2Y,8748
|
@@ -93,8 +93,8 @@ pymammotion/proto/mctrl_driver.proto,sha256=I0BncdAa3laeqT17Sn95r_1HuBD3dSc9IVu9
|
|
93
93
|
pymammotion/proto/mctrl_driver.py,sha256=sseY2MxUtaQZvg7fvbA_gNvtqx9MVDW_rvUcfA2CWVs,2971
|
94
94
|
pymammotion/proto/mctrl_driver_pb2.py,sha256=bfLwZb5Hehb6OIkgFrZMkQ0oTBXoOBxpruszKz-UM1U,3785
|
95
95
|
pymammotion/proto/mctrl_driver_pb2.pyi,sha256=9_rcQELsSeOfeIQMTEFIpeXICpDe3arQeA4kAYWNSWw,5860
|
96
|
-
pymammotion/proto/mctrl_nav.proto,sha256=
|
97
|
-
pymammotion/proto/mctrl_nav.py,sha256=
|
96
|
+
pymammotion/proto/mctrl_nav.proto,sha256=eA7oOZw3Uiy4yAeybYjHkWr-FUjqJ498tsYsChm7rpg,12449
|
97
|
+
pymammotion/proto/mctrl_nav.py,sha256=okOznE_1dCi1yE5sSdQNKWkgI8CpbGRxMAISL5zqiT4,25040
|
98
98
|
pymammotion/proto/mctrl_nav_pb2.py,sha256=LAHfEmGfNVZCN6vuLSZF6s2wd1Qk-siaWe4mdPWPdxc,24213
|
99
99
|
pymammotion/proto/mctrl_nav_pb2.pyi,sha256=qmGYfKh2o63e5ppl9QIWnwDbmGVUVOf7EqhC9ApE5fg,51336
|
100
100
|
pymammotion/proto/mctrl_ota.proto,sha256=4iHr-v1R0QiNndCnv3b6mhXiERLukB67ZzhTgt1iMc0,629
|
@@ -119,7 +119,7 @@ pymammotion/utility/map.py,sha256=GYscVMg2cX3IPlNpCBNHDW0S55yS1WGRf1iHnNZ7TfQ,22
|
|
119
119
|
pymammotion/utility/movement.py,sha256=N75oAoAgFydqoaOedYIxGUHmuTCtPzAOtb-d_29tpfI,615
|
120
120
|
pymammotion/utility/periodic.py,sha256=MbeSb9cfhxzYmdT_RiE0dZe3H9IfbQW_zSqhmSX2RUc,3321
|
121
121
|
pymammotion/utility/rocker_util.py,sha256=6tX7sS87qoQC_tsxbx3NLL-HgS08wtzXiZkhDiz7uo0,7179
|
122
|
-
pymammotion-0.2.
|
123
|
-
pymammotion-0.2.
|
124
|
-
pymammotion-0.2.
|
125
|
-
pymammotion-0.2.
|
122
|
+
pymammotion-0.2.65.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
123
|
+
pymammotion-0.2.65.dist-info/METADATA,sha256=kNunPuA7BQqFxGwNQ2C8kD5_h6RJyyAM8DyVjX8FiSo,3874
|
124
|
+
pymammotion-0.2.65.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
125
|
+
pymammotion-0.2.65.dist-info/RECORD,,
|
File without changes
|
File without changes
|