Skip to content

Improve diagnostics + adapter handling#39

Merged
jgeudens merged 6 commits intomasterfrom
dev/diagnostics
Apr 23, 2026
Merged

Improve diagnostics + adapter handling#39
jgeudens merged 6 commits intomasterfrom
dev/diagnostics

Conversation

@jgeudens
Copy link
Copy Markdown
Member

@jgeudens jgeudens commented Apr 23, 2026

Summary by CodeRabbit

  • Documentation

    • Added an architecture review documenting priorities, issues and remediation plans.
    • Updated adapter specification docs to clarify default connection fields and version formatting.
  • Chores

    • Normalised agent model identifier casing in agent configs.
    • Adjusted default adapter connection settings and version identifier.
  • Style/Logs

    • Standardised informational and diagnostic log string formatting for clearer UTF‑8 output.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 23, 2026

Walkthrough

Changes adjust agent frontmatter model identifiers (Haikuhaiku), add an architecture review document, modify adapter defaults and version string in adapters/describe.json, and standardise diagnostic logging and adapter-version logging across multiple source files. No API signatures or runtime control flow were materially changed.

Changes

Cohort / File(s) Summary
Agent configuration
\.claude/agents/build.md, \.claude/agents/test-runner.md
Model frontmatter value changed from Haiku to haiku (casing only).
Architecture & spec docs
Plan/architecture_review.md, adapters/json-rpc-spec.md
Added architecture review document. JSON-RPC spec expanded to document debug version format and to state that connections defaults include a TCP entry with serial-related default fields; example baudrate updated to 115200.
Adapter defaults
adapters/describe.json
Removed second (serial) default connection; remaining default keeps TCP settings and now includes serial-related fields inline. Top-level version hash updated.
Logging changes — comms & models
src/communication/modbuspoll.cpp, src/models/settingsmodel.cpp, src/ProtocolAdapter/adaptermanager.cpp
Added an info log of active register list in ModbusPoll before starting communication; SettingsModel now logs adapter id/version (formats version as v<ver> or unknown version); adapter diagnostics now pass messages through qUtf8Printable(...) and unknown levels are combined into a single formatted string.
Logging changes — parsers & handlers
src/datahandling/graphdatahandler.cpp, src/datahandling/expressionparser.cpp, src/importexport/presetparser.cpp
Removed one info-level register-list log in GraphDataHandler; multiple warning/info log arguments converted to qUtf8Printable(...) for consistent UTF-8 logging; XML parse-error logging similarly wrapped.
Minor formatting
src/mainapp.cpp
Whitespace/argument-list formatting adjusted; initial info logs wrapped with qUtf8Printable(...).

Possibly related PRs

  • Devicesettings UI #19 — updates the same .claude/agents/* model field casing (directly related).
  • Subexpressions info from adapter #26 — changes adapter diagnostic logging in src/ProtocolAdapter/adaptermanager.cpp (related logging formatting).
  • UI names #13 — previous changes to adapters/describe.json defaults for connections (related adapter defaults).
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 15.38% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Improve diagnostics + adapter handling' is broad and partially related to the changeset, covering diagnostics improvements and adapter configuration changes, but does not highlight the most important changes. Consider a more specific title such as 'Add diagnostic logging and standardise model identifier casing' to better reflect the primary changes across the multiple modified areas.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev/diagnostics

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/models/settingsmodel.cpp (1)

215-232: 🛠️ Refactor suggestion | 🟠 Major

Add the required source Doxygen for this public method.

The changed method is called from AdapterManager, but it has no source-level brief comment. The new logging is fine; please add the public API documentation block above the function.

