python-roborock 7.12.3__tar.gz → 7.12.4__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. {python_roborock-7.12.3 → python_roborock-7.12.4}/PKG-INFO +1 -1
  2. {python_roborock-7.12.3 → python_roborock-7.12.4}/pyproject.toml +1 -1
  3. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/v1/v1_clean_modes.py +18 -3
  4. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/map/b01_q10_map_parser.py +13 -7
  5. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/map/b01_q10_render.py +5 -4
  6. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/map/room_colors.py +17 -9
  7. {python_roborock-7.12.3 → python_roborock-7.12.4}/.gitignore +0 -0
  8. {python_roborock-7.12.3 → python_roborock-7.12.4}/LICENSE +0 -0
  9. {python_roborock-7.12.3 → python_roborock-7.12.4}/README.md +0 -0
  10. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/__init__.py +0 -0
  11. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/broadcast_protocol.py +0 -0
  12. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/callbacks.py +0 -0
  13. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/cli.py +0 -0
  14. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/const.py +0 -0
  15. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/__init__.py +0 -0
  16. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/b01_q10/__init__.py +0 -0
  17. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/b01_q10/b01_q10_code_mappings.py +0 -0
  18. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/b01_q10/b01_q10_containers.py +0 -0
  19. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/b01_q7/__init__.py +0 -0
  20. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/b01_q7/b01_q7_code_mappings.py +0 -0
  21. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/b01_q7/b01_q7_containers.py +0 -0
  22. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/code_mappings.py +0 -0
  23. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/containers.py +0 -0
  24. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/dyad/__init__.py +0 -0
  25. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/dyad/dyad_code_mappings.py +0 -0
  26. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/dyad/dyad_containers.py +0 -0
  27. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/mower/__init__.py +0 -0
  28. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/mower/mower_code_mappings.py +0 -0
  29. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/mower/mower_containers.py +0 -0
  30. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/v1/__init__.py +0 -0
  31. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/v1/v1_code_mappings.py +0 -0
  32. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/v1/v1_containers.py +0 -0
  33. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/zeo/__init__.py +0 -0
  34. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/zeo/zeo_code_mappings.py +0 -0
  35. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/data/zeo/zeo_containers.py +0 -0
  36. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/device_features.py +0 -0
  37. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/README.md +0 -0
  38. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/__init__.py +0 -0
  39. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/cache.py +0 -0
  40. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/device.py +0 -0
  41. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/device_manager.py +0 -0
  42. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/file_cache.py +0 -0
  43. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/rpc/__init__.py +0 -0
  44. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/rpc/a01_channel.py +0 -0
  45. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/rpc/b01_q10_channel.py +0 -0
  46. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/rpc/b01_q7_channel.py +0 -0
  47. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/rpc/v1_channel.py +0 -0
  48. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/__init__.py +0 -0
  49. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/a01/__init__.py +0 -0
  50. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/a01/device_feature.py +0 -0
  51. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/__init__.py +0 -0
  52. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q10/__init__.py +0 -0
  53. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q10/button_light.py +0 -0
  54. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q10/child_lock.py +0 -0
  55. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q10/clean_history.py +0 -0
  56. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q10/command.py +0 -0
  57. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q10/common.py +0 -0
  58. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q10/consumable.py +0 -0
  59. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q10/do_not_disturb.py +0 -0
  60. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q10/dust_collection.py +0 -0
  61. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q10/goto.py +0 -0
  62. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q10/map.py +0 -0
  63. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q10/maps.py +0 -0
  64. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q10/network_info.py +0 -0
  65. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q10/remote.py +0 -0
  66. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q10/status.py +0 -0
  67. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q10/vacuum.py +0 -0
  68. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q10/volume.py +0 -0
  69. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q7/__init__.py +0 -0
  70. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q7/clean_summary.py +0 -0
  71. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q7/map.py +0 -0
  72. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/b01/q7/map_content.py +0 -0
  73. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/common.py +0 -0
  74. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/traits_mixin.py +0 -0
  75. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/__init__.py +0 -0
  76. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/child_lock.py +0 -0
  77. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/clean_summary.py +0 -0
  78. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/command.py +0 -0
  79. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/common.py +0 -0
  80. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/consumeable.py +0 -0
  81. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/device_features.py +0 -0
  82. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/do_not_disturb.py +0 -0
  83. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/dust_collection_mode.py +0 -0
  84. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/flow_led_status.py +0 -0
  85. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/home.py +0 -0
  86. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/led_status.py +0 -0
  87. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/map_content.py +0 -0
  88. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/maps.py +0 -0
  89. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/mop_dryer.py +0 -0
  90. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/network_info.py +0 -0
  91. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/obstacle_photos.py +0 -0
  92. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/rooms.py +0 -0
  93. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/routines.py +0 -0
  94. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/smart_wash_params.py +0 -0
  95. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/status.py +0 -0
  96. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/valley_electricity_timer.py +0 -0
  97. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/volume.py +0 -0
  98. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/traits/v1/wash_towel_mode.py +0 -0
  99. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/transport/__init__.py +0 -0
  100. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/transport/channel.py +0 -0
  101. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/transport/local_channel.py +0 -0
  102. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/devices/transport/mqtt_channel.py +0 -0
  103. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/diagnostics.py +0 -0
  104. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/exceptions.py +0 -0
  105. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/map/__init__.py +0 -0
  106. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/map/b01_grid_layers.py +0 -0
  107. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/map/b01_map_parser.py +0 -0
  108. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/map/b01_q10_overlays.py +0 -0
  109. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/map/map_parser.py +0 -0
  110. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/map/proto/__init__.py +0 -0
  111. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/map/proto/b01_scmap.proto +0 -0
  112. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/map/proto/b01_scmap_pb2.py +0 -0
  113. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/mqtt/__init__.py +0 -0
  114. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/mqtt/health_manager.py +0 -0
  115. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/mqtt/roborock_session.py +0 -0
  116. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/mqtt/session.py +0 -0
  117. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/protocol.py +0 -0
  118. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/protocols/__init__.py +0 -0
  119. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/protocols/a01_protocol.py +0 -0
  120. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/protocols/b01_q10_protocol.py +0 -0
  121. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/protocols/b01_q7_protocol.py +0 -0
  122. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/protocols/v1_protocol.py +0 -0
  123. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/py.typed +0 -0
  124. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/roborock_message.py +0 -0
  125. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/roborock_typing.py +0 -0
  126. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/testing/__init__.py +0 -0
  127. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/testing/a01_simulator.py +0 -0
  128. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/testing/b01_q10_simulator.py +0 -0
  129. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/testing/channel.py +0 -0
  130. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/testing/cloud.py +0 -0
  131. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/testing/simulator.py +0 -0
  132. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/testing/v1_simulator.py +0 -0
  133. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/util.py +0 -0
  134. {python_roborock-7.12.3 → python_roborock-7.12.4}/roborock/web_api.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: python-roborock
3
- Version: 7.12.3
3
+ Version: 7.12.4
4
4
  Summary: A package to control Roborock vacuums.
5
5
  Project-URL: Repository, https://github.com/python-roborock/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 = "7.12.3"
3
+ version = "7.12.4"
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"
@@ -199,14 +199,20 @@ def get_water_modes(features: DeviceFeatures) -> list[WaterModes]:
199
199
 
200
200
  def get_water_slide_mode_name(code: int) -> str | None:
201
201
  """Get the app's range name for a water slide code, or None if out of range."""
202
+ mode = _resolve_water_slide_mode(code)
203
+ return mode.value if mode is not None else None
204
+
205
+
206
+ def _resolve_water_slide_mode(code: int) -> WaterModes | None:
207
+ """Resolve a raw slider code to the water mode for its app range."""
202
208
  if code == 200:
203
- return WaterModes.OFF.value
209
+ return WaterModes.OFF
204
210
  position = code - 220
205
211
  if position < 1:
206
212
  return None
207
213
  for last_position, mode in _WATER_SLIDE_RANGES:
208
214
  if position <= last_position:
209
- return mode.value
215
+ return mode
210
216
  return None
211
217
 
212
218
 
@@ -300,7 +306,14 @@ def get_cleaning_mode_parameters(cleaning_mode: CleaningMode, features: DeviceFe
300
306
  raise RoborockUnsupportedFeature(f"Cleaning mode {cleaning_mode.value!r} is not supported")
301
307
 
302
308
  fan_power, water_box_mode, mop_mode = _get_clean_motor_mode_params(cleaning_mode, features)
303
- params: dict[str, int] = {"fan_power": fan_power.code, "water_box_mode": water_box_mode.code}
309
+ water_code = water_box_mode.code
310
+ if features.is_water_slide_mode_supported:
311
+ # Aliased water enums retain legacy codes; the device mapping preserves
312
+ # slide-specific wire values without changing the user-facing names.
313
+ water_code = next(
314
+ code for code, name in get_water_mode_mapping(features).items() if name == water_box_mode.value
315
+ )
316
+ params: dict[str, int] = {"fan_power": fan_power.code, "water_box_mode": water_code}
304
317
  if features.is_clean_route_setting_supported:
305
318
  params["mop_mode"] = mop_mode.code
306
319
  return [params]
@@ -337,6 +350,8 @@ def get_current_cleaning_mode(
337
350
  return None
338
351
  clean_mode_enum = _resolve_clean_mode(clean_mode, features)
339
352
  water_mode_enum = _resolve_mode_code(water_mode, WaterModes)
353
+ if features.is_water_slide_mode_supported and isinstance(water_mode, int):
354
+ water_mode_enum = _resolve_water_slide_mode(water_mode) or water_mode_enum
340
355
  mop_mode_enum = _resolve_mode_code(mop_mode, CleanRoutes)
341
356
  if clean_mode_enum is None or water_mode_enum is None:
342
357
  return None
@@ -801,8 +801,8 @@ class B01Q10MapParser:
801
801
  """
802
802
  return self.parsed_from_packet(packet)
803
803
 
804
- def parsed_from_packet(self, packet: Q10MapPacket) -> ParsedMapData:
805
- """Render a (possibly erase-modified) packet into a PNG + ``MapData``."""
804
+ def map_data_from_packet(self, packet: Q10MapPacket) -> MapData:
805
+ """Build MapData with a rendered base image, without PNG serialization."""
806
806
  image = self._render(packet)
807
807
 
808
808
  map_data = MapData()
@@ -830,17 +830,23 @@ class B01Q10MapParser:
830
830
  if packet.carpet_mask is not None:
831
831
  map_data.carpet_map = {i for i, value in enumerate(packet.carpet_mask) if value}
832
832
 
833
+ return map_data
834
+
835
+ def parsed_from_packet(self, packet: Q10MapPacket) -> ParsedMapData:
836
+ """Render a (possibly erase-modified) packet into a PNG + ``MapData``."""
837
+ map_data = self.map_data_from_packet(packet)
833
838
  image_bytes = io.BytesIO()
834
- image.save(image_bytes, format=_MAP_FILE_FORMAT)
839
+ if map_data.image is not None:
840
+ map_data.image.data.save(image_bytes, format=_MAP_FILE_FORMAT)
835
841
  return ParsedMapData(image_content=image_bytes.getvalue(), map_data=map_data)
836
842
 
837
843
  def _render(self, packet: Q10MapPacket) -> Image.Image:
838
844
  """Render the Q10 grid with the V1 map palette."""
839
845
  palette = _build_palette(packet.grid, packet.width)
840
- rgba = bytearray()
841
- for value in packet.grid:
842
- rgba.extend(palette[value])
843
- img = Image.frombytes("RGBA", (packet.width, packet.height), bytes(rgba))
846
+ flat_palette = [channel for color in palette for channel in color]
847
+ p_img = Image.frombytes("P", (packet.width, packet.height), packet.grid)
848
+ p_img.putpalette(flat_palette, rawmode="RGBA")
849
+ img = p_img.convert("RGBA")
844
850
  # The ss07 grid is stored top-down (row 0 = top of the home), so it is
845
851
  # rendered as-is -- unlike the V1/Q7 convention, no vertical flip.
846
852
  scale = self._config.map_scale
@@ -109,10 +109,9 @@ def render_q10_map(
109
109
  # areas disappear (as the app shows).
110
110
  render_packet = erased_packet(packet, cells)
111
111
 
112
- parsed = parser.parsed_from_packet(render_packet)
113
- if parsed.image_content is None or parsed.map_data is None:
112
+ map_data = parser.map_data_from_packet(render_packet)
113
+ if map_data.image is None:
114
114
  raise RoborockException("Failed to render Q10 map image")
115
- map_data = parsed.map_data
116
115
 
117
116
  has_drawables = False
118
117
  if trace_calibration is not None and trace is not None:
@@ -128,7 +127,9 @@ def render_q10_map(
128
127
  if has_drawables:
129
128
  return _draw_map_content(map_data, config=config)
130
129
 
131
- return parsed.image_content
130
+ buffer = io.BytesIO()
131
+ map_data.image.data.save(buffer, format="PNG")
132
+ return buffer.getvalue()
132
133
 
133
134
 
134
135
  def solve_q10_calibration(
@@ -23,23 +23,31 @@ def adjacency_aware_room_colors(
23
23
  if width <= 0:
24
24
  return {}
25
25
 
26
+ lut = [room_id_from_cell(i) for i in range(256)]
26
27
  room_ids: set[int] = set()
27
28
  neighbors: dict[int, set[int]] = {}
28
29
  for index, value in enumerate(grid):
29
- room_id = room_id_from_cell(value)
30
+ room_id = lut[value] if 0 <= value < 256 else room_id_from_cell(value)
30
31
  if room_id is None:
31
32
  continue
32
33
  room_ids.add(room_id)
33
34
  neighbors.setdefault(room_id, set())
34
35
 
35
- for neighbor_index in (index - 1 if index % width else -1, index - width):
36
- if neighbor_index < 0:
37
- continue
38
- neighbor_id = room_id_from_cell(grid[neighbor_index])
39
- if neighbor_id is None or neighbor_id == room_id:
40
- continue
41
- neighbors[room_id].add(neighbor_id)
42
- neighbors.setdefault(neighbor_id, set()).add(room_id)
36
+ if index % width:
37
+ left_val = grid[index - 1]
38
+ if left_val != value:
39
+ neighbor_id = lut[left_val] if 0 <= left_val < 256 else room_id_from_cell(left_val)
40
+ if neighbor_id is not None and neighbor_id != room_id:
41
+ neighbors[room_id].add(neighbor_id)
42
+ neighbors.setdefault(neighbor_id, set()).add(room_id)
43
+
44
+ if index >= width:
45
+ up_val = grid[index - width]
46
+ if up_val != value:
47
+ neighbor_id = lut[up_val] if 0 <= up_val < 256 else room_id_from_cell(up_val)
48
+ if neighbor_id is not None and neighbor_id != room_id:
49
+ neighbors[room_id].add(neighbor_id)
50
+ neighbors.setdefault(neighbor_id, set()).add(room_id)
43
51
 
44
52
  candidates: list[Color] = []
45
53
  for palette_id in map(int, ColorsPalette.ROOM_COLORS):