python-roborock 3.8.5__tar.gz → 3.9.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.
Files changed (96) hide show
  1. {python_roborock-3.8.5 → python_roborock-3.9.1}/PKG-INFO +1 -1
  2. {python_roborock-3.8.5 → python_roborock-3.9.1}/pyproject.toml +1 -1
  3. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/containers.py +12 -6
  4. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/device_features.py +1 -1
  5. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/cache.py +2 -2
  6. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/file_cache.py +15 -8
  7. {python_roborock-3.8.5 → python_roborock-3.9.1}/.gitignore +0 -0
  8. {python_roborock-3.8.5 → python_roborock-3.9.1}/LICENSE +0 -0
  9. {python_roborock-3.8.5 → python_roborock-3.9.1}/README.md +0 -0
  10. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/__init__.py +0 -0
  11. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/api.py +0 -0
  12. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/broadcast_protocol.py +0 -0
  13. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/callbacks.py +0 -0
  14. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/cli.py +0 -0
  15. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/cloud_api.py +0 -0
  16. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/command_cache.py +0 -0
  17. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/const.py +0 -0
  18. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/__init__.py +0 -0
  19. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/b01_q10/__init__.py +0 -0
  20. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/b01_q10/b01_q10_code_mappings.py +0 -0
  21. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/b01_q10/b01_q10_containers.py +0 -0
  22. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/b01_q7/__init__.py +0 -0
  23. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/b01_q7/b01_q7_code_mappings.py +0 -0
  24. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/b01_q7/b01_q7_containers.py +0 -0
  25. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/code_mappings.py +0 -0
  26. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/dyad/__init__.py +0 -0
  27. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/dyad/dyad_code_mappings.py +0 -0
  28. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/dyad/dyad_containers.py +0 -0
  29. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/v1/__init__.py +0 -0
  30. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/v1/v1_clean_modes.py +0 -0
  31. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/v1/v1_code_mappings.py +0 -0
  32. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/v1/v1_containers.py +0 -0
  33. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/zeo/__init__.py +0 -0
  34. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/zeo/zeo_code_mappings.py +0 -0
  35. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/data/zeo/zeo_containers.py +0 -0
  36. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/README.md +0 -0
  37. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/__init__.py +0 -0
  38. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/a01_channel.py +0 -0
  39. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/b01_channel.py +0 -0
  40. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/channel.py +0 -0
  41. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/device.py +0 -0
  42. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/device_manager.py +0 -0
  43. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/local_channel.py +0 -0
  44. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/mqtt_channel.py +0 -0
  45. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/__init__.py +0 -0
  46. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/a01/__init__.py +0 -0
  47. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/b01/__init__.py +0 -0
  48. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/traits_mixin.py +0 -0
  49. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/__init__.py +0 -0
  50. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/child_lock.py +0 -0
  51. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/clean_summary.py +0 -0
  52. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/command.py +0 -0
  53. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/common.py +0 -0
  54. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/consumeable.py +0 -0
  55. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/device_features.py +0 -0
  56. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/do_not_disturb.py +0 -0
  57. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/dust_collection_mode.py +0 -0
  58. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/flow_led_status.py +0 -0
  59. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/home.py +0 -0
  60. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/led_status.py +0 -0
  61. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/map_content.py +0 -0
  62. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/maps.py +0 -0
  63. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/network_info.py +0 -0
  64. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/rooms.py +0 -0
  65. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/routines.py +0 -0
  66. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/smart_wash_params.py +0 -0
  67. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/status.py +0 -0
  68. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/valley_electricity_timer.py +0 -0
  69. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/volume.py +0 -0
  70. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/traits/v1/wash_towel_mode.py +0 -0
  71. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/devices/v1_channel.py +0 -0
  72. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/exceptions.py +0 -0
  73. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/map/__init__.py +0 -0
  74. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/map/map_parser.py +0 -0
  75. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/mqtt/__init__.py +0 -0
  76. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/mqtt/health_manager.py +0 -0
  77. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/mqtt/roborock_session.py +0 -0
  78. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/mqtt/session.py +0 -0
  79. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/protocol.py +0 -0
  80. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/protocols/__init__.py +0 -0
  81. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/protocols/a01_protocol.py +0 -0
  82. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/protocols/b01_protocol.py +0 -0
  83. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/protocols/v1_protocol.py +0 -0
  84. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/py.typed +0 -0
  85. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/roborock_future.py +0 -0
  86. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/roborock_message.py +0 -0
  87. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/roborock_typing.py +0 -0
  88. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/util.py +0 -0
  89. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/version_1_apis/__init__.py +0 -0
  90. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/version_1_apis/roborock_client_v1.py +0 -0
  91. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/version_1_apis/roborock_local_client_v1.py +0 -0
  92. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/version_1_apis/roborock_mqtt_client_v1.py +0 -0
  93. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/version_a01_apis/__init__.py +0 -0
  94. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/version_a01_apis/roborock_client_a01.py +0 -0
  95. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/version_a01_apis/roborock_mqtt_client_a01.py +0 -0
  96. {python_roborock-3.8.5 → python_roborock-3.9.1}/roborock/web_api.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-roborock