Proposed documentation block
+/*! \brief Update adapter metadata from an adapter.describe result and notify observers.
+ * \param adapterId       The adapter identifier string.
+ * \param describeResult  The JSON object returned by adapter.describe.
+ */
 void SettingsModel::updateAdapterFromDescribe(const QString& adapterId, const QJsonObject& describeResult)
 {

As per coding guidelines, **/*.{cpp,cxx}: Document all public functions with brief Doxygen comments in the source file.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/models/settingsmodel.cpp` around lines 215 - 232, Add a Doxygen source
comment block immediately above the SettingsModel::updateAdapterFromDescribe
method documenting it as a public API: include a brief description of what the
method does, an `@param` for adapterId describing the adapter identifier, an
`@param` for describeResult describing the JSON describe result, and an `@return`
(void) or note that it emits adapterDataChanged; ensure the comment style
matches other source Doxygen blocks (brief, single-paragraph) and place it just
above the function definition so AdapterManager callers see the documentation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@adapters/describe.json`:
- Line 261: The "version" value currently set to "0.0.1-dev/diagnostics:c471210"
in adapters/describe.json uses '/' and ':' which can break strict parsers;
update the "version" field to a parser-safe form that follows the documented
format (semver or semver-branch), for example "0.0.1-dev-diagnostics+c471210" or
"0.0.1-dev-diagnostics" (or update your spec if you intentionally need the extra
suffix), and ensure the code or consumers reading the "version" key expect the
chosen format.

In `@adapters/json-rpc-spec.md`:
- Line 117: The spec and the describe data disagree on the serial default
baudrate: update the serial default so `defaults`/`defaults.connections` in the
JSON-RPC spec and the serial fields table match the value used by the code;
specifically change the documented `baudrate` in the serial fields table to
115200 (or, alternatively, change `baudrate` in adapters/describe.json to 9600)
so `defaults.connections` and the serial documentation are consistent and
generated configs don’t diverge.

In `@Plan/architecture_review.md`:
- Around line 45-48: The recommendation text is contradictory: instead of saying
"Extract communication timing/stats into GraphDataModel", change it to state
that communication timing/stats should be extracted out of GraphDataModel into a
separate value struct or component (e.g., a CommunicationStats class/struct)
that GraphDataModel references or observes; update the wording to explicitly
recommend moving timing/stats ownership to CommunicationStats (or a dedicated
struct) and signalling updates to GraphDataModel rather than merging those
concerns into GraphDataModel.

---

Outside diff comments:
In `@src/models/settingsmodel.cpp`:
- Around line 215-232: Add a Doxygen source comment block immediately above the
SettingsModel::updateAdapterFromDescribe method documenting it as a public API:
include a brief description of what the method does, an `@param` for adapterId
describing the adapter identifier, an `@param` for describeResult describing the
JSON describe result, and an `@return` (void) or note that it emits
adapterDataChanged; ensure the comment style matches other source Doxygen blocks
(brief, single-paragraph) and place it just above the function definition so
AdapterManager callers see the documentation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a927d59c-c676-46be-8e43-d197ba0eb77b

📥 Commits

Reviewing files that changed from the base of the PR and between 1deed2c and 6ac02f7.

⛔ Files ignored due to path filters (2)
  • adapters/dummymodbusadapter.exe is excluded by !**/*.exe
  • adapters/modbusadapter.exe is excluded by !**/*.exe
📒 Files selected for processing (10)
  • .claude/agents/build.md
  • .claude/agents/test-runner.md
  • Plan/architecture_review.md
  • adapters/describe.json
  • adapters/dummymodbusadapter
  • adapters/json-rpc-spec.md
  • adapters/modbusadapter
  • src/communication/modbuspoll.cpp
  • src/datahandling/graphdatahandler.cpp
  • src/models/settingsmodel.cpp
💤 Files with no reviewable changes (1)
  • src/datahandling/graphdatahandler.cpp

Comment thread adapters/describe.json Outdated
Comment thread adapters/json-rpc-spec.md
Comment thread Plan/architecture_review.md
Documents findings from a full codebase review focused on architecture
and maintainability, with prioritised action items (P1–P3) covering
ownership/lifetime issues, static shared state in QMuParser,
GraphDataModel SRP violations, CommunicationStats coupling,
missing test coverage, and several code-quality items.
Fix serial default, improve diagnostics
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/ProtocolAdapter/adaptermanager.cpp (1)

108-130: ⚠️ Potential issue | 🟠 Major

Same qUtf8Printable concern applied across all diagnostic branches.

Adapter diagnostic messages can contain arbitrary text (including translated strings and content originating from user devices/config), so this site is particularly exposed to the Unicode-round-trip issue described for presetparser.cpp: qUtf8Printable produces UTF-8 bytes, but QDebug's const char* overload decodes them as Latin-1, which will corrupt any non-ASCII character before it reaches ScopeLogging/DiagnosticModel. Prefer streaming the QString directly:

🛠️ Suggested change
     if (level == QStringLiteral("debug"))
     {
-        qCDebug(scopeAdapter) << qUtf8Printable(message);
+        qCDebug(scopeAdapter) << message;
     }
     else if (level == QStringLiteral("info"))
     {
-        qCInfo(scopeAdapter) << qUtf8Printable(message);
+        qCInfo(scopeAdapter) << message;
     }
     else if (level == QStringLiteral("warning"))
     {
-        qCWarning(scopeAdapter) << qUtf8Printable(message);
+        qCWarning(scopeAdapter) << message;
     }
     else if (level == QStringLiteral("error"))
     {
-        qCCritical(scopeAdapter) << qUtf8Printable(message);
+        qCCritical(scopeAdapter) << message;
     }
     else
     {
-        qCWarning(scopeAdapter) << qUtf8Printable(
-          QString("AdapterClient: unknown diagnostic level: %1 - %2").arg(level, message));
+        qCWarning(scopeAdapter)
+          << QString("AdapterClient: unknown diagnostic level: %1 - %2").arg(level, message);
     }

Note: the Cppcheck unknownMacro hint on line 112 is a configuration false positive (qCDebug is a Qt macro) and can be ignored.

QDebug operator<< const char* Latin-1 vs QString UTF-8 Qt 6 logging
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/ProtocolAdapter/adaptermanager.cpp` around lines 108 - 130, In
AdapterManager::onAdapterDiagnostic replace uses of qUtf8Printable(message)
passed to QDebug macros with streaming the QString directly (e.g., pass message
or qPrintable-free QString) so QDebug uses the QString overload and avoids
UTF-8→Latin1 corruption; update every branch (qCDebug, qCInfo, qCWarning,
qCCritical and the fallback warning) to stream the QString instead of
qUtf8Printable, leaving the existing diagnostic text/formatting intact.
♻️ Duplicate comments (1)
Plan/architecture_review.md (1)

45-48: ⚠️ Potential issue | 🟡 Minor

Clarify the extraction direction to avoid contradictory guidance.

This section currently suggests moving comms timing/stats into GraphDataModel, which conflicts with Section 1.3’s decomposition goal. Please state that timing/stats should be extracted out of GraphDataModel into CommunicationStats (or a dedicated struct), with updates signalled to consumers.

Proposed wording
 **Recommended split:**
 - Keep `GraphDataModel : QAbstractTableModel` for the table view.
-- Extract communication timing/stats into `GraphDataModel` or a dedicated value struct, owned by `CommunicationStats` and signalled to whomever needs it.
+- Extract communication timing/stats out of `GraphDataModel` into a dedicated value struct/component owned by `CommunicationStats`, and signal updates to whichever model/view consumes them.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Plan/architecture_review.md` around lines 45 - 48, The text currently
contradicts Section 1.3 by saying comms timing/stats should be moved into
GraphDataModel; change the wording to clearly state that timing/stats must be
extracted out of GraphDataModel (which remains a QAbstractTableModel for the
table view) into CommunicationStats or a dedicated value struct, owned by
CommunicationStats, and that updates are signalled to consumers; reference
GraphDataModel, CommunicationStats and QAbstractTableModel in the revised
sentence so readers know which component retains the table responsibilities and
which owns the timing/stats.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/ProtocolAdapter/adaptermanager.cpp`:
- Around line 108-130: In AdapterManager::onAdapterDiagnostic replace uses of
qUtf8Printable(message) passed to QDebug macros with streaming the QString
directly (e.g., pass message or qPrintable-free QString) so QDebug uses the
QString overload and avoids UTF-8→Latin1 corruption; update every branch
(qCDebug, qCInfo, qCWarning, qCCritical and the fallback warning) to stream the
QString instead of qUtf8Printable, leaving the existing diagnostic
text/formatting intact.

---

Duplicate comments:
In `@Plan/architecture_review.md`:
- Around line 45-48: The text currently contradicts Section 1.3 by saying comms
timing/stats should be moved into GraphDataModel; change the wording to clearly
state that timing/stats must be extracted out of GraphDataModel (which remains a
QAbstractTableModel for the table view) into CommunicationStats or a dedicated
value struct, owned by CommunicationStats, and that updates are signalled to
consumers; reference GraphDataModel, CommunicationStats and QAbstractTableModel
in the revised sentence so readers know which component retains the table
responsibilities and which owns the timing/stats.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b5f7bf33-beb7-4524-bfae-4537429d3970

📥 Commits

Reviewing files that changed from the base of the PR and between 6ac02f7 and 5534482.

⛔ Files ignored due to path filters (2)
  • adapters/dummymodbusadapter.exe is excluded by !**/*.exe
  • adapters/modbusadapter.exe is excluded by !**/*.exe
📒 Files selected for processing (14)
  • .claude/agents/build.md
  • .claude/agents/test-runner.md
  • Plan/architecture_review.md
  • adapters/describe.json
  • adapters/dummymodbusadapter
  • adapters/json-rpc-spec.md
  • adapters/modbusadapter
  • src/ProtocolAdapter/adaptermanager.cpp
  • src/communication/modbuspoll.cpp
  • src/datahandling/expressionparser.cpp
  • src/datahandling/graphdatahandler.cpp
  • src/importexport/presetparser.cpp
  • src/mainapp.cpp
  • src/models/settingsmodel.cpp
✅ Files skipped from review due to trivial changes (4)
  • .claude/agents/build.md
  • .claude/agents/test-runner.md
  • src/datahandling/expressionparser.cpp
  • src/mainapp.cpp
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/models/settingsmodel.cpp
  • src/datahandling/graphdatahandler.cpp
  • adapters/describe.json
  • src/communication/modbuspoll.cpp
  • adapters/json-rpc-spec.md

@jgeudens jgeudens merged commit 8d8ff3d into master Apr 23, 2026
10 checks passed
@jgeudens jgeudens deleted the dev/diagnostics branch April 23, 2026 19:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant