Files
DCU_DesktopController/js/motor/transport.js
T
cbb 2d1743ca4f feat(motor): 支持 WiFi 与 EtherCAT 双链路传输
- 抽象电机传输层,WiFi 与 EtherCAT 实现分离,解码、状态面板、波形和命令序列共用
- 新增 EtherCAT 后端反向代理与自动拉起,解决跨端口 CORS 与预检失败问题
- 刷新速度按链路独立存储,支持 EtherCAT 低延迟读取与 WiFi 稳定轮询
- 更新电机页链路选择、不支持页签置灰样式、README 说明及相关测试脚本
2026-09-04 12:18:06 +08:00

58 lines
2.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* transport.js — 电机控制台的传输选择层
*
* 电机页支持两条链路,业务逻辑(解码、节点列表、STATUS 面板、波形、命令序列、
* 流控)**完全共用**,只有"数据怎么进出"这一层不同:
*
* wifi ESP32 固件 80 端口的 HTTP API(原有实现,行为未变)
* ecat EtherCAT 过程数据,经本地页面服务器 /ecat/api/* 代理到
* tools/ecat/src/ecat_server.py
*
* 传输实例必须实现的接口(详见两个实现文件的注释):
* id / label / supportsOta / supportsPeriodSync
* sendHint(ch) -> string
* probe() -> statusData 连接探测,抛错=没连上
* fetchStatus(wantFull) -> statusData 健康检查
* describeStatus(data) -> string[] #devStatus 文本片段
* reportedIp(data) -> string|null 设备回报 IP(ECAT 恒 null)
* fetchMotorState() -> {have_data, age_ms, active_count, boot_active, motors[]}
* fetchFeedback() -> {channels:[{ch,enabled,valid,rx,tx,err,tec,rec,bus_state}]}
* sendFrames(frames, {ch}) -> results[] frames=[{id,dlc,data}]
* sendBurst(frames, {suffix,dlc}) -> results[]
* fetchVersionNode(node) -> {node,seq,version}|null
* setPeriod(ms) -> void 不支持则空实现
* teardown() -> void 切走时收尾
* 可选:takeNodeIdReport(node)、debug()
*
* motors[] 每项的字段契约(ECAT 实现负责补平差异):
* {node, ch, online, dlc, rx_count, seq, data(64hex), config_data(48hex|"")}
*/
"use strict";
import { createWifiTransport } from "./transport-wifi.js";
import { createEcatTransport } from "./transport-ecat.js";
/** localStorage key:记住上次选的传输,刷新页面后保持 */
export const LS_TRANSPORT = "dcu_motor_transport";
export const TRANSPORT_IDS = ["wifi", "ecat"];
/** @description 按 id 创建传输实例。未知 id 回退到 wifi。 */
export function createTransport(id, ctx) {
return (id === "ecat") ? createEcatTransport(ctx) : createWifiTransport(ctx);
}
/** @description 读上次选择的传输 id(默认 wifi —— 不改变老用户的既有行为)。 */
export function loadTransportId() {
try {
const v = localStorage.getItem(LS_TRANSPORT);
if (v && TRANSPORT_IDS.includes(v)) return v;
} catch (_) {}
return "wifi";
}
/** @description 保存传输选择。 */
export function saveTransportId(id) {
try { localStorage.setItem(LS_TRANSPORT, id); } catch (_) {}
}