Skip to content

v1.13.9 - DeviceResponse::from_command() Implementation (2025-12-10)

What Changed?

This release completes the command-response refactor specification. The DeviceResponse::from_command() method now enables Layer 2 data conversion in the 3-layer architecture, converting handler results (command_response_t) to transport format (device_response_t). This completes the type conversion layer and resolves circular dependency issues between device_response.h and command_queue.h through architectural improvements.


What's New

Main Feature: Layer 2 Type Conversion (DeviceResponse::from_command())

What it does: Implements the middle layer of the 3-layer command-response architecture. This layer takes typed handler results (command_response_t) and converts them to transport format (device_response_t) for serialization. The conversion is deterministic and has no side effects, enabling clean separation of concerns between business logic (Layer 1), type conversion (Layer 2), and JSON serialization (Layer 3).

How to use it: This is an internal architectural improvement. Handlers continue to populate command_response_t with typed fields. The dispatcher automatically calls DeviceResponse::from_command() to convert results before serialization.

Code example:

// Layer 1: Handler populates typed response
command_response_t result = handle_version(cmd);
result.version = "v1.14.0";
result.status = DEVICE_STATUS_OK;
result.sent_at = device_get_timestamp();

// Layer 2: Convert to transport format (automatic in dispatcher)
device_response_t response = DeviceResponse::from_command(result);

// Layer 3: Serialize to JSON (handled by DeviceResponse::send())
DeviceResponse::send(response);

Installation

Quick Start

# Get the release
git checkout v1.13.9

# Build
task build

# Upload
task upload

# Check it works
task monitor

What's Different from the Last Version?

✅ Added

  • DeviceResponse::from_command() method for Layer 2 type conversion
  • device_response_types.h header file extracting enum types to resolve circular dependencies
  • Semantic error codes in all command handlers (DEVICE_CODE_INVALID_ARG, DEVICE_CODE_OUT_OF_RANGE, etc.)
  • Standardized error response patterns across 13+ handler files

🔧 Changed

  • Circular dependency resolution: Moved enum type definitions to separate header (device_response_types.h)
  • Handler signatures: All handlers now use success_response() with no arguments
  • Payload field assignment: Handlers now assign typed fields directly (e.g., response.poll_count = count)
  • Error codes: Replaced integer literals with semantic enum values for type safety
  • device_response.h: Reordered includes to include command_queue.h after type definitions

🐛 Fixed

  • Circular include issue: device_response.h ↔ command_queue.h dependency resolved
  • Incomplete type errors: command_response_t now fully defined before DeviceResponse class methods use it
  • Linker errors: standardized all handler function signatures to match inline helpers

Is It Safe to Upgrade?

Backward Compatible: Yes

  • Phase 4 changes are internal architectural improvements only
  • ENABLE_DEVICE_RESPONSE=0 (default) is unaffected - uses legacy system
  • ENABLE_DEVICE_RESPONSE=1 (opt-in) now has proper circular dependency resolution
  • All handler changes maintain identical response format
  • No changes to serial protocol or device behavior
  • Zero impact on production builds (legacy code path unchanged)

Tests Passed

  • ✅ Builds without compilation errors (0 errors, 0 warnings)
  • ✅ Builds without linker errors (all symbols resolved)
  • ✅ RAM usage: 30.0% (98256 / 327680 bytes)
  • ✅ Flash usage: 24.5% (321377 / 1310720 bytes)
  • ✅ Circular dependency resolved (device_response.h ↔ command_queue.h)
  • ✅ All 13+ handler files standardized and verified

Release Details

  • Date: 2025-12-10
  • Version: v1.13.9
  • Files Changed: 14
  • New: include/device_response_types.h
  • Modified: include/device_response.h, include/command_queue.h, src/device_response.cpp
  • Modified handlers: src/command/{deadtime,gnss,mac_address,poll_count,reset,rtc,stream,wifi}.cpp
  • Commit: Phase 4 (US2) DeviceResponse::from_command() implementation
  • Specification: Phase 0.5 command-response-refactor (T022 - Layer 2 conversion)

Next Steps

Phase 5 (US3): DeviceResponse::send() Serialization Layer

Upcoming work (v1.13.10+):

  • Implement DeviceResponse::send() method using ArduinoJson v7.1.0
  • Convert device_response_t to JSON Lines format (JSONL)
  • Add payload field serialization (version, uptime_ms, mac_address, poll_count, etc.)
  • Proper feature flag handling (ENABLE_RTC, ENABLE_GNSS, ENABLE_BME280)
  • Serial output with newline termination

Phase 6 (US4): Reference Handler Implementation

  • Complete handlers with full payload field serialization
  • GET_VERSION: version field
  • GET_STATUS: uptime_ms, mac_address, poll_count, deadtime_ms
  • GET_THRESHOLD: channel, threshold values
  • Optional handlers: GNSS, WiFi, RTC features

Phase 7: Polish & Documentation

  • Integration testing with actual hardware
  • Protocol validation against JSON schemas
  • Release notes and API documentation updates
  • Performance profiling and optimization