pymammotion 0.5.69__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/__init__.py +53 -0
- pymammotion/agora/__init__.py +0 -0
- pymammotion/agora/agora_api.py +755 -0
- pymammotion/agora/agora_rtc_capabilities.py +748 -0
- pymammotion/agora/agora_websockets.py +1175 -0
- pymammotion/aliyun/__init__.py +1 -0
- pymammotion/aliyun/client.py +235 -0
- pymammotion/aliyun/cloud_gateway.py +982 -0
- pymammotion/aliyun/model/aep_response.py +21 -0
- pymammotion/aliyun/model/connect_response.py +51 -0
- pymammotion/aliyun/model/dev_by_account_response.py +195 -0
- pymammotion/aliyun/model/login_by_oauth_response.py +64 -0
- pymammotion/aliyun/model/regions_response.py +29 -0
- pymammotion/aliyun/model/session_by_authcode_response.py +19 -0
- pymammotion/aliyun/model/thing_response.py +12 -0
- pymammotion/aliyun/regions.py +62 -0
- pymammotion/aliyun/tea/core.py +297 -0
- pymammotion/aliyun/tmp_constant.py +171 -0
- pymammotion/bluetooth/__init__.py +1 -0
- pymammotion/bluetooth/ble.py +62 -0
- pymammotion/bluetooth/ble_message.py +676 -0
- pymammotion/bluetooth/const.py +27 -0
- pymammotion/bluetooth/data/__init__.py +0 -0
- pymammotion/bluetooth/data/convert.py +25 -0
- pymammotion/bluetooth/data/framectrldata.py +40 -0
- pymammotion/bluetooth/data/notifydata.py +62 -0
- pymammotion/bluetooth/model/__init__.py +0 -0
- pymammotion/bluetooth/model/atomic_integer.py +54 -0
- pymammotion/const.py +13 -0
- pymammotion/data/__init__.py +0 -0
- pymammotion/data/model/__init__.py +8 -0
- pymammotion/data/model/account.py +8 -0
- pymammotion/data/model/device.py +192 -0
- pymammotion/data/model/device_config.py +72 -0
- pymammotion/data/model/device_info.py +60 -0
- pymammotion/data/model/device_limits.py +49 -0
- pymammotion/data/model/enums.py +77 -0
- pymammotion/data/model/errors.py +12 -0
- pymammotion/data/model/events.py +14 -0
- pymammotion/data/model/generate_geojson.py +565 -0
- pymammotion/data/model/generate_route_information.py +26 -0
- pymammotion/data/model/hash_list.py +475 -0
- pymammotion/data/model/location.py +36 -0
- pymammotion/data/model/mowing_modes.py +77 -0
- pymammotion/data/model/rapid_state.py +45 -0
- pymammotion/data/model/raw_data.py +215 -0
- pymammotion/data/model/region_data.py +102 -0
- pymammotion/data/model/report_info.py +182 -0
- pymammotion/data/model/work.py +27 -0
- pymammotion/data/mower_state_manager.py +369 -0
- pymammotion/data/mqtt/__init__.py +1 -0
- pymammotion/data/mqtt/event.py +227 -0
- pymammotion/data/mqtt/mammotion_properties.py +276 -0
- pymammotion/data/mqtt/properties.py +203 -0
- pymammotion/data/mqtt/status.py +57 -0
- pymammotion/event/__init__.py +6 -0
- pymammotion/event/event.py +96 -0
- pymammotion/homeassistant/__init__.py +3 -0
- pymammotion/homeassistant/mower_api.py +514 -0
- pymammotion/homeassistant/rtk_api.py +54 -0
- pymammotion/http/__init__.py +0 -0
- pymammotion/http/encryption.py +220 -0
- pymammotion/http/http.py +673 -0
- pymammotion/http/model/__init__.py +0 -0
- pymammotion/http/model/camera_stream.py +31 -0
- pymammotion/http/model/http.py +249 -0
- pymammotion/http/model/response_factory.py +61 -0
- pymammotion/http/model/rtk.py +16 -0
- pymammotion/mammotion/__init__.py +0 -0
- pymammotion/mammotion/commands/__init__.py +0 -0
- pymammotion/mammotion/commands/abstract_message.py +24 -0
- pymammotion/mammotion/commands/mammotion_command.py +81 -0
- pymammotion/mammotion/commands/messages/__init__.py +0 -0
- pymammotion/mammotion/commands/messages/basestation.py +43 -0
- pymammotion/mammotion/commands/messages/driver.py +122 -0
- pymammotion/mammotion/commands/messages/media.py +87 -0
- pymammotion/mammotion/commands/messages/navigation.py +564 -0
- pymammotion/mammotion/commands/messages/network.py +205 -0
- pymammotion/mammotion/commands/messages/ota.py +38 -0
- pymammotion/mammotion/commands/messages/system.py +330 -0
- pymammotion/mammotion/commands/messages/video.py +33 -0
- pymammotion/mammotion/control/__init__.py +0 -0
- pymammotion/mammotion/control/joystick.py +145 -0
- pymammotion/mammotion/devices/__init__.py +29 -0
- pymammotion/mammotion/devices/base.py +163 -0
- pymammotion/mammotion/devices/mammotion.py +571 -0
- pymammotion/mammotion/devices/mammotion_bluetooth.py +496 -0
- pymammotion/mammotion/devices/mammotion_cloud.py +355 -0
- pymammotion/mammotion/devices/mammotion_mower_ble.py +48 -0
- pymammotion/mammotion/devices/mammotion_mower_cloud.py +39 -0
- pymammotion/mammotion/devices/managers/managers.py +81 -0
- pymammotion/mammotion/devices/mower_device.py +120 -0
- pymammotion/mammotion/devices/mower_manager.py +107 -0
- pymammotion/mammotion/devices/rtk_ble.py +89 -0
- pymammotion/mammotion/devices/rtk_cloud.py +115 -0
- pymammotion/mammotion/devices/rtk_device.py +50 -0
- pymammotion/mammotion/devices/rtk_manager.py +125 -0
- pymammotion/mqtt/__init__.py +6 -0
- pymammotion/mqtt/aliyun_mqtt.py +237 -0
- pymammotion/mqtt/linkkit/__init__.py +5 -0
- pymammotion/mqtt/linkkit/h2client.py +585 -0
- pymammotion/mqtt/linkkit/linkkit.py +3025 -0
- pymammotion/mqtt/mammotion_future.py +26 -0
- pymammotion/mqtt/mammotion_mqtt.py +214 -0
- pymammotion/mqtt/mqtt_models.py +66 -0
- pymammotion/proto/__init__.py +4841 -0
- pymammotion/proto/basestation.proto +51 -0
- pymammotion/proto/basestation_pb2.py +35 -0
- pymammotion/proto/basestation_pb2.pyi +89 -0
- pymammotion/proto/common.proto +7 -0
- pymammotion/proto/common_pb2.py +25 -0
- pymammotion/proto/common_pb2.pyi +13 -0
- pymammotion/proto/dev_net.proto +321 -0
- pymammotion/proto/dev_net_pb2.py +111 -0
- pymammotion/proto/dev_net_pb2.pyi +515 -0
- pymammotion/proto/luba_msg.proto +76 -0
- pymammotion/proto/luba_msg_pb2.py +41 -0
- pymammotion/proto/luba_msg_pb2.pyi +97 -0
- pymammotion/proto/luba_mul.proto +129 -0
- pymammotion/proto/luba_mul_pb2.py +61 -0
- pymammotion/proto/luba_mul_pb2.pyi +178 -0
- pymammotion/proto/mctrl_driver.proto +107 -0
- pymammotion/proto/mctrl_driver_pb2.py +57 -0
- pymammotion/proto/mctrl_driver_pb2.pyi +167 -0
- pymammotion/proto/mctrl_nav.proto +591 -0
- pymammotion/proto/mctrl_nav_pb2.py +136 -0
- pymammotion/proto/mctrl_nav_pb2.pyi +1067 -0
- pymammotion/proto/mctrl_ota.proto +80 -0
- pymammotion/proto/mctrl_ota_pb2.py +45 -0
- pymammotion/proto/mctrl_ota_pb2.pyi +128 -0
- pymammotion/proto/mctrl_pept.proto +34 -0
- pymammotion/proto/mctrl_pept_pb2.py +33 -0
- pymammotion/proto/mctrl_pept_pb2.pyi +58 -0
- pymammotion/proto/mctrl_sys.proto +741 -0
- pymammotion/proto/mctrl_sys_pb2.py +206 -0
- pymammotion/proto/mctrl_sys_pb2.pyi +1213 -0
- pymammotion/proto/message_pool.py +3 -0
- pymammotion/proto/py.typed +0 -0
- pymammotion/py.typed +0 -0
- pymammotion/utility/constant/__init__.py +3 -0
- pymammotion/utility/constant/device_constant.py +315 -0
- pymammotion/utility/conversions.py +5 -0
- pymammotion/utility/datatype_converter.py +124 -0
- pymammotion/utility/device_config.py +755 -0
- pymammotion/utility/device_type.py +489 -0
- pymammotion/utility/map.py +259 -0
- pymammotion/utility/movement.py +18 -0
- pymammotion/utility/mur_mur_hash.py +159 -0
- pymammotion/utility/periodic.py +106 -0
- pymammotion/utility/rocker_util.py +194 -0
- pymammotion-0.5.69.dist-info/METADATA +93 -0
- pymammotion-0.5.69.dist-info/RECORD +154 -0
- pymammotion-0.5.69.dist-info/WHEEL +4 -0
- pymammotion-0.5.69.dist-info/licenses/LICENSE +674 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from timeit import default_timer as timer
|
|
3
|
+
|
|
4
|
+
import nest_asyncio
|
|
5
|
+
import pyjoystick
|
|
6
|
+
from pyjoystick.sdl2 import Key, run_event_loop
|
|
7
|
+
from pyjoystick.utils import PeriodicThread
|
|
8
|
+
|
|
9
|
+
from pymammotion.event import BleNotificationEvent
|
|
10
|
+
from pymammotion.mammotion.devices import MammotionBaseBLEDevice
|
|
11
|
+
from pymammotion.utility.movement import get_percent, transform_both_speeds
|
|
12
|
+
|
|
13
|
+
bleNotificationEvt = BleNotificationEvent()
|
|
14
|
+
|
|
15
|
+
nest_asyncio.apply()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class JoystickControl:
|
|
19
|
+
"""Joystick class for controlling Luba with a joystick"""
|
|
20
|
+
|
|
21
|
+
angular_percent = 0
|
|
22
|
+
linear_percent = 0
|
|
23
|
+
linear_speed = 0
|
|
24
|
+
angular_speed = 0
|
|
25
|
+
ignore_events = False
|
|
26
|
+
_blade_height = 25
|
|
27
|
+
worker = None
|
|
28
|
+
|
|
29
|
+
def __init__(self, luba_ble: MammotionBaseBLEDevice) -> None:
|
|
30
|
+
self._client = luba_ble
|
|
31
|
+
self._curr_time = timer()
|
|
32
|
+
self.stopped = False
|
|
33
|
+
|
|
34
|
+
repeater = pyjoystick.HatRepeater(first_repeat_timeout=0.2, repeat_timeout=0.03, check_timeout=0.01)
|
|
35
|
+
|
|
36
|
+
self.mngr = pyjoystick.ThreadEventManager(
|
|
37
|
+
event_loop=run_event_loop,
|
|
38
|
+
handle_key_event=self.key_received,
|
|
39
|
+
add_joystick=self.print_add,
|
|
40
|
+
remove_joystick=self.print_remove,
|
|
41
|
+
button_repeater=repeater,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
self.worker = PeriodicThread(0.2, self.run_movement, name="luba-process_movements")
|
|
45
|
+
self.worker.alive = self.mngr.alive # stop when this event stops
|
|
46
|
+
self.worker.daemon = True
|
|
47
|
+
|
|
48
|
+
def _movement_finished(self) -> None:
|
|
49
|
+
self.ignore_events = False
|
|
50
|
+
|
|
51
|
+
def run_movement(self) -> None:
|
|
52
|
+
if self.linear_percent == 0.0 and self.angular_percent == 0.0:
|
|
53
|
+
if self.stopped:
|
|
54
|
+
return
|
|
55
|
+
self.stopped = True
|
|
56
|
+
self.stopped = False
|
|
57
|
+
(linear_speed, angular_speed) = transform_both_speeds(
|
|
58
|
+
self.linear_speed,
|
|
59
|
+
self.angular_speed,
|
|
60
|
+
self.linear_percent,
|
|
61
|
+
self.angular_percent,
|
|
62
|
+
)
|
|
63
|
+
asyncio.run(self._client.command("send_movement", linear_speed=linear_speed, angular_speed=angular_speed))
|
|
64
|
+
|
|
65
|
+
def print_add(self, joy) -> None:
|
|
66
|
+
print("Added", joy)
|
|
67
|
+
|
|
68
|
+
def print_remove(self, joy) -> None:
|
|
69
|
+
print("Removed", joy)
|
|
70
|
+
|
|
71
|
+
def key_received(self, key) -> None:
|
|
72
|
+
self.handle_key_received(key)
|
|
73
|
+
|
|
74
|
+
def run_controller(self) -> None:
|
|
75
|
+
self.mngr.start()
|
|
76
|
+
self.worker.start()
|
|
77
|
+
|
|
78
|
+
def handle_key_received(self, key) -> None:
|
|
79
|
+
# print(key, "-", key.keytype, "-", key.number, "-", key.value)
|
|
80
|
+
|
|
81
|
+
if key.keytype is Key.BUTTON and key.value == 1:
|
|
82
|
+
# print(key, "-", key.keytype, "-", key.number, "-", key.value)
|
|
83
|
+
if key.number == 0: # x
|
|
84
|
+
asyncio.run(self._client.command("return_to_dock"))
|
|
85
|
+
if key.number == 1:
|
|
86
|
+
asyncio.run(self._client.command("leave_dock"))
|
|
87
|
+
if key.number == 3:
|
|
88
|
+
asyncio.run(self._client.command("set_blade_control", on_off=1))
|
|
89
|
+
if key.number == 2:
|
|
90
|
+
asyncio.run(self._client.command("set_blade_control", on_off=0))
|
|
91
|
+
if key.number == 9:
|
|
92
|
+
# lower knife height
|
|
93
|
+
if self._blade_height > 25:
|
|
94
|
+
self._blade_height -= 5
|
|
95
|
+
asyncio.run(self._client.command("set_blade_height", height=self._blade_height))
|
|
96
|
+
if key.number == 10:
|
|
97
|
+
# raise knife height
|
|
98
|
+
if self._blade_height < 60:
|
|
99
|
+
self._blade_height += 5
|
|
100
|
+
asyncio.run(self._client.command("set_blade_height", height=self._blade_height))
|
|
101
|
+
|
|
102
|
+
if key.keytype is Key.AXIS:
|
|
103
|
+
# print(key, "-", key.keytype, "-", key.number, "-", key.value)
|
|
104
|
+
if key.value > 0.09 or key.value < -0.09:
|
|
105
|
+
match key.number:
|
|
106
|
+
case 1: # left (up down)
|
|
107
|
+
# take left right values and convert to linear movement
|
|
108
|
+
# -1 is forward
|
|
109
|
+
# 1 is back
|
|
110
|
+
|
|
111
|
+
# linear_speed==1000
|
|
112
|
+
# linear_speed==-1000
|
|
113
|
+
print("case 1")
|
|
114
|
+
if key.value > 0:
|
|
115
|
+
"""Backwards."""
|
|
116
|
+
self.linear_speed = 270.0
|
|
117
|
+
self.linear_percent = get_percent(abs(key.value * 100))
|
|
118
|
+
else:
|
|
119
|
+
"""Forwards."""
|
|
120
|
+
self.linear_speed = 90.0
|
|
121
|
+
self.linear_percent = get_percent(abs(key.value * 100))
|
|
122
|
+
|
|
123
|
+
case 2: # right (left right)
|
|
124
|
+
# take left right values and convert to angular movement
|
|
125
|
+
# -1 left
|
|
126
|
+
# 1 is right
|
|
127
|
+
# angular_speed==-450
|
|
128
|
+
# angular_speed==450
|
|
129
|
+
if key.value > 0:
|
|
130
|
+
self.angular_speed = 0.0
|
|
131
|
+
self.angular_percent = get_percent(abs(key.value * 100))
|
|
132
|
+
else:
|
|
133
|
+
# angle=180.0
|
|
134
|
+
# linear_speed=0//angular_speed=-450
|
|
135
|
+
self.angular_speed = 180.0
|
|
136
|
+
self.angular_percent = get_percent(abs(key.value * 100))
|
|
137
|
+
|
|
138
|
+
else:
|
|
139
|
+
match key.number:
|
|
140
|
+
case 1: # left (up down)
|
|
141
|
+
self.linear_speed = 0.0
|
|
142
|
+
self.linear_percent = 0.0
|
|
143
|
+
case 2: # right (left right)
|
|
144
|
+
self.angular_speed = 0.0
|
|
145
|
+
self.angular_percent = 0.0
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Mammotion devices module."""
|
|
2
|
+
|
|
3
|
+
from .mammotion import Mammotion, MammotionDeviceManager
|
|
4
|
+
from .mammotion_bluetooth import MammotionBaseBLEDevice
|
|
5
|
+
from .mammotion_cloud import MammotionBaseCloudDevice, MammotionCloud
|
|
6
|
+
from .mammotion_mower_ble import MammotionMowerBLEDevice
|
|
7
|
+
from .mammotion_mower_cloud import MammotionMowerCloudDevice
|
|
8
|
+
from .mower_device import MammotionMowerDevice
|
|
9
|
+
from .mower_manager import MammotionMowerDeviceManager
|
|
10
|
+
from .rtk_ble import MammotionRTKBLEDevice
|
|
11
|
+
from .rtk_cloud import MammotionRTKCloudDevice
|
|
12
|
+
from .rtk_device import MammotionRTKDevice
|
|
13
|
+
from .rtk_manager import MammotionRTKDeviceManager
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"Mammotion",
|
|
17
|
+
"MammotionDeviceManager",
|
|
18
|
+
"MammotionMowerDeviceManager",
|
|
19
|
+
"MammotionBaseBLEDevice",
|
|
20
|
+
"MammotionBaseCloudDevice",
|
|
21
|
+
"MammotionCloud",
|
|
22
|
+
"MammotionMowerBLEDevice",
|
|
23
|
+
"MammotionMowerCloudDevice",
|
|
24
|
+
"MammotionMowerDevice",
|
|
25
|
+
"MammotionRTKBLEDevice",
|
|
26
|
+
"MammotionRTKCloudDevice",
|
|
27
|
+
"MammotionRTKDevice",
|
|
28
|
+
"MammotionRTKDeviceManager",
|
|
29
|
+
]
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
from abc import ABC, abstractmethod
|
|
2
|
+
import asyncio
|
|
3
|
+
import logging
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
import betterproto2
|
|
7
|
+
|
|
8
|
+
from pymammotion.aliyun.model.dev_by_account_response import Device
|
|
9
|
+
from pymammotion.data.model.device import MowingDevice
|
|
10
|
+
from pymammotion.data.model.raw_data import RawMowerData
|
|
11
|
+
from pymammotion.data.mower_state_manager import MowerStateManager
|
|
12
|
+
from pymammotion.proto import LubaMsg
|
|
13
|
+
|
|
14
|
+
_LOGGER = logging.getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class MammotionBaseDevice(ABC):
|
|
18
|
+
"""Base class for Mammotion devices."""
|
|
19
|
+
|
|
20
|
+
def __init__(self, state_manager: MowerStateManager, cloud_device: Device) -> None:
|
|
21
|
+
"""Initialize MammotionBaseDevice."""
|
|
22
|
+
self.loop = asyncio.get_event_loop()
|
|
23
|
+
self._state_manager = state_manager
|
|
24
|
+
self._raw_data = dict()
|
|
25
|
+
self._raw_mower_data: RawMowerData = RawMowerData()
|
|
26
|
+
self._notify_future: asyncio.Future[bytes] | None = None
|
|
27
|
+
self._cloud_device = cloud_device
|
|
28
|
+
|
|
29
|
+
def _update_raw_data(self, data: bytes) -> None:
|
|
30
|
+
"""Update raw and model data from notifications."""
|
|
31
|
+
tmp_msg = LubaMsg().parse(data)
|
|
32
|
+
res = betterproto2.which_one_of(tmp_msg, "LubaSubMsg")
|
|
33
|
+
match res[0]:
|
|
34
|
+
case "nav":
|
|
35
|
+
self._update_nav_data(tmp_msg)
|
|
36
|
+
case "sys":
|
|
37
|
+
self._update_sys_data(tmp_msg)
|
|
38
|
+
case "driver":
|
|
39
|
+
self._update_driver_data(tmp_msg)
|
|
40
|
+
case "net":
|
|
41
|
+
self._update_net_data(tmp_msg)
|
|
42
|
+
case "mul":
|
|
43
|
+
self._update_mul_data(tmp_msg)
|
|
44
|
+
case "ota":
|
|
45
|
+
self._update_ota_data(tmp_msg)
|
|
46
|
+
|
|
47
|
+
self._raw_mower_data.update_raw(self._raw_data)
|
|
48
|
+
|
|
49
|
+
def _update_nav_data(self, tmp_msg) -> None:
|
|
50
|
+
"""Update navigation data."""
|
|
51
|
+
nav_sub_msg = betterproto2.which_one_of(tmp_msg.nav, "SubNavMsg")
|
|
52
|
+
if nav_sub_msg[1] is None:
|
|
53
|
+
_LOGGER.debug("Sub message was NoneType %s", nav_sub_msg[0])
|
|
54
|
+
return
|
|
55
|
+
nav = self._raw_data.get("nav", {})
|
|
56
|
+
if isinstance(nav_sub_msg[1], int):
|
|
57
|
+
nav[nav_sub_msg[0]] = nav_sub_msg[1]
|
|
58
|
+
else:
|
|
59
|
+
nav[nav_sub_msg[0]] = nav_sub_msg[1].to_dict(casing=betterproto2.Casing.SNAKE)
|
|
60
|
+
self._raw_data["nav"] = nav
|
|
61
|
+
|
|
62
|
+
def _update_sys_data(self, tmp_msg: LubaMsg) -> None:
|
|
63
|
+
"""Update system data."""
|
|
64
|
+
sys_sub_msg = betterproto2.which_one_of(tmp_msg.sys, "SubSysMsg")
|
|
65
|
+
if sys_sub_msg[1] is None:
|
|
66
|
+
_LOGGER.debug("Sub message was NoneType %s", sys_sub_msg[0])
|
|
67
|
+
return
|
|
68
|
+
sys = self._raw_data.get("sys", {})
|
|
69
|
+
sys[sys_sub_msg[0]] = sys_sub_msg[1].to_dict(casing=betterproto2.Casing.SNAKE)
|
|
70
|
+
self._raw_data["sys"] = sys
|
|
71
|
+
|
|
72
|
+
def _update_driver_data(self, tmp_msg: LubaMsg) -> None:
|
|
73
|
+
"""Update driver data."""
|
|
74
|
+
drv_sub_msg = betterproto2.which_one_of(tmp_msg.driver, "SubDrvMsg")
|
|
75
|
+
if drv_sub_msg[1] is None:
|
|
76
|
+
_LOGGER.debug("Sub message was NoneType %s", drv_sub_msg[0])
|
|
77
|
+
return
|
|
78
|
+
drv = self._raw_data.get("driver", {})
|
|
79
|
+
drv[drv_sub_msg[0]] = drv_sub_msg[1].to_dict(casing=betterproto2.Casing.SNAKE)
|
|
80
|
+
self._raw_data["driver"] = drv
|
|
81
|
+
|
|
82
|
+
def _update_net_data(self, tmp_msg: LubaMsg) -> None:
|
|
83
|
+
"""Update network data."""
|
|
84
|
+
net_sub_msg = betterproto2.which_one_of(tmp_msg.net, "NetSubType")
|
|
85
|
+
if net_sub_msg[1] is None:
|
|
86
|
+
_LOGGER.debug("Sub message was NoneType %s", net_sub_msg[0])
|
|
87
|
+
return
|
|
88
|
+
net = self._raw_data.get("net", {})
|
|
89
|
+
if isinstance(net_sub_msg[1], int):
|
|
90
|
+
net[net_sub_msg[0]] = net_sub_msg[1]
|
|
91
|
+
else:
|
|
92
|
+
net[net_sub_msg[0]] = net_sub_msg[1].to_dict(casing=betterproto2.Casing.SNAKE)
|
|
93
|
+
self._raw_data["net"] = net
|
|
94
|
+
|
|
95
|
+
def _update_mul_data(self, tmp_msg: LubaMsg) -> None:
|
|
96
|
+
"""Update mul data."""
|
|
97
|
+
mul_sub_msg = betterproto2.which_one_of(tmp_msg.mul, "SubMul")
|
|
98
|
+
if mul_sub_msg[1] is None:
|
|
99
|
+
_LOGGER.debug("Sub message was NoneType %s", mul_sub_msg[0])
|
|
100
|
+
return
|
|
101
|
+
mul = self._raw_data.get("mul", {})
|
|
102
|
+
mul[mul_sub_msg[0]] = mul_sub_msg[1].to_dict(casing=betterproto2.Casing.SNAKE)
|
|
103
|
+
self._raw_data["mul"] = mul
|
|
104
|
+
|
|
105
|
+
def _update_ota_data(self, tmp_msg: LubaMsg) -> None:
|
|
106
|
+
"""Update OTA data."""
|
|
107
|
+
ota_sub_msg = betterproto2.which_one_of(tmp_msg.ota, "SubOtaMsg")
|
|
108
|
+
if ota_sub_msg[1] is None:
|
|
109
|
+
_LOGGER.debug("Sub message was NoneType %s", ota_sub_msg[0])
|
|
110
|
+
return
|
|
111
|
+
ota = self._raw_data.get("ota", {})
|
|
112
|
+
ota[ota_sub_msg[0]] = ota_sub_msg[1].to_dict(casing=betterproto2.Casing.SNAKE)
|
|
113
|
+
self._raw_data["ota"] = ota
|
|
114
|
+
|
|
115
|
+
@property
|
|
116
|
+
def raw_data(self) -> dict[str, Any]:
|
|
117
|
+
"""Get the raw data of the device."""
|
|
118
|
+
return self._raw_data
|
|
119
|
+
|
|
120
|
+
@property
|
|
121
|
+
def mower(self) -> MowingDevice:
|
|
122
|
+
"""Get the LubaMsg of the device."""
|
|
123
|
+
return self._state_manager.get_device()
|
|
124
|
+
|
|
125
|
+
@abstractmethod
|
|
126
|
+
async def queue_command(self, key: str, **kwargs: Any) -> None:
|
|
127
|
+
"""Queue commands to mower."""
|
|
128
|
+
|
|
129
|
+
@abstractmethod
|
|
130
|
+
async def _ble_sync(self) -> None:
|
|
131
|
+
"""Send ble sync command every 3 seconds or sooner."""
|
|
132
|
+
|
|
133
|
+
@abstractmethod
|
|
134
|
+
def stop(self) -> None:
|
|
135
|
+
"""Stop everything ready for destroying."""
|
|
136
|
+
|
|
137
|
+
async def async_read_settings(self) -> None:
|
|
138
|
+
"""Read settings from device."""
|
|
139
|
+
# no cutting in rain nav_sys_param_cmd (id 3 context 1/0)
|
|
140
|
+
await self.queue_command("read_write_device", rw_id=3, context=1, rw=0)
|
|
141
|
+
# ??
|
|
142
|
+
await self.queue_command("read_write_device", rw_id=4, context=1, rw=0)
|
|
143
|
+
# turning mode nav_sys_param_cmd (id 6, context 1/0)
|
|
144
|
+
await self.queue_command("read_write_device", rw_id=6, context=1, rw=0)
|
|
145
|
+
# traversal mode
|
|
146
|
+
await self.queue_command("read_write_device", rw_id=7, context=1, rw=0)
|
|
147
|
+
|
|
148
|
+
await self.queue_command("read_and_set_sidelight", is_sidelight=True, operate=1)
|
|
149
|
+
|
|
150
|
+
await self.queue_command("read_and_set_rtk_pairing_code", op=1, cfg="")
|
|
151
|
+
|
|
152
|
+
async def async_get_errors(self) -> None:
|
|
153
|
+
"""Error codes."""
|
|
154
|
+
await self.queue_command("read_write_device", rw_id=5, rw=1, context=2)
|
|
155
|
+
await self.queue_command("read_write_device", rw_id=5, rw=1, context=3)
|
|
156
|
+
|
|
157
|
+
async def command(self, key: str, **kwargs: Any) -> None:
|
|
158
|
+
"""Send a command to the device."""
|
|
159
|
+
await self.queue_command(key, **kwargs)
|
|
160
|
+
|
|
161
|
+
@property
|
|
162
|
+
def state_manager(self) -> MowerStateManager:
|
|
163
|
+
return self._state_manager
|