Repository navigation
Conversation
Real-world Device Descriptor Object Pools collected from issues and bench captures, sorted by implement type under tools/testdata/implements, with a manifest.csv index and a README. Serial numbers and NAME identity bits are zeroed. Taken unchanged from the integration build, so tests can run section control detection against real pools without the machines. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Mueller MIDI 3 sprayer (SPR_MIDI_3 V07.10.05.33) presents section control in four ways, chosen by two configuration bits: old or new SC DDIs, condensed work state on or off. Only one of them has been captured. The other three were derived from that capture with the firmware's own DDOP rules (from reverse engineering): it sends every template object and only filters the element child lists, and old SC mode relabels DDI 289 to 141 and 290+ to 161+ as settable. The same rules rebuild the real capture byte for byte. The files are named *_synthetic.ddop and marked as never seen on the wire in the manifest and README. Replace them once real captures exist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Move the section control method detection and the DDI to element mapping out of activate_object_pool(), request_measurement_commands() and send_section_setpoint_states() into resolve_section_control(), which takes the DDOP and returns the method and where to write it. The client keeps the result as its SectionControlPlan. What changes: - Only process data that a device element links counts. Some implements (Mueller MIDI 3) send every template object and leave the unused ones unreferenced, so a pool can declare DDI 290 or a settable DDI 161 that no element owns. - "Settable" is checked on the linked object for that element, not on the first object in the pool with that DDI. This replaces is_ddi_settable(). - New per-element method: DDI 289 on each section element, actual state on DDI 141 of the same element. Settable DDI 141 stays as the fallback. - The global Setpoint Work State (DDI 289) is only taken from an element that is not a section, so per-element pools no longer get it on their last section. - "DDI 289 (SetpointWorkState) not available" is logged once at activation instead of on every setpoint send. - Device element children are read by index: iterating get_child_object_ids() reads past the end of the list (AgIsoStack DataSpan bug, #110) and mapped DDIs to random elements on the MIDI 3 capture. Order of preference: DDI 290 > settable DDI 161 > per-element DDI 289 > per-element settable DDI 141, matching the fallback rules of the ISO 11783-11 DDI 289/290 attachment. The new test_section_control target resolves every DDOP in tools/testdata/implements and checks the section_control column of manifest.csv, plus the exact targets of the four MIDI 3 pools. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Section control detection now looks only at process data that a device element actually links. The method and its targets are resolved once, when the implement activates, by a pure function,
resolve_section_control(). A new test runs that function against every sample DDOP.Draft for review. Some of these paths have only synthetic evidence (see Evidence below), so part of the discussion is whether to keep them.
Commits
manifest.csvand README from the integration build, unchanged. They aren't ondevelopyet.*_synthetic.ddopfiles, derived from the real MIDI 3 capture by the firmware's own DDOP rules (from reverse engineering). The same rules rebuild the real capture byte for byte. The manifest and README mark them as never seen on the wire.What changes in the TC
is_ddi_settable()is removed.get_child_object_ids()reads past the end of the list (Bump AgIsoStack to pick up the DataSpan fix (wrong DDI-to-element mapping) #110).Order of preference: DDI 290 > settable DDI 161 > per-element DDI 289 > per-element settable DDI 141. This follows the fallback rules in the ISO 11783-11 attachment for DDI 289/290: a TC "shall be able to fall back to using the Actual Work State DDIs" when the implement marks them settable.
Evidence
If the synthetic-only paths aren't wanted, the per-element DDI 289 method is the easiest to drop: one branch in the resolver and one manifest row.
Test results
ctest: 6 of 7 pass.section_control_methodstill fails on 4 manifest rows, to be decided before merge. The Kuhn EsproDDI141files (en and hu) and the JD 6000M and 6R175 tractors are listed asDDI141, but their DDI 141 is not settable. Today's TC and this branch both picknonefor them (issue #10: "SC switch is not working"). The proposal is to change those rows tonone; no code change is needed.Notes for reviewers
send_section_setpoint_states().request_measurement_commands()still iterate the broken span; Bump AgIsoStack to pick up the DataSpan fix (wrong DDI-to-element mapping) #110 fixes those.test_section_control, so cmake-format and cmake-lint agree on the wrapping.Not tested
🤖 Generated with Claude Code