pymammotion 0.1.9__tar.gz → 0.2.1__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.

Potentially problematic release.


This version of pymammotion might be problematic. Click here for more details.

Files changed (117) hide show
  1. {pymammotion-0.1.9 → pymammotion-0.2.1}/PKG-INFO +1 -1
  2. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/__init__.py +2 -10
  3. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/aliyun/cloud_gateway.py +2 -3
  4. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/aliyun/dataclass/aep_response.py +4 -0
  5. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/aliyun/dataclass/dev_by_account_response.py +5 -1
  6. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/aliyun/dataclass/regions_response.py +4 -0
  7. pymammotion-0.2.1/pymammotion/data/model/account.py +8 -0
  8. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/model/device.py +5 -4
  9. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/model/device_config.py +2 -2
  10. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/model/location.py +1 -1
  11. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/model/mowing_modes.py +2 -1
  12. pymammotion-0.2.1/pymammotion/data/model/report_info.py +146 -0
  13. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/mqtt/event.py +32 -1
  14. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/http/http.py +12 -11
  15. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mammotion/commands/mammotion_command.py +0 -4
  16. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mammotion/commands/messages/navigation.py +4 -1
  17. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mammotion/devices/mammotion.py +222 -44
  18. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mqtt/mammotion_mqtt.py +13 -52
  19. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/utility/map.py +9 -5
  20. {pymammotion-0.1.9 → pymammotion-0.2.1}/pyproject.toml +2 -2
  21. pymammotion-0.1.9/pymammotion/data/model/report_info.py +0 -141
  22. {pymammotion-0.1.9 → pymammotion-0.2.1}/LICENSE +0 -0
  23. {pymammotion-0.1.9 → pymammotion-0.2.1}/README.md +0 -0
  24. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/aliyun/__init__.py +0 -0
  25. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/aliyun/cloud_service.py +0 -0
  26. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/aliyun/dataclass/connect_response.py +0 -0
  27. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/aliyun/dataclass/login_by_oauth_response.py +0 -0
  28. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/aliyun/dataclass/session_by_authcode_response.py +0 -0
  29. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/aliyun/tmp_constant.py +0 -0
  30. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/bluetooth/__init__.py +0 -0
  31. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/bluetooth/ble.py +0 -0
  32. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/bluetooth/ble_message.py +0 -0
  33. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/bluetooth/const.py +0 -0
  34. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/bluetooth/data/__init__.py +0 -0
  35. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/bluetooth/data/convert.py +0 -0
  36. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/bluetooth/data/framectrldata.py +0 -0
  37. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/bluetooth/data/notifydata.py +0 -0
  38. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/const.py +0 -0
  39. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/__init__.py +0 -0
  40. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/model/__init__.py +0 -0
  41. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/model/enums.py +0 -0
  42. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/model/excute_boarder_params.py +0 -0
  43. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/model/execute_boarder.py +0 -0
  44. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/model/generate_route_information.py +0 -0
  45. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/model/hash_list.py +0 -0
  46. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/model/plan.py +0 -0
  47. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/model/rapid_state.py +0 -0
  48. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/model/region_data.py +0 -0
  49. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/mqtt/__init__.py +0 -0
  50. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/mqtt/properties.py +0 -0
  51. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/mqtt/status.py +0 -0
  52. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/data/state_manager.py +0 -0
  53. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/event/__init__.py +0 -0
  54. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/event/event.py +0 -0
  55. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/http/_init_.py +0 -0
  56. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mammotion/__init__.py +0 -0
  57. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mammotion/commands/__init__.py +0 -0
  58. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mammotion/commands/abstract_message.py +0 -0
  59. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mammotion/commands/messages/__init__.py +0 -0
  60. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mammotion/commands/messages/driver.py +0 -0
  61. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mammotion/commands/messages/media.py +0 -0
  62. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mammotion/commands/messages/network.py +0 -0
  63. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mammotion/commands/messages/ota.py +0 -0
  64. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mammotion/commands/messages/system.py +0 -0
  65. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mammotion/commands/messages/video.py +0 -0
  66. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mammotion/control/__init__.py +0 -0
  67. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mammotion/control/joystick.py +0 -0
  68. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mammotion/devices/__init__.py +0 -0
  69. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/mqtt/__init__.py +0 -0
  70. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/__init__.py +0 -0
  71. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/basestation.proto +0 -0
  72. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/basestation.py +0 -0
  73. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/basestation_pb2.py +0 -0
  74. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/basestation_pb2.pyi +0 -0
  75. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/common.proto +0 -0
  76. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/common.py +0 -0
  77. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/common_pb2.py +0 -0
  78. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/common_pb2.pyi +0 -0
  79. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/dev_net.proto +0 -0
  80. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/dev_net.py +0 -0
  81. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/dev_net_pb2.py +0 -0
  82. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/dev_net_pb2.pyi +0 -0
  83. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/luba_msg.proto +0 -0
  84. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/luba_msg.py +0 -0
  85. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/luba_msg_pb2.py +0 -0
  86. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/luba_msg_pb2.pyi +0 -0
  87. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/luba_mul.proto +0 -0
  88. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/luba_mul.py +0 -0
  89. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/luba_mul_pb2.py +0 -0
  90. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/luba_mul_pb2.pyi +0 -0
  91. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_driver.proto +0 -0
  92. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_driver.py +0 -0
  93. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_driver_pb2.py +0 -0
  94. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_driver_pb2.pyi +0 -0
  95. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_nav.proto +0 -0
  96. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_nav.py +0 -0
  97. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_nav_pb2.py +0 -0
  98. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_nav_pb2.pyi +0 -0
  99. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_ota.proto +0 -0
  100. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_ota.py +0 -0
  101. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_ota_pb2.py +0 -0
  102. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_ota_pb2.pyi +0 -0
  103. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_pept.proto +0 -0
  104. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_pept.py +0 -0
  105. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_pept_pb2.py +0 -0
  106. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_pept_pb2.pyi +0 -0
  107. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_sys.proto +0 -0
  108. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_sys.py +0 -0
  109. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_sys_pb2.py +0 -0
  110. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/proto/mctrl_sys_pb2.pyi +0 -0
  111. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/py.typed +0 -0
  112. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/utility/constant/__init__.py +0 -0
  113. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/utility/constant/device_constant.py +1 -1
  114. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/utility/datatype_converter.py +0 -0
  115. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/utility/device_type.py +0 -0
  116. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/utility/periodic.py +0 -0
  117. {pymammotion-0.1.9 → pymammotion-0.2.1}/pymammotion/utility/rocker_util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pymammotion
