Skip to content

eds: Support custom_options for unknown EDS fields#653

Open
bizfsc wants to merge 1 commit intocanopen-python:masterfrom
bizfsc:feat/custom-options-eds
Open

eds: Support custom_options for unknown EDS fields#653
bizfsc wants to merge 1 commit intocanopen-python:masterfrom
bizfsc:feat/custom-options-eds

Conversation

@bizfsc
Copy link
Copy Markdown
Collaborator

@bizfsc bizfsc commented May 4, 2026

Supersedes #615.

When importing an EDS/DCF file, any key that is not part of the CiA 306 standard field set is now collected into a custom_options dict on the object. This allows applications to round-trip vendor-specific metadata without losing it.

Changes

  • ODVariable, ODRecord and ODArray gain a custom_options: dict attribute (default {}).
  • New _STANDARD_OPTIONS set in eds.py lists all keys that are parsed explicitly (including ObjFlags and Denotation which are handled by a separate PR).
  • New _get_custom_options(eds, section) helper collects every key that is not in _STANDARD_OPTIONS.
  • custom_options is populated for top-level VAR/DOMAIN, ARRAY and RECORD objects as well as for sub-variables via build_variable().
  • export_variable() and export_record() write custom_options back to the EDS file, preserving all unknown fields through a round-trip.
  • Imports aligned with the master style (from canopen.objectdictionary import …, objectcodes).
  • Local DOMAIN/VAR/ARR/RECORD constants removed; replaced with objectcodes.DOMAIN/VAR/ARRAY/RECORD.

Tests

  • test_reading_custom_options — VAR with Category=Motor, Offset=100
  • test_custom_options_standard_keys_excluded — standard keys absent from custom_options
  • test_custom_options_empty_for_standard_object — heartbeat time has {}
  • test_custom_options_record — RECORD-level custom_options
  • test_roundtrip_custom_options — full EDS export/import cycle preserves values
  • test_roundtrip_custom_options_not_duplicated_as_standard — standard keys stay out after round-trip

When importing an EDS/DCF file, any key that is not part of the CiA 306
standard field set is now collected into a custom_options dict on the object.
This allows applications to round-trip vendor-specific metadata without
losing it.

Co-authored-by: FedericoSpada <FedericoSpada@users.noreply.github.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented May 4, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds support for round-tripping vendor-specific (non-CiA-306) EDS/DCF keys by collecting them into a new custom_options dict on object dictionary objects and exporting them back out.

Changes:

  • Introduces custom_options on ODVariable, ODRecord, and ODArray to store unknown EDS keys.
  • Updates EDS import/export to populate and persist custom_options using a _STANDARD_OPTIONS allowlist and _get_custom_options() helper.
  • Adds tests and sample EDS entries covering read + export/import round-trip behavior.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
canopen/objectdictionary/eds.py Collects unknown keys into custom_options during import and writes them back during export.
canopen/objectdictionary/__init__.py Adds custom_options attribute to OD object types.
test/test_eds.py Adds unit tests for reading and round-tripping custom_options.
test/sample.eds Adds sample objects containing vendor-specific keys to validate behavior.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


if object_type in (objectcodes.VAR, objectcodes.DOMAIN):
var = build_variable(eds, section, node_id, index)
var.custom_options = _get_custom_options(eds, section)
"ParameterValue", "Factor", "Description", "Unit",
"StorageLocation", "CompactSubObj",
# CiA 306 fields parsed explicitly:
"SubNumber", "ObjFlags", "Denotation",
Comment on lines +429 to +431
for option, value in var.custom_options.items():
eds.set(section, option, value)

Comment on lines 437 to +439
eds.set(section, "ObjectType", f"0x{ot:X}")
for option, value in var.custom_options.items():
eds.set(section, option, value)
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.

2 participants