feat: EtherCAT ESI support (merge development sync) - #730
Closed
marconetsf wants to merge 22 commits into
Closed
Conversation
Port EtherCAT type definitions and PLC schema extensions. Move all EtherCAT business logic to src/backend/shared/ethercat/ as the single source of truth for both Electron and web backends. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add EtherCAT runtime discovery methods to RuntimePort (scan, test, validate, status, interfaces). Create EsiPort interface for ESI repository operations (load, parse, save, delete, migrate). Wire EsiPort into PlatformPorts. Add hasEthercat capability flag and useEsi() convenience hook. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add updateEthercatConfig action to project slice. Include EtherCAT channel mappings in IEC address collection to prevent conflicts with Modbus. Extend remote device IO point selector to collect EtherCAT channel aliases. Port use-device-configuration hook using EsiPort instead of window.bridge for on-demand device loading. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Port 21 EtherCAT editor components from src/renderer/ to src/frontend/. Replace all window.bridge calls with useRuntime() and useEsi() hooks. Update import paths for shared backend utils and frontend assets. Route EtherCAT protocol to dedicated EtherCATEditor in workspace screen. Enable EtherCAT option in create-element card. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Import generateEthercatConfig from shared backend and wire it into the Runtime v4 compilation pipeline. Generates conf/ethercat.json alongside existing Modbus, S7Comm, and OPC-UA configs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove VPP-specific imports, methods, and compilation export that leaked into the EtherCAT branch during cherry-pick conflict resolution. Fix corrupted escaped quotes in renderer.ts line 1. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Port feat/ethercat-task-selection changes to the refactored architecture: - Add isSystemTask/associatedDevice fields to PLCTask schema - Add enabled field to EtherCATMasterConfig schema - Create ethercat-task-helpers in shared backend (task naming, cycle time conversion) - Auto-create/delete/rename system tasks when EtherCAT devices are managed in the project slice - Sync cycle time changes to system task interval - Preserve system tasks during task list updates - Prevent editing/deleting/reordering system tasks in task table and task editor UI - Add task_name and enabled filter to EtherCAT config generator - Add Enable Plugin toggle to global settings tab Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace direct openPLCStoreBase import in editor-platform.ts with a setProjectPath() setter pattern matching the existing setRuntimeIpAddress approach. The store import was causing a circular dependency that resulted in a blank screen on startup. App.tsx now syncs the project path to the platform adapter via useEffect. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Port all additional work from feat/ethercat-task-selection including: - Restructured EtherCAT editor with tab layout (Network, Devices, Repository, Diagnostics, Advanced) - New EtherCATDeviceEditor for individual slave device editing - Side-by-side scan/configured tables with device tree navigation - Offline device management and improved network interface handling - Standardized device names and hex formatting - plc-ethercat-device editor model and tab type for slave devices - ethercatDeviceActions in shared slice (delete/rename slaves) - Enable plugin filter in config generator - Default task priority changed from 0 to 1 - Error propagation fix in IPC POST request handler Note: ProjectTreeExpandableLeaf (device tree in explorer) deferred to follow-up due to type system differences between architectures. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add expandable leaf component to project tree that supports hierarchical navigation — EtherCAT buses expand to show their configured slave devices as child leaves. Each slave device leaf supports rename, delete, and opens the dedicated EtherCATDeviceEditor. Changes: - Add ProjectTreeExpandableLeaf component with collapse/expand, rename, delete, and context menu support - Add ethercatDevice leafLang and LeafSources entry - Add busName/deviceId props to ProjectTreeLeaf for ethercat slaves - Add ethercat device rename/delete handling in ProjectTreeLeaf - Update explorer to render EtherCAT buses as expandable leaves with slave devices as children Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Ports the 6 unpushed commits from feat/ethercat-task-selection: - d784f3e3 refactor: replace colored IN/OUT badges with plain text in channel tables - 969ecd8f refactor: update channel filter buttons to match console tab style - 98e870ec feat: add task priority setting to EtherCAT advanced config - 4213c4d3 fix: prevent duplicating system task properties when creating new tasks (also applied to the ROWS_NOT_SELECTED path, which copies from task in this branch) - 5a635e33 feat: sort tasks by priority in ST/XML generation and rename tab to Bus - a1df55a1 feat: add breadcrumb trails for remote devices, servers, and EtherCAT slaves Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The breadcrumb above already shows the bus and device context, making the "<name> — Position N — Bus: <bus>" subtitle redundant. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The tab for EtherCAT slave devices (type 'ethercat-device') was falling through to the default ILIcon because the TabIcons map and the languageOrDerivation union had no case for it. Add the mapping so the tab matches the blue DeviceTransferIcon already shown in the project tree. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The button was rendered conditionally in the tab body, so appearing/ disappearing caused the tables below to shift vertically. Place it in the right slot of the existing Scanned Devices header (symmetric with the +/- actions on Configured Devices) and keep it always visible, disabled when nothing is selected. Layout is now stable. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adding an EtherCAT slave (via scan or repository) was leaving channelMappings as an empty array. The compiler reads that field to assign IEC locations (%QX0.0, %IX0.0, ...) when generating the runtime config; without entries, every channel was emitted with an empty iec_location, so outputs never bound to PLC variables and the slave appeared inert until the user opened its editor page (where a useEffect in use-device-configuration was lazily filling the mappings). Move the population to the add path: - enrichDeviceData(device, usedAddresses?) now also returns channelMappings, generated via generateDefaultChannelMappings against the project-wide set of already-used IEC addresses. - New util collectUsedIecAddresses gathers IEC locations from every remote device's Modbus I/O points and EtherCAT channel mappings. ethercat-device-editor.tsx and the add handlers both consume it. - handleAddSelectedFromScan accumulates freshly assigned addresses between iterations so devices added in the same batch don't collide. The lazy-init in use-device-configuration is left in place as a fallback for projects saved before this fix. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
# Conflicts: # src/backend/editor/compiler/compiler-module.ts # src/main/modules/ipc/main.ts # src/main/modules/ipc/renderer.ts # src/types/PLC/units/task.ts
Slave tabs (elementType.type === 'ethercat-device') were never
registered in the files store, so closeFile's getSavedState lookup
defaulted to false and triggered the "Unsaved changes — save?" modal on
every close, even when nothing had been edited. Worse, clicking "Save"
in that modal called executeSaveFile, which also failed on the missing
files entry, so the tab refused to close ("Don't Save" worked because
its handler bypassed the result).
Treat ethercat-device tabs as views over the parent remote device's
data: they own no file and have no per-tab dirty state. Short-circuit
closeFile to forceCloseFile for that tab type. Real edits to slave
config still dirty the parent bus tab via syncDevicesToStore, so the
project-level save flow is unaffected.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Upstream commit 1554301 moved the shared PLC type schemas from src/types/PLC/ to src/backend/shared/types/PLC/ (and deleted src/types/PLC/runtime-logs.ts in favor of the existing definition in middleware/shared/ports/types.ts) but did not update every importer. Eight files were left referencing the old paths, breaking tsc with 13 "Cannot find module" / cascading implicit-any errors. Repoint each importer to the new location: - @root/types/PLC/devices -> @root/backend/shared/types/PLC/devices - @root/types/PLC/open-plc -> @root/backend/shared/types/PLC/open-plc - @root/types/PLC/runtime-logs -> @root/middleware/shared/ports Also re-sorts adjacent imports in the touched files via eslint --fix to satisfy simple-import-sort. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…support-v2 # Conflicts: # package-lock.json # package.json # src/frontend/screens/workspace-screen.tsx # src/middleware/editor-platform.ts
Contributor
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Moves the canonical ESI type definitions from src/types/ethercat/ to src/middleware/shared/ports/esi-types.ts so ports can import them without violating the architecture layer rule (ports -> [utils, ports]). The original file at src/types/ethercat/esi-types.ts becomes a re-export barrel so the 30+ existing consumers continue working without import changes. Also fixes Prettier formatting on 6 EtherCAT files flagged by CI. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Resolves architecture validation failures by ensuring ESI types live exclusively in src/middleware/shared/ports/esi-types.ts (the ports layer) and all 30 consumers import from there directly. The previous approach (re-export barrel in types/ethercat/) violated two architecture rules simultaneously: ports->types and types->ports were both forbidden. This commit eliminates the barrel entirely — types/ethercat/index.ts no longer re-exports ESI types, and all imports now use @root/middleware/shared/ports/esi-types. Also runs lint:fix to resolve import sorting issues in synced files. Co-authored-by: Claude Opus 4.6 (1M context) <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
Brings the
feat/ethercat-support-v2branch up to date with development, incorporating the latest CI sync workflow and documentation updates. The EtherCAT ESI feature (editor adapter, ESI UI components, parser, IPC handlers) was already implemented in prior commits on this branch.This PR represents the desktop editor side of the EtherCAT ESI feature. The backend and web adapter are delivered in companion PRs.
What this branch contains (EtherCAT ESI feature)
Desktop editor adapter
src/middleware/adapters/editor/esi-adapter.ts— implements EsiPort via Electron IPC, injecting project path from callbackmain.ts/renderer.tsfor ESI operationsESI Service (main process)
src/backend/editor/ethercat/esi-service.ts— persistence layer managingdevices/esi/directory within projectsShared backend (parser + channel utilities)
src/backend/shared/ethercat/esi-parser-main.ts—parseESILight+parseESIDeviceFullusing fast-xml-parsersrc/backend/shared/ethercat/esi-parser.ts— PDO-to-channel conversion, IEC address generation, default mapping generationESI UI Components
esi-upload.tsx— drag-and-drop upload with progress, 100 MB limitesi-repository.tsx/esi-repository-table.tsx— library managementesi-channels-table.tsx— channel-to-variable mappingesi-device-info.tsx— device detail panelrepository-tab.tsx— tab orchestrating the abovechannel-mapping-table.tsx,configured-devices.tsx,advanced-tab.tsx— device configurationPort contract
src/middleware/shared/ports/esi-port.ts— 6 methods (loadRepositoryLight, migrateRepository, parseAndSaveFile, deleteRepositoryItem, clearRepository, loadDeviceFull)src/types/ethercat/esi-types.ts— 627 lines of ESI domain typesMerge with development
Latest merge incorporates CI sync workflow (
ci-sync.yml), updated documentation (CLAUDE.md), and new comparison scripts for cross-repo surface validation.Companion PRs
Test plan
npm run dev— application starts and ESI tab worksnpm test— unit tests passnpm run validate:arch) passes🤖 Generated with Claude Code