3
- Version: 0.1.9
3
+ Version: 0.2.1
4
4
  Summary:
5
5
  License: GNU-3.0
6
6
  Author: Michael Arthur
@@ -10,21 +10,13 @@ import os
10
10
 
11
11
  # works outside HA on its own
12
12
  from pymammotion.bluetooth.ble import LubaBLE
13
- from pymammotion.http.http import LubaHTTP, connect_http
13
+ from pymammotion.http.http import MammotionHTTP, connect_http
14
14
 
15
15
  # TODO make a working device that will work outside HA too.
16
16
  from pymammotion.mammotion.devices import MammotionBaseBLEDevice
17
17
  from pymammotion.mqtt import MammotionMQTT
18
18
 
19
-
20
-
21
- __all__ = [
22
- 'LubaBLE',
23
- 'LubaHTTP',
24
- 'connect_http',
25
- 'MammotionBaseBLEDevice',
26
- 'MammotionMQTT'
27
- ]
19
+ __all__ = ["LubaBLE", "MammotionHTTP", "connect_http", "MammotionBaseBLEDevice", "MammotionMQTT"]
28
20
 
29
21
  logger = logging.getLogger(__name__)
30
22
 
@@ -391,8 +391,6 @@ class CloudIOTGateway:
391
391
 
