+
ADAM-4017+ 模拟量(地址 2)
-
+
Vin{{ i }} {{ ANALOG_INFO[key].label }} {{ board?.analog[key] ?? '-' }}
@@ -326,19 +449,32 @@ const cameraTitle = computed(() =>
-
+
ADAM-4150 数字量(地址 1)
- DI{{ i }} {{ input.label }}
+
+ DI{{ i }} {{ input.label }}
+
- DO{{ i }} {{ label }}
+
+ DO{{ i }} {{ label }}
+
串口服务器
-
COM2 → 4017COM3 → 4150COM4 → ZigBee 协调器COM5 → LED 屏
+
+
+ {{ port }} → {{ portDevices(port) }}
+
+
@@ -860,6 +996,42 @@ button {
color: var(--muted);
}
+.port-warning {
+ color: #ff8a80;
+}
+
+.port-warnings {
+ padding: 4px 8px;
+ background: #4a2f35;
+ border-radius: 4px;
+}
+
+/* 接线:鼠标所在设备接的模块、通道和串口 */
+.wiring-path {
+ flex: 1;
+ min-width: 0;
+ margin: 0 12px;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ color: #6c7889;
+}
+
+.wiring-path.active {
+ color: #9fd3ff;
+}
+
+.module.linked {
+ box-shadow: inset 0 0 0 1px var(--accent);
+}
+
+.readings .linked,
+.io.linked {
+ color: #9fd3ff;
+ text-decoration: underline;
+ text-underline-offset: 3px;
+}
+
.link {
padding: 0;
background: none;
diff --git a/web/src/scene/wiring.ts b/web/src/scene/wiring.ts
new file mode 100644
index 0000000..24ae70b
--- /dev/null
+++ b/web/src/scene/wiring.ts
@@ -0,0 +1,21 @@
+// 实训台接线在网页上的显示:串口服务器上每个口接了哪些设备。
+// 串口下拉框展开时也用灰字标出来:运行区 provide,ControlView inject;设计器里没有实训台,用默认接线。
+import type { InjectionKey, Ref } from 'vue'
+import { BOARD_PORTS, DEFAULT_WIRING, PORT_DEVICE_NAMES, PORT_DEVICES, type PortDevice, type Wiring } from '@iot/shared'
+
+/** 接在这个串口上的设备(项目 7 的 COM2 上并着 4017+ 和 4150) */
+export function devicesOn(wiring: Wiring, port: string): PortDevice[] {
+ return PORT_DEVICES.filter((device) => wiring[device] === port)
+}
+
+/** 串口 → 设备名,如 { COM2: 'ADAM-4017+、ADAM-4150' };没接设备的口不列出 */
+export function portLabels(wiring: Wiring = DEFAULT_WIRING): Record
{
+ const labels: Record = {}
+ for (const port of BOARD_PORTS) {
+ const names = devicesOn(wiring, port).map((device) => PORT_DEVICE_NAMES[device])
+ if (names.length) labels[port] = names.join('、')
+ }
+ return labels
+}
+
+export const PORT_LABELS: InjectionKey[>> = Symbol('portLabels')
diff --git a/web/src/winforms/ControlView.vue b/web/src/winforms/ControlView.vue
index 70de8d0..c0ec9f4 100644
--- a/web/src/winforms/ControlView.vue
+++ b/web/src/winforms/ControlView.vue
@@ -10,6 +10,7 @@ import DataGridViewControl from './DataGridViewControl.vue'
import DateTimePickerControl from './DateTimePickerControl.vue'
import LedControl from './LedControl.vue'
import TrackBarControl from './TrackBarControl.vue'
+import { PORT_LABELS, portLabels } from '../scene/wiring'
const props = defineProps<{
node: ControlNode
@@ -61,8 +62,8 @@ const items = computed(() => (p.value.Items as string[] | undefined) ?? [])
const editable = computed(() => p.value.DropDownStyle !== 'DropDownList')
const combo = ref()
const listStyle = ref({})
-/** 串口列表里每个口后面用灰字标出实训台上接的设备,只是提示,下拉框的值还是 COM2 这样的串口名 */
-const portDevices: Record = { COM2: 'ADAM-4017+', COM3: 'ADAM-4150', COM4: 'ZigBee 协调器', COM5: 'LED 屏' }
+/** 串口列表里每个口后面用灰字标出实训台上接的设备(按当前实验的接线),只是提示,下拉框的值还是 COM2 这样的串口名 */
+const portDevices = inject(PORT_LABELS, ref(portLabels()))
function openDropDown() {
if (!enabled.value) return
]