Conversation
|
analyze again with the current state of development branch |
Here is the updated assessment against the current tip of Code Quality Assessment —
|
| Commit | Change | Quality impact |
|---|---|---|
1d8340f |
Remove Monthly + Yearly COP sensors | ✅ cop_sensor.py shrunk from 886 → 577 lines, 5 classes → 3 |
992b25b |
Fix area schema to use vol.In |
✅ Minor correctness fix |
710f2bb |
Add BLOCK_LABELS dict to const.py + translations |
➡ Neutral — adds 61-line dict to const.py, improves UI |
0f4d664 |
Fix ventilator speed unit/device_class | ✅ Correctness fix in sensor_meta.py |
Metrics at a Glance (dev branch vs previous)
| Metric | Previous | Now | Δ |
|---|---|---|---|
| Production lines | 11,704 | 11,486 | −218 ✅ |
| Test functions | 386 | 393 | +7 ✅ |
| Tests passing | 371 | 378 | +7 ✅ |
| Tests failing | 15 | 15 | 0 (same failures) |
| Lint errors (ruff) | 86 | 80 | −6 ✅ |
Broad except Exception |
13 | 13 | 0 |
| Functions > 50 lines | 20 | 20 | 0 |
| High-CC functions (≥10) | 10 | 14 | +4 |
| Type hint coverage | 80% | 81% | +1% ✅ |
| Test/code ratio | 0.37x | 0.38x | ≈same |
Findings — Status by Category
✅ Resolved / Improved
cop_sensor.pyreduced from 886 → 577 lines by removing unused Monthly/Yearly COP classes. Thenative_valueCC≈11 offender from the previous report (the monthly/yearly classes) is now gone.- Ventilator speed sensor now has correct
device_classand unit. - Area schema fixed to use
vol.In(stricter, correct). - 7 new tests added, all passing.
⚠️ Still Open (unchanged from previous report)
-
decode_valueduplicated — still copy-pasted insensor.pyandcop_sensor.py.value_codec.pyexists for this. Thecop_sensor.pycopy still has the comment "duplicated to avoid circular imports" even though importing fromvalue_codechas no circularity at all. -
hass.datamulti-instance safety —device,device_id,write_manager,register_managerare still stored athass.data[DOMAIN](global, not perentry_id). A second config entry would overwrite the first. The duplicatesetdefaultis now actually three calls (lines 44, 86, 156) instead of two. -
sensor_meta.py— still 971 lines / 97 entries. The file's module docstring still claims to be the metadata store, while register map tuples also carry metadata via a 6th element. No single source of truth. -
13 bare
except Exception— identical count and locations as before. No narrowing of exception types. -
20 functions > 50 lines — same list.
send_request()(136 lines, CC≈26) and_list_serial_ports()(96 lines, CC≈26) remain the worst offenders. -
High-CC function count increased from 10 → 14 —
_async_enable_integration_disabled_entities()(CC≈14) andshould_hide_entity_by_default()(CC≈11, grown due to newBLOCK_LABELScontent inconst.py) are newly flagged. The functionshould_hide_entity_by_defaultat CC≈11 / 58 lines is itself a smell — hiding logic should be data-driven (a set of keywords), not a chain ofifbranches. -
asyncio.sleep(0.01)insideasync with device.lock— still present in 9 places acrossswitch.py,select.py,number.py,time.py,calendar.py,schedule.py. -
15 failing tests — identical set. 13 fail due to
pytest-asyncionot being inrequirements_test.txt. 2 fail due to incomplete mock intest_thz_device_extended.py. These are non-functional tests that appear to be written but never run. -
has_entity_nameonly conditionally set (when atranslation_keyexists) — entity naming is inconsistent between translated and untranslated entities. -
1 live f-string in a
_LOGGERcall —thz_device.py:630uses_LOGGER.error(f"...")instead of_LOGGER.error("...", e). 6 commented-out_LOGGERdebug lines also remain inthz_device.py. -
4 internal markdown files in repo root —
BUGFIX_CONNECTION_TIMEOUT.md,CODE_REVIEW_SUMMARY.md,IMPLEMENTATION_SUMMARY.md,REFACTORING_SUMMARY.mdare developer artefacts, not user docs. Should move todocs/or be removed.
Priority Order for Next Steps
| Priority | Item |
|---|---|
| High | Fix hass.data global-vs-per-entry (multi-instance safety) |
| High | Add pytest-asyncio to requirements_test.txt to un-fail 13 tests |
| Medium | Consolidate decode_value into value_codec.py |
| Medium | Narrow the 13 except Exception to specific types |
| Medium | Make should_hide_entity_by_default data-driven (set of keywords/prefixes) to reduce CC |
| Low | Move the 4 internal .md files out of repo root |
| Low | Fix the lone f-string logger call + remove 6 commented-out debug lines in thz_device.py |
Overall grade: C+ → B− (slight improvement due to COP cleanup and test additions, but the structural issues remain untouched).
Assessed overall code quality across the integration. No code changes were made — findings are documented below for prioritization.
Key Findings
hass.data:device,device_id,write_manager,register_managerstored athass.data[DOMAIN](global) instead of underentry_id— breaks with two simultaneous config entriesdecode_valueduplicated insensor.py,cop_sensor.py, andtests/test_helpers.py;value_codec.pyexists for exactly this purposesensor_meta.py(97 entries, 971 lines) and register map 6th-tuple element both define sensor metadata with no clear precedence ruleexcept Exceptioncatches acrossthz_device.py,__init__.py,calendar.py,config_flow.pysend_request()and_list_serial_ports()reach CC≈26asyncio.sleep(0.01)held insideasync with device.lockin 9 places — blocks other entities from device access during write operationspytest-asyncio(not inrequirements_test.txt), 2 due to incomplete mock setupcalendar,cop_sensor,config_flow,number,switch,select,time,value_codec, others)BUGFIX_*.md,CODE_REVIEW_*.md, etc.) clutter repo root💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.