392
392
  def check_or_refresh_session(self):
393
393
  """Check or refresh the session."""
394
- if self.load_saved_params() is False:
395
- return False
396
394
  config = Config(
397
395
  app_key=self._app_key,
398
396
  app_secret=self._app_secret,
@@ -436,7 +434,7 @@ class CloudIOTGateway:
436
434
  # Carica la stringa JSON in un dizionario
437
435
  json.loads(response_body_str)
438
436
 
439
- def list_binding_by_account(self):
437
+ def list_binding_by_account(self) -> ListingDevByAccountResponse:
440
438
  """List bindings by account."""
441
439
  config = Config(
442
440
  app_key=self._app_key,
@@ -476,6 +474,7 @@ class CloudIOTGateway:
476
474
  raise Exception("Error in creating session: " + response_body_dict["msg"])
477
475
 
478
476
  self._listing_dev_by_account_response = ListingDevByAccountResponse.from_dict(response_body_dict)
477
+ return self._listing_dev_by_account_response
479
478
 
480
479
  def send_cloud_command(self, iot_id: str, command: bytes) -> str:
481
480
  """Send a cloud command to the specified IoT device."""
@@ -1,6 +1,7 @@
1
1
  from dataclasses import dataclass
2
2
  from typing import Optional
3
3
 
4
+ from mashumaro.config import BaseConfig
4
5
  from mashumaro.mixins.orjson import DataClassORJSONMixin
5
6
 
6
7
 
@@ -16,3 +17,6 @@ class AepResponse(DataClassORJSONMixin):
16
17
  code: int
17
18
  data: DeviceData
18
19
  id: Optional[str] = None
20
+
21
+ class Config(BaseConfig):
22
+ omit_default = True
@@ -1,12 +1,12 @@
1
1
  from dataclasses import dataclass
2
2
  from typing import List, Optional
3
3
 
4
+ from mashumaro.config import BaseConfig
4
5
  from mashumaro.mixins.orjson import DataClassORJSONMixin
5
6
 
6
7
 
7
8
  @dataclass
8
9
  class Device(DataClassORJSONMixin):
9
- productModel: str
10
10
  gmtModified: int
11
11
  netType: str
12
12
  nickName: str
@@ -26,6 +26,10 @@ class Device(DataClassORJSONMixin):
26
26
  status: int
27
27
  productImage: Optional[str] = None
28
28
  categoryImage: Optional[str] = None
29
+ productModel: Optional[str] = None
30
+
31
+ class Config(BaseConfig):
32
+ omit_default = True
29
33
 
30
34
 
31
35
  @dataclass
@@ -2,6 +2,7 @@ from dataclasses import dataclass
2
2
  from typing import Optional, TypeVar
3
3
 
4
4
  from mashumaro import DataClassDictMixin
5
+ from mashumaro.config import BaseConfig
5
6
  from mashumaro.mixins.orjson import DataClassORJSONMixin
6
7
 
7
8
  DataT = TypeVar("DataT")
@@ -24,3 +25,6 @@ class RegionResponse(DataClassDictMixin):
24
25
  code: int
25
26
  id: Optional[str] = None
26
27
  msg: Optional[str] = None
28
+
29
+ class Config(BaseConfig):
30
+ omit_default = True
@@ -0,0 +1,8 @@
1
+ from dataclasses import dataclass
2
+
3
+
4
+ @dataclass
5
+ class Credentials:
6
+ email: str
7
+ password: str
8
+ account_id: str
@@ -1,4 +1,5 @@
1
1
  """MowingDevice class to wrap around the betterproto dataclasses."""
2
+
2
3
  import math
3
4
  from dataclasses import dataclass
4
5
 
@@ -15,7 +16,7 @@ from pymammotion.proto.mctrl_driver import MctlDriver
15
16
  from pymammotion.proto.mctrl_nav import MctlNav
16
17
  from pymammotion.proto.mctrl_ota import MctlOta
17
18
  from pymammotion.proto.mctrl_pept import MctlPept
18
- from pymammotion.proto.mctrl_sys import MctlSys, MowToAppInfoT, SystemUpdateBufMsg, ReportInfoData
19
+ from pymammotion.proto.mctrl_sys import MctlSys, MowToAppInfoT, ReportInfoData, SystemUpdateBufMsg
19
20
  from pymammotion.utility.map import CoordinateConverter
20
21
 
21
22
 
@@ -99,12 +100,12 @@ class MowingDevice:
99
100
  if index == 0:
100
101
  self.location.position_type = location.pos_type
101
102
  self.location.orientation = location.real_toward / 10000
102
- self.location.device = coordinate_converter.enu_to_lla(parse_double(location.real_pos_y, 4.0), parse_double(location.real_pos_x, 4.0))
103
+ self.location.device = coordinate_converter.enu_to_lla(
104
+ parse_double(location.real_pos_y, 4.0), parse_double(location.real_pos_x, 4.0)
105
+ )
103
106
 
104
107
  self.report_data = self.report_data.from_dict(toapp_report_data.to_dict(casing=betterproto.Casing.SNAKE))
105
108
 
106
-
107
-
108
109
  def mow_info(self, toapp_mow_info: MowToAppInfoT):
109
110
  pass
110
111
 
@@ -3,7 +3,7 @@ from dataclasses import dataclass
3
3
 
4
4
  @dataclass
5
5
  class DeviceLimits:
6
- cutter_height_min: int
7
- cutter_height_max: int
6
+ blade_height_min: int
7
+ blade_height_max: int
8
8
  working_speed_min: float
9
9
  working_speed_max: float
@@ -34,7 +34,7 @@ class Location:
34
34
  RTK: Point
35
35
  dock: Dock
36
36
  position_type: int
37
- orientation: int # 360 degree rotation +-
37
+ orientation: int # 360 degree rotation +-
38
38
 
39
39
  def __init__(self):
40
40
  self.device = Point()
@@ -39,7 +39,8 @@ class MowOrder(IntEnum):
39
39
 
40
40
  class BypassStrategy(IntEnum):
41
41
  """Matches up with ultra_wave."""
42
+
42
43
  direct_touch = 0
43
44
  slow_touch = 1
44
45
  less_touch = 2
45
- no_touch = 3 # luba 2 yuka only or possibly value of 10
46
+ no_touch = 3 # luba 2 yuka only or possibly value of 10
@@ -0,0 +1,146 @@
1
+ from dataclasses import asdict, dataclass, field
2
+
3
+
4
+ @dataclass
5
+ class ConnectData:
6
+ connect_type: int = 0
7
+ ble_rssi: int = 0
8
+ wifi_rssi: int = 0
9
+
10
+ @classmethod
11
+ def from_dict(cls, data: dict):
12
+ return cls(
13
+ connect_type=data.get("connect_type", 0),
14
+ ble_rssi=data.get("ble_rssi", 0),
15
+ wifi_rssi=data.get("wifi_rssi", 0),
16
+ )
17
+
18
+
19
+ @dataclass
20
+ class DeviceData:
21
+ sys_status: int = 0
22
+ charge_state: int = 0
23
+ battery_val: int = 0
24
+ sensor_status: int = 0
25
+ last_status: int = 0
26
+ sys_time_stamp: str = ""
27
+
28
+ @classmethod
29
+ def from_dict(cls, data: dict):
30
+ return cls(
31
+ sys_status=data.get("sys_status", 0),
32
+ charge_state=data.get("charge_state", 0),
33
+ battery_val=data.get("battery_val", 0),
34
+ sensor_status=data.get("sensor_status", 0),
35
+ last_status=data.get("last_status", 0),
36
+ sys_time_stamp=data.get("sys_time_stamp", ""),
37
+ )
38
+
39
+
40
+ @dataclass
41
+ class RTKData:
42
+ status: int = 0
43
+ pos_level: int = 0
44
+ gps_stars: int = 0
45
+ dis_status: str = ""
46
+ co_view_stars: int = 0
47
+
48
+ @classmethod
49
+ def from_dict(cls, data: dict):
50
+ return cls(
51
+ status=data.get("status", 0),
52
+ pos_level=data.get("pos_level", 0),
53
+ gps_stars=data.get("gps_stars", 0),
54
+ dis_status=data.get("dis_status", ""),
55
+ co_view_stars=data.get("co_view_stars", 0),
56
+ )
57
+
58
+
59
+ @dataclass
60
+ class LocationData:
61
+ real_pos_x: int = 0
62
+ real_pos_y: int = 0
63
+ real_toward: int = 0
64
+ pos_type: int = 0
65
+ bol_hash: str = ""
66
+
67
+ @classmethod
68
+ def from_dict(cls, data: dict):
69
+ return cls(
70
+ real_pos_x=data.get("real_pos_x", 0),
71
+ real_pos_y=data.get("real_pos_y", 0),
72
+ real_toward=data.get("real_toward", 0),
73
+ pos_type=data.get("pos_type", 0),
74
+ bol_hash=data.get("bol_hash", ""),
75
+ )
76
+
77
+
78
+ @dataclass
79
+ class WorkData:
80
+ path: int = 0
81
+ path_hash: str = ""
82
+ progress: int = 0
83
+ area: int = 0
84
+ bp_info: int = 0
85
+ bp_hash: str = ""
86
+ bp_pos_x: int = 0
87
+ bp_pos_y: int = 0
88
+ real_path_num: str = ""
89
+ path_pos_x: int = 0
90
+ path_pos_y: int = 0
91
+ ub_zone_hash: str = ""
92
+ ub_path_hash: str = ""
93
+ init_cfg_hash: str = ""
94
+ ub_ecode_hash: str = ""
95
+ nav_run_mode: int = 0
96
+ test_mode_status: int = 0
97
+ man_run_speed: int = 0
98
+ nav_edit_status: int = 0
99
+ knife_height: int = 0
100
+
101
+ @classmethod
102
+ def from_dict(cls, data: dict):
103
+ return cls(
104
+ path=data.get("path", 0),
105
+ path_hash=data.get("path_hash", ""),
106
+ progress=data.get("progress", 0),
107
+ area=data.get("area", 0),
108
+ bp_info=data.get("bp_info", 0),
109
+ bp_hash=data.get("bp_hash", ""),
110
+ bp_pos_x=data.get("bp_pos_x", 0),
111
+ bp_pos_y=data.get("bp_pos_y", 0),
112
+ real_path_num=data.get("real_path_num", ""),
113
+ path_pos_x=data.get("path_pos_x", 0),
114
+ path_pos_y=data.get("path_pos_y", 0),
115
+ ub_zone_hash=data.get("ub_zone_hash", ""),
116
+ ub_path_hash=data.get("ub_path_hash", ""),
117
+ init_cfg_hash=data.get("init_cfg_hash", ""),
118
+ ub_ecode_hash=data.get("ub_ecode_hash", ""),
119
+ nav_run_mode=data.get("nav_run_mode", 0),
120
+ test_mode_status=data.get("test_mode_status", 0),
121
+ man_run_speed=data.get("man_run_speed", 0),
122
+ nav_edit_status=data.get("nav_edit_status", 0),
123
+ knife_height=data.get("knife_height", 0),
124
+ )
125
+
126
+
127
+ @dataclass
128
+ class ReportData:
129
+ connect: ConnectData = field(default_factory=ConnectData)
130
+ dev: DeviceData = field(default_factory=DeviceData)
131
+ rtk: RTKData = field(default_factory=RTKData)
132
+ locations: list[LocationData] = field(default_factory=list)
133
+ work: WorkData = field(default_factory=WorkData)
134
+
135
+ def from_dict(self, data: dict):
136
+ locations = self.locations
137
+ if data.get("locations") is not None:
138
+ locations = [LocationData.from_dict(loc) for loc in data.get("locations", [])]
139
+
140
+ return ReportData(
141
+ connect=ConnectData.from_dict(data.get("connect", asdict(self.connect))),
142
+ dev=DeviceData.from_dict(data.get("dev", asdict(self.dev))),
143
+ rtk=RTKData.from_dict(data.get("rtk", asdict(self.rtk))),
144
+ locations=locations,
145
+ work=WorkData.from_dict(data.get("work", asdict(self.work))),
146
+ )
@@ -1,6 +1,6 @@
1
1
  from base64 import b64decode
2
2
  from dataclasses import dataclass
3
- from typing import Any, Literal, Union
3
+ from typing import Any, Literal, Optional, Union
4
4
 
5
5
  from google.protobuf import json_format
6
6
  from mashumaro.mixins.orjson import DataClassORJSONMixin
@@ -67,6 +67,17 @@ class GeneralParams(DataClassORJSONMixin):
67
67
  tenantInstanceId: str
68
68
  value: Any
69
69
 
70
+ # Campi opzionali
71
+ checkFailedData: Optional[dict] = None
72
+ _tenantId: Optional[str] = None
73
+ generateTime: Optional[int] = None
74
+ JMSXDeliveryCount: Optional[int] = None
75
+ qos: Optional[int] = None
76
+ requestId: Optional[str] = None
77
+ _categoryKey: Optional[str] = None
78
+ deviceType: Optional[str] = None
79
+ _traceId: Optional[str] = None
80
+
70
81
 
71
82
  @dataclass
72
83
  class DeviceProtobufMsgEventParams(GeneralParams):
@@ -88,3 +99,23 @@ class ThingEventMessage(DataClassORJSONMixin):
88
99
  id: str
89
100
  params: Union[DeviceProtobufMsgEventParams, DeviceWarningEventParams]
90
101
  version: Literal["1.0"]
102
+
103
+ @classmethod
104
+ def from_dicts(cls, payload: dict) -> "ThingEventMessage":
105
+ """Deserializza il payload JSON in un'istanza di ThingEventMessage."""
106
+ method = payload.get("method")
107
+ event_id = payload.get("id")
108
+ params_dict = payload.get("params", {})
109
+ version = payload.get("version")
110
+
111
+ # Determina quale classe usare per i parametri
112
+ identifier = params_dict.get("identifier")
113
+ if identifier == "device_protobuf_msg_event":
114
+ params_obj = DeviceProtobufMsgEventParams(**params_dict)
115
+ elif identifier == "device_warning_event":
116
+ params_obj = DeviceWarningEventParams(**params_dict)
117
+ else:
118
+ raise ValueError(f"Unknown identifier: {identifier}")
119
+
120
+ # Crea e restituisce l'istanza di ThingEventMessage
121
+ return cls(method=method, id=event_id, params=params_obj, version=version)
@@ -1,10 +1,12 @@
1
1
  from dataclasses import dataclass
2
- from typing import Generic, Literal, TypeVar
2
+ from typing import Generic, Literal, Optional, TypeVar
3
3
 
4
4
  from aiohttp import ClientSession
5
+ from aiohttp.hdrs import AUTHORIZATION
5
6
  from mashumaro import DataClassDictMixin
6
7
  from mashumaro.mixins.orjson import DataClassORJSONMixin
7
8
 
9
+ from pymammotion.aliyun.dataclass.connect_response import Device
8
10
  from pymammotion.const import (
9
11
  MAMMOTION_CLIENT_ID,
10
12
  MAMMOTION_CLIENT_SECRET,
@@ -25,7 +27,7 @@ class Response(DataClassDictMixin, Generic[DataT]):
25
27
  class LoginResponseUserInformation(DataClassORJSONMixin):
26
28
  areaCode: str
27
29
  domainAbbreviation: str
28
- email: str
30
+ email: Optional[str]
29
31
  userId: str
30
32
  userAccount: str
31
33
  authType: str
@@ -44,11 +46,11 @@ class LoginResponseData(DataClassORJSONMixin):
44
46
  jti: str
45
47
 
46
48
 
47
- class LubaHTTP:
48
- def __init__(self, session: ClientSession, login: LoginResponseData):
49
- self._session = session
50
- self._session.headers["Authorization"] = f"Bearer {login.access_token}"
51
- self._login = login
49
+ class MammotionHTTP:
50
+ def __init__(self, login: LoginResponseData):
51
+ self._headers = dict()
52
+ self._headers["Authorization"] = f"Bearer {login.access_token}"
53
+ self.login_info = login
52
54
 
53
55
  @classmethod
54
56
  async def login(cls, session: ClientSession, username: str, password: str) -> Response[LoginResponseData]:
@@ -63,14 +65,13 @@ class LubaHTTP:
63
65
  ),
64
66
  ) as resp:
65
67
  data = await resp.json()
66
- print(data)
67
68
  # TODO catch errors from mismatch user / password
68
69
  # Assuming the data format matches the expected structure
69
70
  login_response_data = LoginResponseData.from_dict(data["data"])
70
71
  return Response(data=login_response_data, code=data["code"], msg=data["msg"])
71
72
 
72
73
 
73
- async def connect_http(username: str, password: str) -> LubaHTTP:
74
+ async def connect_http(username: str, password: str) -> MammotionHTTP:
74
75
  async with ClientSession(MAMMOTION_DOMAIN) as session:
75
- login_response = await LubaHTTP.login(session, username, password)
76
- return LubaHTTP(session, login_response.data)
76
+ login_response = await MammotionHTTP.login(session, username, password)
77
+ return MammotionHTTP(login_response.data)
@@ -4,14 +4,11 @@ from pymammotion.mammotion.commands.messages.ota import MessageOta
4
4
  from pymammotion.mammotion.commands.messages.system import MessageSystem
5
5
  from pymammotion.mammotion.commands.messages.video import MessageVideo
6
6
  from pymammotion.proto import dev_net_pb2, luba_msg_pb2
7
- from pymammotion.utility.device_type import DeviceType
8
7
 
9
8
 
10
9
  class MammotionCommand(MessageSystem, MessageNavigation, MessageNetwork, MessageOta, MessageVideo):
11
10
  """MQTT commands for Luba."""
12
11
 
13
-
14
-
15
12
  def __init__(self, device_name: str) -> None:
16
13
  self._device_name = device_name
17
14
  self._product_key = ""
@@ -26,7 +23,6 @@ class MammotionCommand(MessageSystem, MessageNavigation, MessageNetwork, Message
26
23
  def set_device_product_key(self, product_key: str) -> None:
27
24
  self._product_key = product_key
28
25
 
29
-
30
26
  """BLE commands for Luba."""
31
27
 
32
28
  def send_todev_ble_sync(self, sync_type: int) -> bytes:
@@ -34,7 +34,10 @@ logger = logging.getLogger(__name__)
34
34
  class MessageNavigation(AbstractMessage, ABC):
35
35
  def get_msg_device(self, msg_type: MsgCmdType, msg_device: MsgDevice) -> MsgDevice:
36
36
  """Changes the rcver name if it's not a luba1."""
37
- if not DeviceType.is_luba1(self.get_device_name(), self.get_device_product_key()) and msg_type == MsgCmdType.MSG_CMD_TYPE_NAV:
37
+ if (
38
+ not DeviceType.is_luba1(self.get_device_name(), self.get_device_product_key())
39
+ and msg_type == MsgCmdType.MSG_CMD_TYPE_NAV
40
+ ):
38
41
  return MsgDevice.DEV_NAVIGATION
39
42
  return msg_device
40
43