Conversation
- Add CongaMapImageHandler: scales Conga JSON (pixelSize, canvas size, entity coordinates) by ×5 before the Hypfer render pipeline, producing solid filled rooms and correctly positioned entities without post-upscale - Add CongaImageDraw: thin subclass of HypferImageDraw; coordinate scaling handled entirely in the handler - Add ImageData.is_conga_map() for detection via congaPixels field presence - Export CongaMapImageHandler and ImageData in public API (__init__.py) - Add tests/test_conga.py: detection, image generation, room extraction, calibration data (4-point vacuum↔map pairs), room data structure - Fix ALLOWED_IMAGE_FORMAT dict formatting in const.py - Bump version 0.2.9 → 0.3.0b0
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds Conga vacuum support: new Changes
Sequence Diagram(s)sequenceDiagram
participant Caller
participant CongaHandler as CongaMapImageHandler
participant MapData as ImageData
participant BaseHandler as HypferMapImageHandler
participant Draw as CongaImageDraw
Caller->>CongaHandler: async_get_image_from_json(m_json)
CongaHandler->>MapData: is_conga_map(m_json)?
alt conga detected
CongaHandler->>CongaHandler: _scale_conga_json(m_json, CONGA_SCALE)
CongaHandler->>BaseHandler: async_get_image_from_json(scaled_json)
else not conga
CongaHandler->>BaseHandler: async_get_image_from_json(m_json)
end
BaseHandler->>Draw: render layers/entities
Draw-->>BaseHandler: Image
BaseHandler-->>CongaHandler: Image
CongaHandler-->>Caller: Image
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@SCR/valetudo_map_parser/__init__.py`:
- Around line 1-2: Update the module docstring in __init__.py so the advertised
version matches pyproject.toml: change the version text in the top-level module
string (the triple-quoted docstring in SCR/valetudo_map_parser/__init__.py) from
"0.2.6" to "0.3.0b0" ensuring the exact new version token is used so docs and
quick source inspection reflect the current release.
In `@SCR/valetudo_map_parser/config/shared.py`:
- Around line 154-159: The set_content_type method currently only accepts keys
from ALLOWED_IMAGE_FORMAT (e.g., "pil","png","jpeg") but defaults to
"image/pil", so calling get_content_type() (which returns MIME values) and
passing that back into set_content_type resets formats to PIL; update
set_content_type to accept either a key or a MIME value: if new_image_format is
in ALLOWED_IMAGE_FORMAT keys, set self._image_format =
ALLOWED_IMAGE_FORMAT[new_image_format]; else if new_image_format is in
ALLOWED_IMAGE_FORMAT.values(), set self._image_format = new_image_format;
otherwise fall back to a sensible default (e.g., ALLOWED_IMAGE_FORMAT["pil"]) to
avoid the unexpected reset; reference function set_content_type,
ALLOWED_IMAGE_FORMAT and get_content_type when making the change.
In `@SCR/valetudo_map_parser/config/utils.py`:
- Around line 83-98: Add a factory function that centralizes handler selection
by calling ImageData.detect_vacuum_type(json_data) and branching on its return
value to instantiate the correct handler: when it returns "conga" return a
CongaMapImageHandler(shared) instance, when "rand256" return
ReImageHandler(shared) (or the existing Re/Rand handler), otherwise return
HypferMapImageHandler(shared); replace existing direct instantiations (e.g.,
places creating HypferMapImageHandler(shared) directly) to use this new factory
so CongaMapImageHandler can be reached via the detector.
In `@SCR/valetudo_map_parser/map_data.py`:
- Around line 300-303: The code only falls back to congaPixels when
compressed_pixels is exactly None, which misses upstream payloads that provide
an empty list; change the condition in the ImageData parsing so empty
compressed_pixels is treated the same as missing data (e.g., replace "if
compressed_pixels is None:" with a falsy check like "if not
compressed_pixels:"), then build pixels from json_obj.get("pixels") or
json_obj.get("congaPixels", []) and call
ImageData._convert_pixels_to_compressed(pixels) as before.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 5e71a0d0-95da-49f4-85fb-baa104afb09d
📒 Files selected for processing (7)
SCR/valetudo_map_parser/__init__.pySCR/valetudo_map_parser/config/shared.pySCR/valetudo_map_parser/config/utils.pySCR/valetudo_map_parser/const.pySCR/valetudo_map_parser/map_data.pySCR/valetudo_map_parser/reimg_draw.pypyproject.toml
SCR/valetudo_map_parser/__init__.py
Outdated
| """Valetudo map parser. | ||
| Version: 0.2.7""" | ||
| Version: 0.2.6""" |
There was a problem hiding this comment.
Update the module header version to match the release.
This file still advertises 0.2.6, while pyproject.toml was bumped to 0.3.0b0. Keeping them aligned avoids stale metadata in generated docs and quick source inspection.
Proposed fix
-"""Valetudo map parser.
-Version: 0.2.6"""
+"""Valetudo map parser.
+Version: 0.3.0b0"""📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| """Valetudo map parser. | |
| Version: 0.2.7""" | |
| Version: 0.2.6""" | |
| """Valetudo map parser. | |
| Version: 0.3.0b0""" |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@SCR/valetudo_map_parser/__init__.py` around lines 1 - 2, Update the module
docstring in __init__.py so the advertised version matches pyproject.toml:
change the version text in the top-level module string (the triple-quoted
docstring in SCR/valetudo_map_parser/__init__.py) from "0.2.6" to "0.3.0b0"
ensuring the exact new version token is used so docs and quick source inspection
reflect the current release.
| def set_content_type(self, new_image_format: str = "image/pil") -> None: | ||
| """Set image format / content type""" | ||
| if new_image_format not in ALLOWED_IMAGE_FORMAT.keys(): | ||
| self._image_format = "image/pil" | ||
| return | ||
| self._image_format = ALLOWED_IMAGE_FORMAT.get(new_image_format) |
There was a problem hiding this comment.
Accept MIME values here or change the default to a format key.
Line 154 defaults to "image/pil", but Line 156 only accepts the keys from ALLOWED_IMAGE_FORMAT ("pil", "png", "jpeg"). That means round-tripping get_content_type() back into set_content_type() will unexpectedly reset PNG/JPEG back to PIL.
Proposed fix
- def set_content_type(self, new_image_format: str = "image/pil") -> None:
- """Set image format / content type"""
- if new_image_format not in ALLOWED_IMAGE_FORMAT.keys():
- self._image_format = "image/pil"
- return
- self._image_format = ALLOWED_IMAGE_FORMAT.get(new_image_format)
+ def set_content_type(self, new_image_format: str = "pil") -> None:
+ """Set image format / content type."""
+ if new_image_format in ALLOWED_IMAGE_FORMAT.values():
+ self._image_format = new_image_format
+ return
+ self._image_format = ALLOWED_IMAGE_FORMAT.get(new_image_format, "image/pil")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@SCR/valetudo_map_parser/config/shared.py` around lines 154 - 159, The
set_content_type method currently only accepts keys from ALLOWED_IMAGE_FORMAT
(e.g., "pil","png","jpeg") but defaults to "image/pil", so calling
get_content_type() (which returns MIME values) and passing that back into
set_content_type resets formats to PIL; update set_content_type to accept either
a key or a MIME value: if new_image_format is in ALLOWED_IMAGE_FORMAT keys, set
self._image_format = ALLOWED_IMAGE_FORMAT[new_image_format]; else if
new_image_format is in ALLOWED_IMAGE_FORMAT.values(), set self._image_format =
new_image_format; otherwise fall back to a sensible default (e.g.,
ALLOWED_IMAGE_FORMAT["pil"]) to avoid the unexpected reset; reference function
set_content_type, ALLOWED_IMAGE_FORMAT and get_content_type when making the
change.
| @staticmethod | ||
| def detect_vacuum_type(json_data: dict) -> str: | ||
| """Detect the vacuum type from the raw JSON map data. | ||
|
|
||
| Returns: | ||
| 'conga' — Conga vacuum (congaPixels present in layers) | ||
| 'hypfer' — Standard Hypfer/Valetudo vacuum | ||
| 'rand256' — Rand256 / Valetudo Re vacuum (rrm key present) | ||
| """ | ||
| if not isinstance(json_data, dict): | ||
| return "hypfer" | ||
| if "rrm" in json_data or json_data.get("__class") == "RRMap": | ||
| return "rand256" | ||
| if ImageData.is_conga_map(json_data): | ||
| return "conga" | ||
| return "hypfer" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Definitions and call sites for detect_vacuum_type():"
rg -n -C2 '\bdetect_vacuum_type\s*\(' --type=py
echo
echo "References to concrete handler classes:"
rg -n -C3 '\bCongaMapImageHandler\b|\bHypferMapImageHandler\b|\bReImageHandler\b' --type=py
echo
echo "Potential factory/selection code:"
rg -n -C4 'detect_vacuum_type|CongaMapImageHandler|HypferMapImageHandler|ReImageHandler|handler' --type=pyRepository: sca075/Python-package-valetudo-map-parser
Length of output: 50397
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== CALL SITES for detect_vacuum_type() ==="
rg -n 'detect_vacuum_type\(' --type=py | grep -v 'def detect_vacuum_type'
echo
echo "=== IMPORTS of BaseHandler.detect_vacuum_type ==="
rg -n 'from.*detect_vacuum_type|import.*detect_vacuum_type' --type=py
echo
echo "=== Check main __init__.py for handler factory logic ==="
head -200 SCR/valetudo_map_parser/__init__.py | tail -120Repository: sca075/Python-package-valetudo-map-parser
Length of output: 128
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Checking __init__.py for handler initialization logic ==="
cat SCR/valetudo_map_parser/__init__.py | head -250 | tail -100
echo
echo "=== Check for RRMapParser class (main entry point) ==="
fd -t f "RRMapParser" . --type py 2>/dev/null | head -5
echo
echo "=== Search for RRMapParser definition ==="
rg -n 'class RRMapParser' --type=py -A 30Repository: sca075/Python-package-valetudo-map-parser
Length of output: 2472
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== RRMapParser class definition ==="
rg -n 'class RRMapParser' --type=py -A 50
echo
echo "=== Search for where handlers are instantiated in main code ==="
rg -n 'HypferMapImageHandler\(|CongaMapImageHandler\(|ReImageHandler\(' --type=py | grep -v test | grep -v '\.pyc'Repository: sca075/Python-package-valetudo-map-parser
Length of output: 4510
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Public methods accepting json_data in handlers ==="
rg -n 'def.*json_data' --type=py -B 2 -A 3 | head -80
echo
echo "=== Check if detect_vacuum_type is referenced in comments/docstrings ==="
rg -i 'detect.*vacuum|vacuum.*detect' --type=py -B 2 -A 2
echo
echo "=== Look for async_get_image entry points in handlers ==="
rg -n 'async def async_get_image' --type=py -A 5 | head -60Repository: sca075/Python-package-valetudo-map-parser
Length of output: 7386
This detector is not integrated into handler selection—CongaMapImageHandler cannot be instantiated.
The detect_vacuum_type() method has no call sites in the codebase. Handler instantiation occurs directly (e.g., HypferMapImageHandler(shared)), not through a factory that branches on the detected vacuum type. Without wiring this detector into the handler selection path, Conga support remains unreachable despite the handler and detector both existing.
To activate Conga support, add a factory or entry point that:
- Calls
detect_vacuum_type(json_data) - Branches on the result to instantiate
CongaMapImageHandlerwhen the return value is"conga" - Falls back to
HypferMapImageHandlerorReImageHandlerfor other types
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@SCR/valetudo_map_parser/config/utils.py` around lines 83 - 98, Add a factory
function that centralizes handler selection by calling
ImageData.detect_vacuum_type(json_data) and branching on its return value to
instantiate the correct handler: when it returns "conga" return a
CongaMapImageHandler(shared) instance, when "rand256" return
ReImageHandler(shared) (or the existing Re/Rand handler), otherwise return
HypferMapImageHandler(shared); replace existing direct instantiations (e.g.,
places creating HypferMapImageHandler(shared) directly) to use this new factory
so CongaMapImageHandler can be reached via the detector.
| compressed_pixels = json_obj.get("compressedPixels") | ||
| if compressed_pixels is None: | ||
| pixels = json_obj.get("pixels", []) | ||
| pixels = json_obj.get("pixels") or json_obj.get("congaPixels", []) | ||
| compressed_pixels = ImageData._convert_pixels_to_compressed(pixels) |
There was a problem hiding this comment.
Treat empty compressedPixels the same as missing data.
Right now the Conga fallback only runs when compressedPixels is None. If an upstream payload serializes that field as [] instead of omitting it, Line 302 never looks at congaPixels and the layer is recorded as empty.
Proposed fix
- compressed_pixels = json_obj.get("compressedPixels")
- if compressed_pixels is None:
+ compressed_pixels = json_obj.get("compressedPixels")
+ if not compressed_pixels:
pixels = json_obj.get("pixels") or json_obj.get("congaPixels", [])
compressed_pixels = ImageData._convert_pixels_to_compressed(pixels)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| compressed_pixels = json_obj.get("compressedPixels") | |
| if compressed_pixels is None: | |
| pixels = json_obj.get("pixels", []) | |
| pixels = json_obj.get("pixels") or json_obj.get("congaPixels", []) | |
| compressed_pixels = ImageData._convert_pixels_to_compressed(pixels) | |
| compressed_pixels = json_obj.get("compressedPixels") | |
| if not compressed_pixels: | |
| pixels = json_obj.get("pixels") or json_obj.get("congaPixels", []) | |
| compressed_pixels = ImageData._convert_pixels_to_compressed(pixels) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@SCR/valetudo_map_parser/map_data.py` around lines 300 - 303, The code only
falls back to congaPixels when compressed_pixels is exactly None, which misses
upstream payloads that provide an empty list; change the condition in the
ImageData parsing so empty compressed_pixels is treated the same as missing data
(e.g., replace "if compressed_pixels is None:" with a falsy check like "if not
compressed_pixels:"), then build pixels from json_obj.get("pixels") or
json_obj.get("congaPixels", []) and call
ImageData._convert_pixels_to_compressed(pixels) as before.
- Add CongaMapImageHandler: scales Conga JSON (pixelSize, canvas size, entity coordinates) by ×5 before the Hypfer render pipeline, producing solid filled rooms and correctly positioned entities without post-upscale - Add CongaImageDraw: thin subclass of HypferImageDraw; coordinate scaling handled entirely in the handler - Add ImageData.is_conga_map() for detection via congaPixels field presence - Export CongaMapImageHandler and ImageData in public API (__init__.py) - Add tests/test_conga.py: detection, image generation, room extraction, calibration data (4-point vacuum↔map pairs), room data structure - Fix ALLOWED_IMAGE_FORMAT dict formatting in const.py - Bump version 0.2.9 → 0.3.0b0
There was a problem hiding this comment.
🧹 Nitpick comments (1)
SCR/valetudo_map_parser/conga_handler.py (1)
46-52: ScalepixelSizefrom the payload, not from an assumption.Line 47 hardcodes
pixelSizetoscale, while the rest of the method multiplies source values. That stays correct only while every Conga map remainspixelSize == 1; using the incoming value keeps the transform self-consistent and avoids future skew if a payload variant changes.♻️ Proposed fix
scaled = copy.deepcopy(m_json) - scaled["pixelSize"] = scale + scaled["pixelSize"] = int(scaled.get("pixelSize", 1)) * scale size = scaled.get("size", {}) scaled["size"] = { "x": int(size.get("x", 800)) * scale, "y": int(size.get("y", 800)) * scale, }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@SCR/valetudo_map_parser/conga_handler.py` around lines 46 - 52, The code currently sets scaled["pixelSize"] = scale which assumes the incoming payload's pixelSize is 1; instead read the incoming value from m_json and multiply it by scale so the transform stays self-consistent. Change the assignment to compute original_pixel = int(m_json.get("pixelSize", 1)) and set scaled["pixelSize"] = original_pixel * scale (leaving the existing size scaling logic as-is), referencing the variables scaled, m_json, pixelSize, scale, and size to locate the change in conga_handler.py.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@SCR/valetudo_map_parser/conga_handler.py`:
- Around line 46-52: The code currently sets scaled["pixelSize"] = scale which
assumes the incoming payload's pixelSize is 1; instead read the incoming value
from m_json and multiply it by scale so the transform stays self-consistent.
Change the assignment to compute original_pixel = int(m_json.get("pixelSize",
1)) and set scaled["pixelSize"] = original_pixel * scale (leaving the existing
size scaling logic as-is), referencing the variables scaled, m_json, pixelSize,
scale, and size to locate the change in conga_handler.py.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c3eb75cf-f6af-47d6-8a49-582c4a23fec0
📒 Files selected for processing (2)
SCR/valetudo_map_parser/conga_draw.pySCR/valetudo_map_parser/conga_handler.py
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@pyproject.toml`:
- Line 3: The pyproject.toml version field is set to "0.3.0b1" but the PR states
the intended prerelease is "v0.3.0b0"; update the version string in
pyproject.toml (version = "0.3.0b1") to the correct prerelease identifier to
match the release plan and ensure package metadata stays in sync with the
package __init__.py (e.g., the __version__ or VERSION constant) so tags and
published artifacts use the intended prerelease number.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 82684260-a66d-4f6e-9f56-5425a6c4b490
📒 Files selected for processing (2)
SCR/valetudo_map_parser/__init__.pypyproject.toml
- Add CongaMapImageHandler subclassing HypferMapImageHandler with JSON coordinate scaling (pixelSize=1 → 5) via async_get_conga_from_json - Add CongaImageDraw subclassing HypferImageDraw as Conga draw engine - Add is_conga: bool = False to CameraShared for vacuum type detection - Route Conga in BaseHandler._generate_new_image via hasattr duck-typing - Remove is_conga_map() from ImageData and detect_vacuum_type() from BaseHandler — detection is mqtt_vacuum_camera's responsibility - Export CongaMapImageHandler and ImageData from public API
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (2)
SCR/valetudo_map_parser/map_data.py (1)
288-291:⚠️ Potential issue | 🟡 MinorTreat empty
compressedPixelsas missing data too.The Conga fallback still only runs when
compressedPixels is None. If an upstream payload sendscompressedPixels: [], this path never readscongaPixelsand the layer is stored empty.Proposed fix
- compressed_pixels = json_obj.get("compressedPixels") - if compressed_pixels is None: + compressed_pixels = json_obj.get("compressedPixels") + if not compressed_pixels: pixels = json_obj.get("pixels") or json_obj.get("congaPixels", []) compressed_pixels = ImageData._convert_pixels_to_compressed(pixels)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@SCR/valetudo_map_parser/map_data.py` around lines 288 - 291, The code only falls back to congaPixels when compressed_pixels is None, so an upstream empty array compressedPixels: [] is treated as present and prevents using congaPixels; update the condition in the map parsing logic to treat empty lists as missing (e.g., check for falsy or len==0) so that when compressed_pixels is None or empty you retrieve pixels = json_obj.get("pixels") or json_obj.get("congaPixels", []) and call ImageData._convert_pixels_to_compressed(pixels) to populate compressed_pixels.SCR/valetudo_map_parser/config/shared.py (1)
155-160:⚠️ Potential issue | 🟡 MinorAccept MIME values here or change the default.
get_content_type()returns MIME values, but this setter still only accepts the short keys fromALLOWED_IMAGE_FORMAT. Passing the current content type back intoset_content_type()will silently reset PNG/JPEG outputs to PIL.Proposed fix
- def set_content_type(self, new_image_format: str = "image/pil") -> None: - """Set image format / content type""" - if new_image_format not in ALLOWED_IMAGE_FORMAT.keys(): - self._image_format = "image/pil" - return - self._image_format = ALLOWED_IMAGE_FORMAT.get(new_image_format) + def set_content_type(self, new_image_format: str = "pil") -> None: + """Set image format / content type.""" + if new_image_format in ALLOWED_IMAGE_FORMAT: + self._image_format = ALLOWED_IMAGE_FORMAT[new_image_format] + return + if new_image_format in ALLOWED_IMAGE_FORMAT.values(): + self._image_format = new_image_format + return + self._image_format = ALLOWED_IMAGE_FORMAT["pil"]🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@SCR/valetudo_map_parser/config/shared.py` around lines 155 - 160, set_content_type currently only accepts short keys from ALLOWED_IMAGE_FORMAT and resets when passed a MIME string; update it to accept either the mapping keys or the MIME values returned by get_content_type. In set_content_type (and using ALLOWED_IMAGE_FORMAT and _image_format), check: if new_image_format is a key => set _image_format to ALLOWED_IMAGE_FORMAT[new_image_format]; else if new_image_format is one of ALLOWED_IMAGE_FORMAT.values() => set _image_format to new_image_format; otherwise fall back to the default ("image/pil" or the chosen canonical default) and return. Ensure the stored _image_format is always the MIME string.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@SCR/valetudo_map_parser/conga_handler.py`:
- Around line 32-35: The Conga handler constructor does not set the shared flag;
in the __init__ method of the Conga handler (the def __init__(self, shared_data:
CameraShared) -> None: constructor that currently calls
super().__init__(shared_data) and creates CongaImageDraw(self)), set
shared_data.is_conga = True to keep CameraShared.is_conga synchronized with the
active handler; update that constructor to assign the flag immediately after
calling super().__init__ (and consider leaving a brief comment noting the state
synchronization).
---
Duplicate comments:
In `@SCR/valetudo_map_parser/config/shared.py`:
- Around line 155-160: set_content_type currently only accepts short keys from
ALLOWED_IMAGE_FORMAT and resets when passed a MIME string; update it to accept
either the mapping keys or the MIME values returned by get_content_type. In
set_content_type (and using ALLOWED_IMAGE_FORMAT and _image_format), check: if
new_image_format is a key => set _image_format to
ALLOWED_IMAGE_FORMAT[new_image_format]; else if new_image_format is one of
ALLOWED_IMAGE_FORMAT.values() => set _image_format to new_image_format;
otherwise fall back to the default ("image/pil" or the chosen canonical default)
and return. Ensure the stored _image_format is always the MIME string.
In `@SCR/valetudo_map_parser/map_data.py`:
- Around line 288-291: The code only falls back to congaPixels when
compressed_pixels is None, so an upstream empty array compressedPixels: [] is
treated as present and prevents using congaPixels; update the condition in the
map parsing logic to treat empty lists as missing (e.g., check for falsy or
len==0) so that when compressed_pixels is None or empty you retrieve pixels =
json_obj.get("pixels") or json_obj.get("congaPixels", []) and call
ImageData._convert_pixels_to_compressed(pixels) to populate compressed_pixels.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a237c16e-24d2-4243-bbce-35410d38c7b7
📒 Files selected for processing (4)
SCR/valetudo_map_parser/config/shared.pySCR/valetudo_map_parser/config/utils.pySCR/valetudo_map_parser/conga_handler.pySCR/valetudo_map_parser/map_data.py
🚧 Files skipped from review as they are similar to previous changes (1)
- SCR/valetudo_map_parser/config/utils.py
| def __init__(self, shared_data: CameraShared) -> None: | ||
| """Initialise the Conga image handler.""" | ||
| super().__init__(shared_data) | ||
| self.imd = CongaImageDraw(self) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf 'Assignments and reads of is_conga:\n'
rg -n -C2 '\bis_conga\b'
printf '\nConga handler construction sites:\n'
rg -n -C2 '\bCongaMapImageHandler\s*\('Repository: sca075/Python-package-valetudo-map-parser
Length of output: 925
Set shared_data.is_conga = True in the Conga handler constructor to keep state synchronized.
CameraShared.is_conga is initialized to False and is never set to True when the Conga handler is active. While the flag is not currently read elsewhere in the codebase, keeping shared state synchronized with the active handler is a valid code hygiene practice.
Suggested fix
def __init__(self, shared_data: CameraShared) -> None:
"""Initialise the Conga image handler."""
super().__init__(shared_data)
+ self.shared.is_conga = True
self.imd = CongaImageDraw(self)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@SCR/valetudo_map_parser/conga_handler.py` around lines 32 - 35, The Conga
handler constructor does not set the shared flag; in the __init__ method of the
Conga handler (the def __init__(self, shared_data: CameraShared) -> None:
constructor that currently calls super().__init__(shared_data) and creates
CongaImageDraw(self)), set shared_data.is_conga = True to keep
CameraShared.is_conga synchronized with the active handler; update that
constructor to assign the flag immediately after calling super().__init__ (and
consider leaving a brief comment noting the state synchronization).
There was a problem hiding this comment.
♻️ Duplicate comments (1)
SCR/valetudo_map_parser/__init__.py (1)
2-2:⚠️ Potential issue | 🟡 MinorAlign the module docstring version with the release metadata.
Line 2 advertises
0.3.0b2, but this PR’s stated release target is0.3.0b0. Please keep the header in sync with the package version so source inspection and generated docs do not report a different build.#!/bin/bash # Verify that package metadata and source-advertised versions agree. # Expected result: the same version token appears in package metadata and this module docstring. fd -HI 'pyproject.toml|setup.cfg|setup.py' . rg -n '(^version\s*=)|(__version__\s*=)|(^Version: )' pyproject.toml setup.cfg setup.py SCR 2>/dev/null🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@SCR/valetudo_map_parser/__init__.py` at line 2, Update the module docstring version string in SCR/valetudo_map_parser/__init__.py (the "Version: 0.3.0b2" header) to match the release metadata token (0.3.0b0) so source-advertised version aligns with package metadata; check the package metadata file (pyproject.toml / setup.cfg / setup.py) for the canonical version and change the Version header in __init__.py to that exact token, and re-run the provided verification commands to confirm all version tokens match.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@SCR/valetudo_map_parser/__init__.py`:
- Line 2: Update the module docstring version string in
SCR/valetudo_map_parser/__init__.py (the "Version: 0.3.0b2" header) to match the
release metadata token (0.3.0b0) so source-advertised version aligns with
package metadata; check the package metadata file (pyproject.toml / setup.cfg /
setup.py) for the canonical version and change the Version header in __init__.py
to that exact token, and re-run the provided verification commands to confirm
all version tokens match.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 17467792-e2da-4d2c-b9af-628238b35f33
📒 Files selected for processing (2)
SCR/valetudo_map_parser/__init__.pypyproject.toml
🚧 Files skipped from review as they are similar to previous changes (1)
- pyproject.toml
feat: add Conga vacuum support — bump to v0.3.0b2
entity coordinates) by ×5 before the Hypfer render pipeline, producing
solid filled rooms and correctly positioned entities without post-upscale
handled entirely in the handler
calibration data (4-point vacuum↔map pairs), room data structure
Summary by CodeRabbit
New Features
Chores