3
- Version: 3.8.5
3
+ Version: 3.9.1
4
4
  Summary: A package to control Roborock vacuums.
5
5
  Project-URL: Repository, https://github.com/humbertogontijo/python-roborock
6
6
  Project-URL: Documentation, https://python-roborock.readthedocs.io/
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "python-roborock"
3
- version = "3.8.5"
3
+ version = "3.9.1"
4
4
  description = "A package to control Roborock vacuums."
5
5
  authors = [{ name = "humbertogontijo", email = "humbertogontijo@users.noreply.github.com" }, {name="Lash-L"}, {name="allenporter"}]
6
6
  requires-python = ">=3.11, <4"
@@ -1,5 +1,6 @@
1
1
  import dataclasses
2
2
  import datetime
3
+ import inspect
3
4
  import json
4
5
  import logging
5
6
  import re
@@ -27,7 +28,11 @@ def _camelize(s: str):
27
28
 
28
29
 
29
30
  def _decamelize(s: str):
30
- return re.sub("([A-Z]+)", "_\\1", s).lower()
31
+ # Split before uppercase letters not at the start, and before numbers
32
+ s = re.sub(r"(?<=[a-z0-9])([A-Z])", r"_\1", s)
33
+ s = re.sub(r"([A-Z]+)([A-Z][a-z])", r"\1_\2", s) # Split acronyms followed by normal camelCase
34
+ s = re.sub(r"([a-zA-Z])([0-9]+)", r"\1_\2", s)
35
+ return s.lower()
31
36
 
32
37
 
33
38
  def _attr_repr(obj: Any) -> str:
@@ -64,11 +69,12 @@ class RoborockBase:
64
69
  if get_origin(class_type) is dict:
65
70
  _, value_type = get_args(class_type) # assume keys are only basic types
66
71
  return {k: RoborockBase._convert_to_class_obj(value_type, v) for k, v in value.items()}
67
- if issubclass(class_type, RoborockBase):
68
- return class_type.from_dict(value)
69
- if issubclass(class_type, RoborockModeEnum):
70
- return class_type.from_code(value)
71
- if class_type is Any:
72
+ if inspect.isclass(class_type):
73
+ if issubclass(class_type, RoborockBase):
74
+ return class_type.from_dict(value)
75
+ if issubclass(class_type, RoborockModeEnum):
76
+ return class_type.from_code(value)
77
+ if class_type is Any or type(class_type) is str:
72
78
  return value
73
79
  return class_type(value) # type: ignore[call-arg]
74
80
 
@@ -313,7 +313,7 @@ class DeviceFeatures(RoborockBase):
313
313
  is_support_incremental_map: bool = field(metadata={"new_feature_str_mask": (4194304, 8)})
314
314
  is_offline_map_supported: bool = field(metadata={"new_feature_str_mask": (16384, 8)})
315
315
  is_super_deep_wash_supported: bool = field(metadata={"new_feature_str_mask": (32768, 8)})
316
- is_ces2022_supported: bool = field(metadata={"new_feature_str_mask": (65536, 8)})
316
+ is_ces_2022_supported: bool = field(metadata={"new_feature_str_mask": (65536, 8)})
317
317
  is_dss_believable: bool = field(metadata={"new_feature_str_mask": (131072, 8)})
