pymammotion 0.4.0a9__tar.gz → 0.4.0b1__tar.gz

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.
Files changed (134) hide show
  1. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/PKG-INFO +1 -1
  2. pymammotion-0.4.0b1/pymammotion/data/state_manager.py +173 -0
  3. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/commands/messages/video.py +2 -5
  4. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/devices/base.py +0 -9
  5. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/devices/mammotion_bluetooth.py +9 -0
  6. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/devices/mammotion_cloud.py +8 -0
  7. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pyproject.toml +2 -2
  8. pymammotion-0.4.0a9/pymammotion/data/state_manager.py +0 -147
  9. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/LICENSE +0 -0
  10. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/README.md +0 -0
  11. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/__init__.py +0 -0
  12. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/aliyun/__init__.py +0 -0
  13. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/aliyun/cloud_gateway.py +0 -0
  14. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/aliyun/model/aep_response.py +0 -0
  15. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/aliyun/model/connect_response.py +0 -0
  16. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/aliyun/model/dev_by_account_response.py +0 -0
  17. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/aliyun/model/login_by_oauth_response.py +0 -0
  18. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/aliyun/model/regions_response.py +0 -0
  19. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/aliyun/model/session_by_authcode_response.py +0 -0
  20. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/aliyun/model/stream_subscription_response.py +0 -0
  21. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/aliyun/tmp_constant.py +0 -0
  22. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/bluetooth/__init__.py +0 -0
  23. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/bluetooth/ble.py +0 -0
  24. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/bluetooth/ble_message.py +0 -0
  25. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/bluetooth/const.py +0 -0
  26. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/bluetooth/data/__init__.py +0 -0
  27. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/bluetooth/data/convert.py +0 -0
  28. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/bluetooth/data/framectrldata.py +0 -0
  29. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/bluetooth/data/notifydata.py +0 -0
  30. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/bluetooth/model/__init__.py +0 -0
  31. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/bluetooth/model/atomic_integer.py +0 -0
  32. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/const.py +0 -0
  33. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/__init__.py +0 -0
  34. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/__init__.py +0 -0
  35. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/account.py +0 -0
  36. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/device.py +0 -0
  37. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/device_config.py +0 -0
  38. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/device_info.py +0 -0
  39. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/device_limits.py +0 -0
  40. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/enums.py +0 -0
  41. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/excute_boarder_params.py +0 -0
  42. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/execute_boarder.py +0 -0
  43. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/generate_route_information.py +0 -0
  44. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/hash_list.py +0 -0
  45. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/location.py +0 -0
  46. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/mowing_modes.py +0 -0
  47. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/plan.py +0 -0
  48. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/rapid_state.py +0 -0
  49. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/raw_data.py +0 -0
  50. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/region_data.py +0 -0
  51. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/model/report_info.py +0 -0
  52. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/mqtt/__init__.py +0 -0
  53. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/mqtt/event.py +0 -0
  54. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/mqtt/properties.py +0 -0
  55. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/data/mqtt/status.py +0 -0
  56. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/event/__init__.py +0 -0
  57. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/event/event.py +0 -0
  58. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/http/_init_.py +0 -0
  59. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/http/encryption.py +0 -0
  60. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/http/http.py +0 -0
  61. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/http/model/http.py +0 -0
  62. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/__init__.py +0 -0
  63. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/commands/__init__.py +0 -0
  64. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/commands/abstract_message.py +0 -0
  65. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/commands/mammotion_command.py +0 -0
  66. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/commands/messages/__init__.py +0 -0
  67. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/commands/messages/driver.py +0 -0
  68. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/commands/messages/media.py +0 -0
  69. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/commands/messages/navigation.py +0 -0
  70. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/commands/messages/network.py +0 -0
  71. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/commands/messages/ota.py +0 -0
  72. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/commands/messages/system.py +0 -0
  73. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/control/__init__.py +0 -0
  74. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/control/joystick.py +0 -0
  75. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/devices/__init__.py +0 -0
  76. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mammotion/devices/mammotion.py +0 -0
  77. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mqtt/__init__.py +0 -0
  78. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mqtt/linkkit/__init__.py +0 -0
  79. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mqtt/linkkit/h2client.py +0 -0
  80. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mqtt/linkkit/linkkit.py +0 -0
  81. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mqtt/mammotion_future.py +0 -0
  82. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/mqtt/mammotion_mqtt.py +0 -0
  83. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/__init__.py +0 -0
  84. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/basestation.proto +0 -0
  85. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/basestation.py +0 -0
  86. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/basestation_pb2.py +0 -0
  87. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/basestation_pb2.pyi +0 -0
  88. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/common.proto +0 -0
  89. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/common.py +0 -0
  90. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/common_pb2.py +0 -0
  91. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/common_pb2.pyi +0 -0
  92. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/dev_net.proto +0 -0
  93. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/dev_net.py +0 -0
  94. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/dev_net_pb2.py +0 -0
  95. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/dev_net_pb2.pyi +0 -0
  96. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/luba_msg.proto +0 -0
  97. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/luba_msg.py +0 -0
  98. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/luba_msg_pb2.py +0 -0
  99. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/luba_msg_pb2.pyi +0 -0
  100. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/luba_mul.proto +0 -0
  101. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/luba_mul.py +0 -0
  102. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/luba_mul_pb2.py +0 -0
  103. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/luba_mul_pb2.pyi +0 -0
  104. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_driver.proto +0 -0
  105. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_driver.py +0 -0
  106. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_driver_pb2.py +0 -0
  107. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_driver_pb2.pyi +0 -0
  108. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_nav.proto +0 -0
  109. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_nav.py +0 -0
  110. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_nav_pb2.py +0 -0
  111. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_nav_pb2.pyi +0 -0
  112. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_ota.proto +0 -0
  113. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_ota.py +0 -0
  114. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_ota_pb2.py +0 -0
  115. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_ota_pb2.pyi +0 -0
  116. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_pept.proto +0 -0
  117. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_pept.py +0 -0
  118. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_pept_pb2.py +0 -0
  119. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_pept_pb2.pyi +0 -0
  120. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_sys.proto +0 -0
  121. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_sys.py +0 -0
  122. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_sys_pb2.py +0 -0
  123. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/proto/mctrl_sys_pb2.pyi +0 -0
  124. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/py.typed +0 -0
  125. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/utility/constant/__init__.py +0 -0
  126. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/utility/constant/device_constant.py +0 -0
  127. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/utility/conversions.py +0 -0
  128. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/utility/datatype_converter.py +0 -0
  129. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/utility/device_config.py +0 -0
  130. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/utility/device_type.py +0 -0
  131. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/utility/map.py +0 -0
  132. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/utility/movement.py +0 -0
  133. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/utility/periodic.py +0 -0
  134. {pymammotion-0.4.0a9 → pymammotion-0.4.0b1}/pymammotion/utility/rocker_util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: pymammotion
3
- Version: 0.4.0a9
3
+ Version: 0.4.0b1
4
4
  Summary:
5
5
  License: GPL-3.0
6
6
  Author: Michael Arthur
@@ -0,0 +1,173 @@
1
+ """Manage state from notifications into MowingDevice."""
2
+
3
+ from collections.abc import Awaitable, Callable
4
+ from datetime import datetime
5
+ import logging
6
+ from typing import Any
7
+
8
+ import betterproto
9
+
10
+ from pymammotion.data.model.device import MowingDevice
11
+ from pymammotion.data.model.device_info import SideLight
12
+ from pymammotion.data.model.hash_list import AreaHashNameList
13
+ from pymammotion.data.mqtt.properties import ThingPropertiesMessage
14
+ from pymammotion.data.mqtt.status import ThingStatusMessage
15
+ from pymammotion.proto.dev_net import DrvDevInfoResp, WifiIotStatusReport
16
+ from pymammotion.proto.luba_msg import LubaMsg
17
+ from pymammotion.proto.mctrl_nav import AppGetAllAreaHashName, NavGetCommDataAck, NavGetHashListAck, SvgMessageAckT
18
+ from pymammotion.proto.mctrl_sys import DeviceProductTypeInfoT, TimeCtrlLight
19
+
20
+ logger = logging.getLogger(__name__)
21
+
22
+
23
+ class StateManager:
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:
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [project]
6
6
  name = "pymammotion"
7
- version = "0.4.0-alpha9"
7
+ version = "0.4.0-beta1"
8
8
  license = "GPL-3.0"
9
9
  description = ""
10
10
  readme = "README.md"
@@ -65,7 +65,7 @@ mypy = "^1.11.2"
65
65
  autotyping = "^24.3.0"
66
66
 
67
67
  [tool.bumpver]
68
- current_version = "0.4.0-alpha9"
68
+ current_version = "0.4.0-beta1"
69
69
  version_pattern = "MAJOR.MINOR.PATCH"
70
70
  commit_message = "Bump version {old_version} -> {new_version}"
71
71
  commit = true