318
318
  is_main_brush_up_down_supported_from_str: bool = field(metadata={"new_feature_str_mask": (262144, 8)})
319
319
  is_goto_pure_clean_path_supported: bool = field(metadata={"new_feature_str_mask": (524288, 8)})
@@ -8,12 +8,12 @@ this interface to provide their own caching mechanism.
8
8
  from dataclasses import dataclass, field
9
9
  from typing import Any, Protocol
10
10
 
11
- from roborock.data import CombinedMapInfo, HomeData, NetworkInfo
11
+ from roborock.data import CombinedMapInfo, HomeData, NetworkInfo, RoborockBase
12
12
  from roborock.device_features import DeviceFeatures
13
13
 
14
14
 
15
15
  @dataclass
16
- class CacheData:
16
+ class CacheData(RoborockBase):
17
17
  """Data structure for caching device information."""
18
18
 
19
19
  home_data: HomeData | None = None
@@ -17,18 +17,25 @@ from .cache import Cache, CacheData
17
17
  class FileCache(Cache):
18
18
  """File backed cache implementation."""
19
19
 
20
- def __init__(self, file_path: pathlib.Path, init_fn: Callable[[], CacheData] = CacheData) -> None:
20
+ def __init__(
21
+ self,
22
+ file_path: pathlib.Path,
23
+ init_fn: Callable[[], CacheData] = CacheData,
24
+ serialize_fn: Callable[[Any], bytes] = pickle.dumps,
25
+ deserialize_fn: Callable[[bytes], Any] = pickle.loads,
26
+ ) -> None:
21
27
  """Initialize the file cache with the given file path."""
22
28
  self._init_fn = init_fn
23
29
  self._file_path = file_path
24
30
  self._cache_data: CacheData | None = None
31
+ self._serialize_fn = serialize_fn
32
+ self._deserialize_fn = deserialize_fn
25
33
 
26
34
  async def get(self) -> CacheData:
27
35
  """Get cached value."""
28
36
  if self._cache_data is not None:
29
37
  return self._cache_data
30
-
31
- data = await load_value(self._file_path)
38
+ data = await load_value(self._file_path, self._deserialize_fn)
32
39
  if data is not None and not isinstance(data, CacheData):
33
40
  raise TypeError(f"Invalid cache data loaded from {self._file_path}")
34
41
 
@@ -43,21 +50,21 @@ class FileCache(Cache):
43
50
  """Flush the cache to disk."""
44
51
  if self._cache_data is None:
45
52
  return
46
- await store_value(self._file_path, self._cache_data)
53
+ await store_value(self._file_path, self._cache_data, self._serialize_fn)
47
54
 
48
55
 
49
- async def store_value(file_path: pathlib.Path, value: Any) -> None:
56
+ async def store_value(file_path: pathlib.Path, value: Any, serialize_fn: Callable[[Any], bytes] = pickle.dumps) -> None:
50
57
  """Store a value to the given file path."""
51
58
 
52
59
  def _store_to_disk(file_path: pathlib.Path, value: Any) -> None:
53
60
  with open(file_path, "wb") as f:
54
- data = pickle.dumps(value)
61
+ data = serialize_fn(value)
55
62
  f.write(data)
56
63
 
57
64
  await asyncio.to_thread(_store_to_disk, file_path, value)
58
65
 
59
66
 
60
- async def load_value(file_path: pathlib.Path) -> Any | None:
67
+ async def load_value(file_path: pathlib.Path, deserialize_fn: Callable[[bytes], Any] = pickle.loads) -> Any | None:
61
68
  """Load a value from the given file path."""
62
69
 
63
70
  def _load_from_disk(file_path: pathlib.Path) -> Any | None:
@@ -65,6 +72,6 @@ async def load_value(file_path: pathlib.Path) -> Any | None:
65
72
  return None
66
73
  with open(file_path, "rb") as f:
67
74
  data = f.read()
68
- return pickle.loads(data)
75
+ return deserialize_fn(data)
69
76
 
70
77
  return await asyncio.to_thread(_load_from_disk, file_path)
File without changes