@@ -1,147 +0,0 @@
1
- """Manage state from notifications into MowingDevice."""
2
-
3
- from collections.abc import Awaitable, Callable
4
- from datetime import datetime
5
- import logging
6
- from typing import Any
7
-
8
- import betterproto
9
-
10
- from pymammotion.data.model.device import MowingDevice
11
- from pymammotion.data.model.device_info import SideLight
12
- from pymammotion.data.model.hash_list import AreaHashNameList
13
- from pymammotion.data.mqtt.properties import ThingPropertiesMessage
14
- from pymammotion.data.mqtt.status import ThingStatusMessage
15
- from pymammotion.proto.dev_net import DrvDevInfoResp, WifiIotStatusReport
16
- from pymammotion.proto.luba_msg import LubaMsg
17
- from pymammotion.proto.mctrl_nav import AppGetAllAreaHashName, NavGetCommDataAck, NavGetHashListAck, SvgMessageAckT
18
- from pymammotion.proto.mctrl_sys import DeviceProductTypeInfoT, TimeCtrlLight
19
-
20
- logger = logging.getLogger(__name__)
21
-
22
-
23
- class StateManager:
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.gethash_ack_callback: Callable[[NavGetHashListAck], Awaitable[None]] | None = None
32
- self.get_commondata_ack_callback: Callable[[NavGetCommDataAck | SvgMessageAckT], Awaitable[None]] | None = None
33
- self.on_notification_callback: Callable[[tuple[str, Any | None]], Awaitable[None]] | None = None
34
- self.queue_command_callback: Callable[[str, dict[str, Any]], Awaitable[bytes]] | None = None
35
- self.last_updated_at = datetime.now()
36
-
37
- def get_device(self) -> MowingDevice:
38
- """Get device."""
39
- return self._device
40
-
41
- def set_device(self, device: MowingDevice) -> None:
42
- """Set device."""
43
- self._device = device
44
-
45
- async def properties(self, properties: ThingPropertiesMessage) -> None:
46
- self._device.mqtt_properties = properties
47
-
48
- async def status(self, status: ThingStatusMessage) -> None:
49
- if not self._device.online:
50
- self._device.online = True
51
- self._device.status_properties = status
52
-
53
- @property
54
- def online(self) -> bool:
55
- return self._device.online
56
-
57
- @online.setter
58
- def online(self, value: bool) -> None:
59
- self._device.online = value
60
-
61
- async def notification(self, message: LubaMsg) -> None:
62
- """Handle protobuf notifications."""
63
- res = betterproto.which_one_of(message, "LubaSubMsg")
64
- self.last_updated_at = datetime.now()
65
-
66
- match res[0]:
67
- case "nav":
68
- await self._update_nav_data(message)
69
- case "sys":
70
- await self._update_sys_data(message)
71
- case "driver":
72
- self._update_driver_data(message)
73
- case "net":
74
- self._update_net_data(message)
75
- case "mul":
76
- self._update_mul_data(message)
77
- case "ota":
78
- self._update_ota_data(message)
79
-
80
- if self.on_notification_callback:
81
- await self.on_notification_callback(res)
82
-
83
- async def _update_nav_data(self, message) -> None:
84
- """Update nav data."""
85
- nav_msg = betterproto.which_one_of(message.nav, "SubNavMsg")
86
- match nav_msg[0]:
87
- case "toapp_gethash_ack":
88
- hashlist_ack: NavGetHashListAck = nav_msg[1]
89
- self._device.map.update_root_hash_list(hashlist_ack)
90
- await self.gethash_ack_callback(nav_msg[1])
91
- case "toapp_get_commondata_ack":
92
- common_data: NavGetCommDataAck = nav_msg[1]
93
- updated = self._device.map.update(common_data)
94
- if updated:
95
- await self.get_commondata_ack_callback(common_data)
96
- case "toapp_svg_msg":
97
- common_data: SvgMessageAckT = nav_msg[1]
98
- updated = self._device.map.update(common_data)
99
- if updated:
100
- await self.get_commondata_ack_callback(common_data)
101
-
102
- case "toapp_all_hash_name":
103
- hash_names: AppGetAllAreaHashName = nav_msg[1]
104
- converted_list = [AreaHashNameList(name=item.name, hash=item.hash) for item in hash_names.hashnames]
105
- self._device.map.area_name = converted_list
106
-
107
- async def _update_sys_data(self, message) -> None:
108
- """Update system."""
109
- sys_msg = betterproto.which_one_of(message.sys, "SubSysMsg")
110
- match sys_msg[0]:
111
- case "system_update_buf":
112
- self._device.buffer(sys_msg[1])
113
- case "toapp_report_data":
114
- self._device.update_report_data(sys_msg[1])
115
- case "mow_to_app_info":
116
- self._device.mow_info(sys_msg[1])
117
- case "system_tard_state_tunnel":
118
- self._device.run_state_update(sys_msg[1])
119
- case "todev_time_ctrl_light":
120
- ctrl_light: TimeCtrlLight = sys_msg[1]
121
- side_led: SideLight = SideLight.from_dict(ctrl_light.to_dict(casing=betterproto.Casing.SNAKE))
122
- self._device.mower_state.side_led = side_led
123
- case "device_product_type_info":
124
- device_product_type: DeviceProductTypeInfoT = sys_msg[1]
125
- self._device.mower_state.model_id = device_product_type.main_product_type
126
-
127
- def _update_driver_data(self, message) -> None:
128
- pass
129
-
130
- def _update_net_data(self, message) -> None:
131
- net_msg = betterproto.which_one_of(message.net, "NetSubType")
132
- match net_msg[0]:
133
- case "toapp_wifi_iot_status":
134
- wifi_iot_status: WifiIotStatusReport = net_msg[1]
135
- self._device.mower_state.product_key = wifi_iot_status.productkey
136
- case "toapp_devinfo_resp":
137
- toapp_devinfo_resp: DrvDevInfoResp = net_msg[1]
138
- for resp in toapp_devinfo_resp.resp_ids:
139
- if resp.res == "DRV_RESULT_SUC":
140
- self._device.mower_state.swversion = resp.info
141
- self._device.device_firmwares.device_version = resp.info
142
-
143
- def _update_mul_data(self, message) -> None:
144
- pass
145
-
146
- def _update_ota_data(self, message) -> None:
147
- pass
File without changes
File without changes