agentworkshop 0.7.40 → 0.7.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/_nuxt/{CzOCSGLe.js → BN16aRdQ.js} +1 -1
  3. package/.output/public/_nuxt/BWVhZntO.js +1 -0
  4. package/.output/public/_nuxt/{Dihnimlk.js → C0ZrS1KL.js} +1 -1
  5. package/.output/public/_nuxt/{Dr9v6C0f.js → C4s_niy-.js} +2 -2
  6. package/.output/public/_nuxt/D6mbFA-a.js +1 -0
  7. package/.output/public/_nuxt/{DcsCcxp4.js → D98NH8kG.js} +1 -1
  8. package/.output/public/_nuxt/{C_iYD-EB.js → DGbd-UiG.js} +1 -1
  9. package/.output/public/_nuxt/{DCn7QZ5N.js → Dap5PmTL.js} +1 -1
  10. package/.output/public/_nuxt/DvLxILQP.js +1 -0
  11. package/.output/public/_nuxt/{DZshyNLa.js → IREZ1eC2.js} +1 -1
  12. package/.output/public/_nuxt/_id_.D9ymtHB5.css +1 -0
  13. package/.output/public/_nuxt/_id_.jf-_8E_c.css +1 -0
  14. package/.output/public/_nuxt/builds/latest.json +1 -1
  15. package/.output/public/_nuxt/builds/meta/78a295bb-2072-48a4-8b46-6d545fdae743.json +1 -0
  16. package/.output/public/_nuxt/ca4TJ3Op.js +1 -0
  17. package/.output/public/_nuxt/daq.DjSgY94l.css +1 -0
  18. package/.output/public/_nuxt/{BP-NyKVG.js → eqq3wWQF.js} +1 -1
  19. package/.output/server/chunks/_/nitro.mjs +886 -673
  20. package/.output/server/chunks/_/nitro.mjs.map +1 -1
  21. package/.output/server/chunks/build/{TownView-BuLAsmpR.mjs → TownView--otsnr_7.mjs} +4 -4
  22. package/.output/server/chunks/build/{TownView-BuLAsmpR.mjs.map → TownView--otsnr_7.mjs.map} +1 -1
  23. package/.output/server/chunks/build/{_id_-BU1wfOID.mjs → _id_-Brv-JSvr.mjs} +141 -140
  24. package/.output/server/chunks/build/_id_-Brv-JSvr.mjs.map +1 -0
  25. package/.output/server/chunks/build/{_id_-BYsEua57.mjs → _id_-D9pl1OZy.mjs} +37 -36
  26. package/.output/server/chunks/build/_id_-D9pl1OZy.mjs.map +1 -0
  27. package/.output/server/chunks/build/{_wsId_-BxlDcJHg.mjs → _wsId_-BASfDf0s.mjs} +4 -4
  28. package/.output/server/chunks/build/{_wsId_-BxlDcJHg.mjs.map → _wsId_-BASfDf0s.mjs.map} +1 -1
  29. package/.output/server/chunks/build/{daq-cgyjKmJu.mjs → daq-DkMvD8sg.mjs} +93 -92
  30. package/.output/server/chunks/build/daq-DkMvD8sg.mjs.map +1 -0
  31. package/.output/server/chunks/build/{dcw-CoTxBlAZ.mjs → dcw-C1jgVJkO.mjs} +3 -3
  32. package/.output/server/chunks/build/{dcw-CoTxBlAZ.mjs.map → dcw-C1jgVJkO.mjs.map} +1 -1
  33. package/.output/server/chunks/build/{logs-BSOeZwwI.mjs → logs--dByNyhw.mjs} +2 -2
  34. package/.output/server/chunks/build/{logs-BSOeZwwI.mjs.map → logs--dByNyhw.mjs.map} +1 -1
  35. package/.output/server/chunks/build/{pages-DFxjn9Xa.mjs → pages-B0bUWnC6.mjs} +3 -3
  36. package/.output/server/chunks/build/{pages-DFxjn9Xa.mjs.map → pages-B0bUWnC6.mjs.map} +1 -1
  37. package/.output/server/chunks/build/{town-qMPql9Se.mjs → town-CoQdblbZ.mjs} +4 -4
  38. package/.output/server/chunks/build/{town-qMPql9Se.mjs.map → town-CoQdblbZ.mjs.map} +1 -1
  39. package/.output/server/chunks/build/{useDaqStream-CIBaiGAl.mjs → useDaqStream-DfCFpb3p.mjs} +9 -3
  40. package/.output/server/chunks/build/useDaqStream-DfCFpb3p.mjs.map +1 -0
  41. package/.output/server/chunks/build/{useDcwStream-CBbiYnWe.mjs → useDcwStream-UPiX-3iO.mjs} +11 -2
  42. package/.output/server/chunks/build/useDcwStream-UPiX-3iO.mjs.map +1 -0
  43. package/.output/server/chunks/routes/api/workshop/channel-templates/_id/instantiate.post.mjs +1 -1
  44. package/.output/server/chunks/routes/api/workshop/channels.post.mjs +3 -3
  45. package/.output/server/chunks/routes/api/workshop/dcw/index5.post.mjs +1 -1
  46. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/start.post.mjs +1 -1
  47. package/.output/server/chunks/routes/api/workshop/dcw/lines/_id/stop.post.mjs +1 -1
  48. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.delete.mjs +1 -1
  49. package/.output/server/chunks/routes/api/workshop/dcw/params/_id_.patch.mjs +1 -1
  50. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.delete.mjs +1 -1
  51. package/.output/server/chunks/routes/api/workshop/dcw/templates/_key_.patch.mjs +1 -1
  52. package/.output/server/chunks/routes/api/workshop/harnesses/_id/providers.get.mjs +1 -1
  53. package/.output/server/chunks/routes/api/workshop/harnesses.get.mjs +1 -1
  54. package/.output/server/chunks/routes/api/workshop/hitl/pending.get.mjs +1 -1
  55. package/.output/server/chunks/routes/api/workshop/hitl/respond.post.mjs +1 -1
  56. package/.output/server/chunks/routes/api/workshop/index.put.mjs +1 -1
  57. package/.output/server/chunks/routes/api/workshop/index5.get.mjs +3 -1
  58. package/.output/server/chunks/routes/api/workshop/index5.get.mjs.map +1 -1
  59. package/.output/server/chunks/routes/api/workshop/index6.get.mjs +3 -1
  60. package/.output/server/chunks/routes/api/workshop/index6.get.mjs.map +1 -1
  61. package/.output/server/chunks/routes/api/workshop/plugins/_name/disable.post.mjs +1 -1
  62. package/.output/server/chunks/routes/api/workshop/plugins/_name/enable.post.mjs +1 -1
  63. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.delete.mjs +1 -1
  64. package/.output/server/chunks/routes/api/workshop/scene/layouts/_channelId_.put.mjs +1 -1
  65. package/.output/server/chunks/routes/api/workshop/workspaces/_id/channel-templates/_tplId_.post.mjs +1 -1
  66. package/.output/server/chunks/routes/renderer.mjs +2 -2
  67. package/.output/server/chunks/virtual/entry.mjs +9 -9
  68. package/.output/server/chunks/virtual/precomputed.mjs +1 -1
  69. package/.output/server/package.json +1 -1
  70. package/README-zh.md +5 -5
  71. package/README.md +6 -6
  72. package/app/composables/workshop/useDaqStream.ts +7 -4
  73. package/app/composables/workshop/useDcwStream.ts +8 -2
  74. package/app/pages/daq/[id].vue +9 -5
  75. package/app/pages/daq/index.vue +13 -10
  76. package/app/pages/dcw/[id].vue +8 -4
  77. package/docs/cli.en.md +2 -2
  78. package/docs/cli.md +2 -2
  79. package/docs/plugins.en.md +33 -1
  80. package/docs/plugins.md +29 -1
  81. package/docs/sdk.en.md +1 -1
  82. package/docs/sdk.md +1 -1
  83. package/package.json +3 -2
  84. package/scripts/_loop-biax-campaign.mjs +124 -0
  85. package/scripts/test-serial-bridge.mjs +418 -0
  86. package/scripts/ui/e2e-interactive.mjs +328 -0
  87. package/scripts/ui/seed-industrial-demo.mjs +171 -0
  88. package/server/api/workshop/daq/index.get.ts +3 -1
  89. package/server/api/workshop/dcw/index.get.ts +3 -0
  90. package/server/plugins/aw-plugins.ts +9 -7
  91. package/server/plugins-builtin/serial-bridge/client.mjs +210 -0
  92. package/server/plugins-builtin/serial-bridge/drivers.mjs +409 -0
  93. package/server/plugins-builtin/serial-bridge/i18n.json +62 -0
  94. package/server/plugins-builtin/serial-bridge/index.mjs +247 -0
  95. package/server/plugins-builtin/serial-bridge/lib.mjs +208 -0
  96. package/server/plugins-builtin/serial-bridge/rtu.mjs +168 -0
  97. package/server/services/workshop/daq/daq-controller.ts +7 -2
  98. package/server/services/workshop/daq/drivers.ts +78 -3
  99. package/server/services/workshop/dcw/dcw-controller.ts +5 -1
  100. package/server/services/workshop/dcw/drivers.ts +85 -2
  101. package/server/services/workshop/dcw/plugin-bridge.ts +45 -0
  102. package/server/services/workshop/plugins/host.mjs +30 -0
  103. package/shared/daq-protocol.ts +15 -0
  104. package/.output/public/_nuxt/BOt2SP4z.js +0 -1
  105. package/.output/public/_nuxt/ClILjvWH.js +0 -1
  106. package/.output/public/_nuxt/D8qvkfyY.js +0 -1
  107. package/.output/public/_nuxt/Du9ZJtnj.js +0 -1
  108. package/.output/public/_nuxt/_id_.CM4bIgKY.css +0 -1
  109. package/.output/public/_nuxt/_id_.bNV69Dtf.css +0 -1
  110. package/.output/public/_nuxt/builds/meta/f4707884-7cf4-4a31-80d2-e3d72b73745f.json +0 -1
  111. package/.output/public/_nuxt/daq.B0D3dPAc.css +0 -1
  112. package/.output/server/chunks/build/_id_-BU1wfOID.mjs.map +0 -1
  113. package/.output/server/chunks/build/_id_-BYsEua57.mjs.map +0 -1
  114. package/.output/server/chunks/build/daq-cgyjKmJu.mjs.map +0 -1
  115. package/.output/server/chunks/build/useDaqStream-CIBaiGAl.mjs.map +0 -1
  116. package/.output/server/chunks/build/useDcwStream-CBbiYnWe.mjs.map +0 -1
@@ -17,7 +17,7 @@
17
17
  import { createLogger } from '../logger'
18
18
  import { createRequire } from 'node:module'
19
19
  import { encodePng } from './png-enc'
20
- import type { DaqDriverKind, DriverTestResult } from '../../../../shared/daq-protocol'
20
+ import { DAQ_DRIVERS, type DaqDriverKind, type DriverTestResult } from '../../../../shared/daq-protocol'
21
21
 
22
22
  const log = createLogger('daq.drivers')
23
23
 
@@ -1075,16 +1075,64 @@ function pluginRegistry(): Map<string, DaqDriver> {
1075
1075
  return g_plugins.__daqPluginDrivers ??= new Map()
1076
1076
  }
1077
1077
 
1078
+ /**
1079
+ * 插件驱动的自描述目录(前端「添加节点」下拉与动态参数表单的数据源)。
1080
+ * 插件驱动在 DaqDriver 上携带可选 meta(label/status/configFields,与 DaqDriverMeta 同形、
1081
+ * kind 放宽为 string);未带 meta 的插件驱动只在 meta.pluginDrivers 里以 kind 出现,
1082
+ * 前端能感知存在但不出表单(如实降级,不猜测参数 schema)。
1083
+ */
1084
+ export interface PluginDriverMeta {
1085
+ kind: string
1086
+ label: string
1087
+ status: 'builtin' | 'real' | 'planned'
1088
+ configFields?: import('../../../../shared/daq-protocol').DriverConfigField[]
1089
+ /** true = 来自插件协议插件(前端展示「插件」徽标) */
1090
+ plugin: true
1091
+ }
1092
+
1093
+ const g_metas = globalThis as typeof globalThis & { __daqPluginDriverMetas?: Map<string, PluginDriverMeta> }
1094
+ function pluginMetaRegistry(): Map<string, PluginDriverMeta> {
1095
+ return g_metas.__daqPluginDriverMetas ??= new Map()
1096
+ }
1097
+
1078
1098
  /** 插件驱动注册(kind 与内置冲突时覆盖并告警;resolveDaqDriver 插件优先) */
1079
1099
  export function registerPluginDriver(driver: DaqDriver): void {
1080
1100
  if (driver.kind in REGISTRY) log.warn(`[daq-drivers] 插件驱动覆盖内置:「${driver.kind}」`)
1081
1101
  pluginRegistry().set(driver.kind, driver)
1102
+ const meta = (driver as DaqDriver & { meta?: Omit<PluginDriverMeta, 'kind' | 'plugin'> }).meta
1103
+ if (meta && typeof meta.label === 'string') {
1104
+ pluginMetaRegistry().set(driver.kind, {
1105
+ kind: driver.kind,
1106
+ label: meta.label,
1107
+ status: meta.status === 'builtin' || meta.status === 'planned' ? meta.status : 'real',
1108
+ configFields: Array.isArray(meta.configFields) ? meta.configFields : [],
1109
+ plugin: true,
1110
+ })
1111
+ }
1112
+ else {
1113
+ // 同名驱动重注册(热重载)可能这次不带 meta:旧 meta 一并清除,保持两边一致
1114
+ pluginMetaRegistry().delete(driver.kind)
1115
+ }
1082
1116
  }
1083
1117
 
1084
1118
  export function listPluginDrivers(): string[] {
1085
1119
  return [...pluginRegistry().keys()]
1086
1120
  }
1087
1121
 
1122
+ /**
1123
+ * 清空插件驱动与自描述目录(插件宿主热重载前调用):停用/卸载的插件驱动随之失效,
1124
+ * 只有本轮重新装载成功的插件驱动会再注册进来 —— 否则被停用的驱动会一直生效到进程重启。
1125
+ */
1126
+ export function clearPluginDrivers(): void {
1127
+ pluginRegistry().clear()
1128
+ pluginMetaRegistry().clear()
1129
+ }
1130
+
1131
+ /** 插件驱动自描述目录(驱动目录合并端点用;热重载随重注册刷新) */
1132
+ export function listPluginDriverMetas(): PluginDriverMeta[] {
1133
+ return [...pluginMetaRegistry().values()]
1134
+ }
1135
+
1088
1136
  export function normalizeDriverKind(kind: string): DaqDriverKind {
1089
1137
  if (kind === 'modbus') return 'modbus-tcp'
1090
1138
  if (kind === 'rtu' || kind === 'modbus-rtu-tcp') return 'modbus-rtu'
@@ -1095,10 +1143,11 @@ export function resolveDaqDriver(kind: DaqDriverKind): DaqDriver {
1095
1143
  return pluginRegistry().get(kind) ?? REGISTRY[kind] ?? mockDaqDriver
1096
1144
  }
1097
1145
 
1098
- /** 驱动可用性探测(meta 报告:包缺失时 UI 显示"未安装"而非硬失败) */
1146
+ /** 驱动可用性探测(meta 报告:包缺失时 UI 显示"未安装"而非硬失败;含插件驱动) */
1099
1147
  export async function probeDriverAvailability(): Promise<Record<string, boolean>> {
1100
1148
  const out: Record<string, boolean> = {}
1101
- for (const [kind, drv] of Object.entries(REGISTRY)) {
1149
+ const all: Array<[string, DaqDriver]> = [...Object.entries(REGISTRY), ...pluginRegistry()]
1150
+ for (const [kind, drv] of all) {
1102
1151
  try {
1103
1152
  out[kind] = await drv.available()
1104
1153
  }
@@ -1108,3 +1157,29 @@ export async function probeDriverAvailability(): Promise<Record<string, boolean>
1108
1157
  }
1109
1158
  return out
1110
1159
  }
1160
+
1161
+ /**
1162
+ * 驱动目录合并(内置 DAQ_DRIVERS + 插件自描述;同名插件条目覆盖内置并标记 plugin)。
1163
+ * index.get.ts 以 `drivers` 下发,前端据此渲染「添加节点」下拉与动态参数表单。
1164
+ */
1165
+ export async function driverCatalog(): Promise<Array<{
1166
+ kind: string
1167
+ label: string
1168
+ status: 'builtin' | 'real' | 'planned'
1169
+ configFields: import('../../../../shared/daq-protocol').DriverConfigField[]
1170
+ plugin?: boolean
1171
+ }>> {
1172
+ const out: Array<{ kind: string, label: string, status: 'builtin' | 'real' | 'planned', configFields: import('../../../../shared/daq-protocol').DriverConfigField[], plugin?: boolean }> = DAQ_DRIVERS.map(d => ({
1173
+ kind: d.kind,
1174
+ label: d.label,
1175
+ status: d.status,
1176
+ configFields: d.configFields,
1177
+ }))
1178
+ for (const m of listPluginDriverMetas()) {
1179
+ const i = out.findIndex(d => d.kind === m.kind)
1180
+ const entry = { kind: m.kind, label: m.label, status: m.status, configFields: m.configFields ?? [], plugin: true }
1181
+ if (i >= 0) out[i] = entry
1182
+ else out.push(entry)
1183
+ }
1184
+ return out
1185
+ }
@@ -11,9 +11,10 @@
11
11
 
12
12
  import { randomUUID } from 'node:crypto'
13
13
  import { applyTransform, inverseTransform, normalizeDataTransform, dcwKeyFromRef } from '../../../../shared/dcw-protocol'
14
- import type { AepDcwNodeChange, DcwDriverKind, DcwNodeView, DcwParamView, DataTransform, LineInput, LineQueryOpts, LineQueryResult, LineRunState, LineView, ProductInput, ProductView, RecipeInput, RecipeRunView, RecipeView, DcwWriteMeta } from '../../../../shared/dcw-protocol'
14
+ import type { AepDcwNodeChange, DcwDriverKind, DcwNodeView, DcwParamInput, DcwParamView, DataTransform, LineInput, LineQueryOpts, LineQueryResult, LineRunState, LineView, ProductInput, ProductView, RecipeInput, RecipeRunView, RecipeView, DcwWriteMeta } from '../../../../shared/dcw-protocol'
15
15
  import { AppError, ErrorCodes } from '../../../utils/errors'
16
16
  import { normalizeDcwDriverKind, resolveDcwDriver } from './drivers'
17
+ import { attachDcwPluginBridge } from './plugin-bridge'
17
18
  import { findDcwTemplate } from './dcw-templates'
18
19
  import { getDeviceTwinRepo } from '../assets/device-twin.repo'
19
20
  import { DcwNode } from './dcw-node'
@@ -34,6 +35,9 @@ import { daqRuntimeSettings } from '../settings'
34
35
  /** 运维日志写下发防噪:同节点同值 10s 内的心跳重下发不重复入册 */
35
36
  const opsWriteMemo = new Map<string, { eng: number, at: number }>()
36
37
 
38
+ // 写驱动插件桥(模块装载即挂;插件宿主先到则注册项排队、此处接管回放)
39
+ attachDcwPluginBridge()
40
+
37
41
  /** 周期读网关默认间隔(节点 readIntervalMs=null 时生效;真实 PLC 建议按链路承载调整) */
38
42
  const DEFAULT_READ_INTERVAL_MS = 5000
39
43
 
@@ -9,6 +9,7 @@
9
9
  */
10
10
  import { createRequire } from 'node:module'
11
11
  import type { DcwDriverKind } from '../../../../shared/dcw-protocol'
12
+ import { DCW_DRIVERS } from '../../../../shared/dcw-protocol'
12
13
  import { AppError } from '../../../utils/errors'
13
14
  import { classifyCommError, closeModbusSafely, decodeRegisters, evictModbusConn, evictOpcUaConn, getModbusConn, getOpcUaConn, modbusKey, registerOffset, withModbusConn } from '../daq/drivers'
14
15
 
@@ -637,12 +638,94 @@ const REGISTRY: Record<DcwDriverKind, DcwWriteDriver> = {
637
638
  'http': httpDcwDriver,
638
639
  }
639
640
 
641
+ /**
642
+ * 插件写驱动注册表(经 ctx.dcw.registerWriteDriver;与数采侧 registerPluginDriver 对称)。
643
+ * globalThis 防 HMR 双实例;resolveDcwDriver 插件优先,热重载同名幂等覆盖。
644
+ * 驱动可携带可选 meta(label/configFields)进写控驱动目录(dcwDriverCatalog)。
645
+ */
646
+ export interface PluginWriteDriverMeta {
647
+ kind: string
648
+ label: string
649
+ status: 'builtin' | 'real' | 'planned'
650
+ configFields?: import('../../../../shared/daq-protocol').DriverConfigField[]
651
+ plugin: true
652
+ }
653
+
654
+ const g_plugins = globalThis as typeof globalThis & { __dcwPluginDrivers?: Map<string, DcwWriteDriver> }
655
+ function pluginRegistry(): Map<string, DcwWriteDriver> {
656
+ return g_plugins.__dcwPluginDrivers ??= new Map()
657
+ }
658
+
659
+ const g_metas = globalThis as typeof globalThis & { __dcwPluginDriverMetas?: Map<string, PluginWriteDriverMeta> }
660
+ function pluginMetaRegistry(): Map<string, PluginWriteDriverMeta> {
661
+ return g_metas.__dcwPluginDriverMetas ??= new Map()
662
+ }
663
+
664
+ export function registerPluginWriteDriver(driver: DcwWriteDriver): void {
665
+ if (driver.kind in REGISTRY) console.warn(`[dcw-drivers] 插件写驱动覆盖内置:「${driver.kind}」`)
666
+ pluginRegistry().set(driver.kind, driver)
667
+ const meta = (driver as DcwWriteDriver & { meta?: Omit<PluginWriteDriverMeta, 'kind' | 'plugin'> }).meta
668
+ if (meta && typeof meta.label === 'string') {
669
+ pluginMetaRegistry().set(driver.kind, {
670
+ kind: driver.kind,
671
+ label: meta.label,
672
+ status: meta.status === 'builtin' || meta.status === 'planned' ? meta.status : 'real',
673
+ configFields: Array.isArray(meta.configFields) ? meta.configFields : [],
674
+ plugin: true,
675
+ })
676
+ }
677
+ else {
678
+ pluginMetaRegistry().delete(driver.kind)
679
+ }
680
+ }
681
+
682
+ export function listPluginWriteDrivers(): string[] {
683
+ return [...pluginRegistry().keys()]
684
+ }
685
+
686
+ /** 插件写驱动自描述目录(写控驱动目录合并端点用) */
687
+ export function listPluginWriteDriverMetas(): PluginWriteDriverMeta[] {
688
+ return [...pluginMetaRegistry().values()]
689
+ }
690
+
691
+ /** 清空插件写驱动与其自描述目录(插件宿主热重载前调用;与数采侧 clearPluginDrivers 对称) */
692
+ export function clearPluginWriteDrivers(): void {
693
+ pluginRegistry().clear()
694
+ pluginMetaRegistry().clear()
695
+ }
696
+
697
+ /**
698
+ * 写控驱动目录(内置 DCW_DRIVERS + 插件自描述合并;同名插件条目覆盖内置)。
699
+ * dcw index.get 以 `drivers` 下发,前端写控节点向导据此渲染。
700
+ */
701
+ export async function dcwDriverCatalog(): Promise<Array<{
702
+ kind: string
703
+ label: string
704
+ status: 'builtin' | 'real' | 'planned'
705
+ configFields: import('../../../../shared/daq-protocol').DriverConfigField[]
706
+ plugin?: boolean
707
+ }>> {
708
+ const out: Array<{ kind: string, label: string, status: 'builtin' | 'real' | 'planned', configFields: import('../../../../shared/daq-protocol').DriverConfigField[], plugin?: boolean }> = DCW_DRIVERS.map(d => ({
709
+ kind: d.kind,
710
+ label: d.label,
711
+ status: d.status,
712
+ configFields: d.configFields,
713
+ }))
714
+ for (const m of listPluginWriteDriverMetas()) {
715
+ const i = out.findIndex(d => d.kind === m.kind)
716
+ const entry = { kind: m.kind, label: m.label, status: m.status, configFields: m.configFields ?? [], plugin: true }
717
+ if (i >= 0) out[i] = entry
718
+ else out.push(entry)
719
+ }
720
+ return out
721
+ }
722
+
640
723
  export function normalizeDcwDriverKind(kind: string): DcwDriverKind {
641
724
  if (kind === 'modbus') return 'modbus-tcp'
642
725
  if (kind === 'rtu' || kind === 'modbus-rtu-tcp') return 'modbus-rtu'
643
- return (kind in REGISTRY ? kind : 'mock') as DcwDriverKind
726
+ return ((kind in REGISTRY || pluginRegistry().has(kind) ? kind : 'mock')) as DcwDriverKind
644
727
  }
645
728
 
646
729
  export function resolveDcwDriver(kind: DcwDriverKind): DcwWriteDriver {
647
- return REGISTRY[kind] ?? mockDcwDriver
730
+ return pluginRegistry().get(kind) ?? REGISTRY[kind] ?? mockDcwDriver
648
731
  }
@@ -0,0 +1,45 @@
1
+ import type { DcwWriteDriver } from './drivers'
2
+ import { registerPluginWriteDriver } from './drivers'
3
+
4
+ interface DcwPluginBridge {
5
+ pendingDrivers: unknown[]
6
+ /** 回放槽(drain 接管后设置;注册即时回调) */
7
+ _drain?: () => void
8
+ registerWriteDriver(d: unknown): void
9
+ drain(onDriver: (d: unknown) => void): void
10
+ }
11
+
12
+ /** 自建桥(仅队列 + drain 槽;宿主后到时由其接管) */
13
+ function makeDcwBridge(): DcwPluginBridge {
14
+ return {
15
+ pendingDrivers: [],
16
+ registerWriteDriver(d) {
17
+ this.pendingDrivers.push(d)
18
+ this._drain?.()
19
+ },
20
+ drain(onDriver) {
21
+ this._drain = () => {
22
+ for (const d of this.pendingDrivers.splice(0)) onDriver(d)
23
+ }
24
+ this._drain()
25
+ },
26
+ }
27
+ }
28
+
29
+ let attached = false
30
+
31
+ /**
32
+ * DCW 写驱动插件桥 —— 与数采侧 attachDaqPluginBridge 同构:
33
+ * 插件宿主与 dcw 模块装载顺序无关(谁后到谁接管,先到的注册项排队回放)。
34
+ * 在 dcw-controller 模块装载时调用一次。
35
+ */
36
+ export function attachDcwPluginBridge(): void {
37
+ if (attached) return
38
+ attached = true
39
+ const g = globalThis as { __dcwPluginExt?: DcwPluginBridge }
40
+ const bridge: DcwPluginBridge = g.__dcwPluginExt ?? makeDcwBridge()
41
+ g.__dcwPluginExt = bridge
42
+ bridge.drain(
43
+ d => registerPluginWriteDriver(d as DcwWriteDriver),
44
+ )
45
+ }
@@ -534,6 +534,24 @@ async function loadAllPlugins(host, { config, paths }) {
534
534
  return m.getDaqNodeRepo().snapshot()
535
535
  },
536
536
  }
537
+ // DCW 写驱动扩展面:与 daq.registerDriver 对称(排队桥 globalThis.__dcwPluginExt,
538
+ // dcw-controller 侧 plugin-bridge 接管回放)。写驱动契约见 server/services/workshop/dcw/drivers.ts。
539
+ const dcwExt = (globalThis.__dcwPluginExt ??= {
540
+ pendingDrivers: [],
541
+ registerWriteDriver(d) {
542
+ this.pendingDrivers.push(d)
543
+ this._drain?.()
544
+ },
545
+ drain(onDriver) {
546
+ this._drain = () => {
547
+ for (const d of this.pendingDrivers.splice(0)) onDriver(d)
548
+ }
549
+ this._drain()
550
+ },
551
+ })
552
+ ctx.dcw = {
553
+ registerWriteDriver: d => dcwExt.registerWriteDriver(d),
554
+ }
537
555
  // OMP 工具扩展面:插件注册自定义 host 工具 → omp 会话运行时热注入
538
556
  const ompExt = (globalThis.__ompPluginToolsBridge ??= {
539
557
  pending: [],
@@ -697,6 +715,18 @@ async function doReload(host) {
697
715
  }
698
716
  }
699
717
  const prevNames = [...host.plugins.keys()]
718
+ // 插件注册的协议驱动(数采读 + 写控)先清空:停用/卸载的插件驱动立即失效,
719
+ // 本轮装载成功的插件经 ctx.daq/ctx.dcw 重新注册(同名幂等)。
720
+ try {
721
+ const daqDrivers = await import('@/server/services/workshop/daq/drivers')
722
+ daqDrivers.clearPluginDrivers()
723
+ }
724
+ catch { /* daq 未装载(桥排队中):注册表为空,无需清 */ }
725
+ try {
726
+ const dcwDrivers = await import('@/server/services/workshop/dcw/drivers')
727
+ dcwDrivers.clearPluginWriteDrivers()
728
+ }
729
+ catch { /* dcw 未装载:同上 */ }
700
730
  // 工具注销延后:先装载新集、后清「本轮未再装载」的旧插件工具。
701
731
  // 原先在装载前就全部注销 → 重载窗口内(秒级~数十秒)所有插件工具"未知工具",
702
732
  // 期间到达的 Agent 工具调用(daq:sample 自动诊断/kb_store 等)被误拒
@@ -351,6 +351,21 @@ export const DAQ_DRIVERS: DaqDriverMeta[] = [
351
351
  export const daqDriverMeta = (kind: DaqDriverKind): DaqDriverMeta | undefined =>
352
352
  DAQ_DRIVERS.find(d => d.kind === kind)
353
353
 
354
+ /**
355
+ * 驱动目录条目(GET /api/workshop/daq `drivers` 字段):内置 DAQ_DRIVERS 与
356
+ * 协议插件自描述(ctx.daq.registerDriver 携带的 meta)合并后的统一形态。
357
+ * kind 放宽为 string —— 插件可注册任意自定义协议 kind。
358
+ */
359
+ export interface DaqDriverCatalogEntry {
360
+ kind: string
361
+ label: string
362
+ status: 'builtin' | 'real' | 'planned'
363
+ /** 连接参数表单 schema(前端动态渲染;插件驱动经 meta.configFields 自描述) */
364
+ configFields: DriverConfigField[]
365
+ /** true = 来自协议插件(前端展示「插件」徽标;热重载/停用随宿主收敛) */
366
+ plugin?: boolean
367
+ }
368
+
354
369
  /** 连接测试结果(REST/前端向导共用) */
355
370
  export interface DriverTestResult {
356
371
  ok: boolean
@@ -1 +0,0 @@
1
- import{a as e}from"./BU83-NnX.js";import{$ as t,Ht as n,P as r,R as i,S as a,Ut as o,V as s,Vt as c,W as l,b as u,d,dt as f,f as p,h as m,i as h,m as g,nt as _,p as v,pt as y,tt as b,xt as x,y as S}from"./CSkxz2NX.js";import{c as C,f as ee,l as w,s as te}from"./D6uzXueg.js";import{n as ne}from"./DtYHUi5Z.js";import{t as re}from"./BHA40aHa.js";import{n as ie}from"./KZQX7xoM.js";import{t as ae}from"./DZtm4l-P2.js";import{t as T}from"./BDNMzG2s2.js";import{t as E}from"./D0ZBQrN_2.js";import{t as oe}from"./BC9wjTJK2.js";import{t as se}from"./CNs_Ozdc2.js";import{t as ce}from"./DTFCy6h-.js";import{a as le,i as ue,n as de,r as fe,t as pe}from"./DcsCcxp4.js";import{t as me}from"./D8qvkfyY.js";import{t as he}from"./C3J6FYKa.js";import{t as D}from"./CFxtLwjp.js";var O={class:`mono dim`},k={class:`mono ch`},ge=[`title`],_e=[`title`],ve={class:`trend-cell`},ye=[`title`],be=[`y1`,`y2`],xe=[`y1`,`y2`],Se=[`points`],A=[`y1`,`y2`],Ce={class:`mono`},we={class:`mono`},Te=[`title`],Ee=[`value`,`title`],De={value:``},Oe=[`value`],ke=[`title`],j={key:1,class:`run-pill na`},Ae={class:`prod-cell`},M=[`title`],N=[`title`],P={key:1,class:`dim`},je={class:`dev-binds`},Me=[`title`],Ne=[`onClick`],Pe=[`title`],F={value:``},Fe=[`value`,`disabled`],Ie={class:`right`},Le=[`title`],Re=120,I=26,ze=Object.assign(T(a({__name:`DaqNodeRow`,props:{n:{}},setup(t){let n=t,{t:r}=ie(),i=pe(),a=me(),f=he();function _(e){if(!e.lastAt)return!0;let t=e.intervalMs??i.controller.defaultIntervalMs;return Date.now()-Date.parse(e.lastAt)>Math.max(t*4,12e3)}function v(e){return e.enabled?e.lineId?a.lineStateOf(e.lineId).active?!i.controller.running||_(e)?`offline`:e.state:`idle`:`unassigned`:`disabled`}function y(e){let t=v(e);return t===`ok`||t===`warn`||t===`alarm`}function C(e){if(!e.lineId)return null;let t=a.lineStateOf(e.lineId);return!t.active||!t.recipeId?null:a.recipes.find(e=>e.id===t.recipeId)?.daqWindows?.find(t=>t.nodeId===e.id)??null}function ee(e){let t=C(e);return!t||e.value==null?!1:t.min!=null&&e.value<t.min||t.max!=null&&e.value>t.max}function w(e){let t=C(e);return t&&(t.min!=null||t.max!=null)?{min:t.min,max:t.max}:e.warnLow!=null||e.warnHigh!=null?{min:e.warnLow,max:e.warnHigh}:{min:null,max:null}}function te(e){let t=e.filter(Number.isFinite);if(t.length<2)return``;let n=Math.min(...t),r=Math.max(...t)-n||1;return t.map((e,i)=>`${(i/(t.length-1)*Re).toFixed(1)},${(I-(e-n)/r*24-1).toFixed(1)}`).join(` `)}function ne(e,t){if(t==null||!Number.isFinite(t))return null;let n=e.filter(Number.isFinite);if(n.length<2)return null;let r=Math.min(...n,t),i=Math.max(...n,t)-r||1;return Number((I-(t-r)/i*24-1).toFixed(1))}function ae(e){let t=v(e),n=r(`daq.k44c2n065`);if(t===`offline`)return e.lastError?{key:t,label:n,tip:e.lastError}:{key:t,label:n,tip:i.controller.running?r(`daq.k1staled129`,{p0:Math.round(Math.max((e.intervalMs??i.controller.defaultIntervalMs)*4,12e3)/1e3)}):r(`daq.k1gateoff140`)};let a={ok:r(`daq.k41k5c062`),warn:r(`daq.k49z8v063`),alarm:r(`daq.k3xmid064`),offline:n,idle:r(`daq.k3ozyqz117`),disabled:r(`daq.k1disabl130`),unassigned:r(`daq.k3ootr6053`)};if(t===`idle`)return{key:t,label:a.idle,tip:r(`daq.k1idlehin139`)};if((t===`ok`||t===`warn`||t===`alarm`)&&ee(e)){let t=C(e);return{key:`alarm`,label:r(`daq.k1l3pt51104`),tip:r(`daq.k1hrrqa1122`,{p0:t?.min??`-∞`,p1:t?.max??`+∞`,p2:``})}}return{key:t,label:a[t],tip:``}}function T(e){let t=i.templates.find(t=>t.key===le(e));return t?`${t.name} · ${t.ch}`:e||`-`}let oe=e=>e==null?r(`daq.k9vnp9h124`,{p0:i.controller.defaultIntervalMs}):`${e}ms`,se=e=>e==null?r(`daq.k9vnp9h124`,{p0:i.controller.defaultPublishIntervalMs}):e===0?r(`daq.k41mvv078`):`${e}ms`,ce=e=>i.meta.drivers.find(t=>t.kind===e)?.status===`planned`,ue=e=>e.deviceIds??(e.deviceBindingId?[e.deviceBindingId]:[]),de=e=>f.twins.find(t=>t.id===e)?.name??e,fe=d(()=>f.twins.filter(e=>e.kind!==`daq`&&!(e.modelRef??``).startsWith(`daq-`)&&!(e.modelRef??``).startsWith(`dcw-`))),D=d(()=>{let e=n.n,t=w(e),r=e.lineId?a.lineStateOf(e.lineId):null;return{tpl:T(e.templateRef),pill:ae(e),alarm:ee(e),live:y(e),trend:te(e.hist),limMin:ne(e.hist,t.min),limMax:ne(e.hist,t.max),interval:oe(e.intervalMs),publish:se(e.publishIntervalMs),lineActive:!!r?.active,lineProduct:r?.productName??``,lineRecipe:r?.recipeName??``}});async function ze(){let t=n.n,a=!t.enabled;try{await i.patchNode(t.id,{enabled:a}),t.enabled=a,a||(t.state=`offline`),e.success(r(a?`daq.k1nodestart147`:`daq.k1nodestop146`))}catch(t){e.error(E(t))}}async function Be(t){let r=t.target.value;try{await i.patchNode(n.n.id,{lineId:r});let e=n.n;e.lineId=r}catch(t){e.error(E(t))}}async function Ve(t){let r=t.target.value;if(!r)return;let a=n.n;if(!a.deviceIds?.includes(r)){try{await i.setNodeBindings(a.id,[...a.deviceIds??[],r])}catch(t){e.error(E(t))}t.target.value=``}}async function He(t){let r=n.n;try{await i.setNodeBindings(r.id,(r.deviceIds??[]).filter(e=>e!==t))}catch(t){e.error(E(t))}}return(e,n)=>{let r=re;return s(),m(`tr`,{class:c({"row-recipe-alarm":D.value.alarm})},[p(`td`,null,[p(`span`,O,o(t.n.id.slice(0,8)),1),p(`b`,null,o(t.n.name),1),p(`small`,k,o(D.value.tpl),1)]),p(`td`,null,[p(`span`,{class:c([`st-pill`,[D.value.pill.key]]),title:D.value.pill.tip},o(D.value.pill.label),11,ge)]),p(`td`,{class:c([`mono val`,{stale:!D.value.live,"val-alarm":t.n.state===`alarm`||D.value.alarm}]),title:D.value.live?void 0:D.value.pill.tip},[S(o(t.n.value==null?`--`:t.n.value.toFixed(t.n.decimals))+` `,1),p(`small`,null,o(t.n.unit),1)],10,_e),p(`td`,ve,[(s(),m(`svg`,{class:`trend`,viewBox:`0 0 120 26`,preserveAspectRatio:`none`,title:e.$t(`daq.k1trnd002`)},[D.value.limMin==null?g(``,!0):(s(),m(`line`,{key:0,class:`lim`,x1:`0`,y1:D.value.limMin,x2:`120`,y2:D.value.limMin},null,8,be)),D.value.limMax==null?g(``,!0):(s(),m(`line`,{key:1,class:`lim max`,x1:`0`,y1:D.value.limMax,x2:`120`,y2:D.value.limMax},null,8,xe)),D.value.trend?(s(),m(`polyline`,{key:2,class:c([`trace`,{alarm:t.n.state===`alarm`||D.value.alarm}]),points:D.value.trend},null,10,Se)):(s(),m(`line`,{key:3,class:`trace-idle`,x1:`0`,y1:I/2,x2:`120`,y2:I/2},null,8,A))],8,ye))]),p(`td`,Ce,o(D.value.interval),1),p(`td`,we,o(D.value.publish),1),p(`td`,null,[p(`span`,{class:c([`drv-tag`,{planned:ce(t.n.driver)}]),title:ce(t.n.driver)?e.$t(`daq.k1plndrv138`):``},o(t.n.driver),11,Te)]),p(`td`,null,[p(`select`,{class:`line-sel`,value:t.n.lineId,title:e.$t(`daq.k3q23v3010`),onChange:Be},[p(`option`,De,o(e.$t(`daq.k3ootr6053`)),1),(s(!0),m(h,null,l(x(a).lines,e=>(s(),m(`option`,{key:e.id,value:e.id},o(e.name),9,Oe))),128))],40,Ee)]),p(`td`,null,[t.n.lineId?(s(),m(`span`,{key:0,class:c([`run-pill`,{on:D.value.lineActive}]),title:e.$t(`daq.k1runtipc131`)},[n[0]||=p(`span`,{class:`rp-dot`},null,-1),S(` `+o(D.value.lineActive?e.$t(`daq.k3vp67i096`):e.$t(`daq.k3ozyqz117`)),1)],10,ke)):(s(),m(`span`,j,o(e.$t(`daq.k3ootr6053`)),1))]),p(`td`,Ae,[t.n.lineId&&D.value.lineActive?(s(),m(h,{key:0},[p(`b`,{title:e.$t(`daq.k1prdrtip132`)},o(D.value.lineProduct||`--`),9,M),p(`small`,{class:`mono`,title:e.$t(`daq.k1prdrtip132`)},o(D.value.lineRecipe||`--`),9,N)],64)):(s(),m(`span`,P,`--`))]),p(`td`,null,[p(`div`,je,[(s(!0),m(h,null,l(ue(t.n),t=>(s(),m(`span`,{key:t,class:`dev-bind-chip`,title:e.$t(`daq.k2bindtip137`)},[S(o(de(t))+` `,1),p(`span`,{class:`dev-unbind`,title:`unbind`,onClick:e=>He(t)},`✕`,8,Ne)],8,Me))),128)),p(`select`,{class:`line-sel dev-add`,value:``,title:e.$t(`daq.k2bindtip137`),onChange:Ve},[p(`option`,F,o(e.$t(`daq.k3own4q056`)),1),(s(!0),m(h,null,l(fe.value,e=>(s(),m(`option`,{key:e.id,value:e.id,disabled:(t.n.deviceIds??[]).includes(e.id)},o(de(e.id)),9,Fe))),128))],40,Pe)])]),p(`td`,Ie,[p(`button`,{class:c([`node-toggle`,{off:!t.n.enabled}]),title:t.n.enabled?e.$t(`daq.k1nodestop146`):e.$t(`daq.k1nodestart147`),onClick:ze},[p(`span`,{class:c(t.n.enabled?`i-tabler-player-pause`:`i-tabler-player-play`)},null,2),S(` `+o(t.n.enabled?e.$t(`daq.k1nodestop146`):e.$t(`daq.k1nodestart147`)),1)],10,Le),u(r,{class:`console-link`,to:`/daq/${t.n.id}`},{default:b(()=>[n[1]||=p(`span`,{class:`i-tabler-dashboard`},null,-1),S(` `+o(e.$t(`daq.k3o3jg2074`)),1)]),_:1},8,[`to`])])],2)}}}),[[`__scopeId`,`data-v-4b6f87e1`]]),{__name:`WorkshopDaqNodeRow`}),Be={class:`page`},Ve={class:`aw-page-head`},He={class:`sub`},Ue={class:`badges mono`},We=[`title`],Ge=[`title`],Ke={class:`txt`},qe={class:`mono`},Je={key:1,class:`infra-banner`},Ye={class:`txt`},Xe={key:2,class:`infra-banner`},Ze={class:`txt`},Qe=[`disabled`],$e={key:3,class:`alarm-bar`},et={class:`bar-label`},tt={class:`mono`},nt={class:`alarm-scroll`},rt=[`title`],it={class:`mono dim`},at={class:`mono`},ot={key:0,class:`esc mono`},st=[`onClick`],ct={class:`aw-tile ctrl-card`},lt={class:`ctrl-row`},ut={class:`ctrl-left`},dt=[`title`],ft={class:`cycle mono`},pt=[`title`],mt={class:`ctrl-right`},ht={class:`ctrl-metrics mono`},gt=[`title`],_t=[`title`],vt=[`title`],yt=[`title`],bt={class:`line-strip`},xt={class:`strip-label`},St={class:`mono`},Ct={class:`strip-scroll`},wt={key:0,class:`lp-run`},Tt={key:1,class:`lp-idle`},Et={class:`lp-idle`},Dt={class:`modal`},Ot={class:`m-title`},kt={class:`seg-row`},At={class:`f-grid`},jt={class:`f`},Mt=[`value`],Nt={class:`f`},Pt=[`placeholder`],Ft={key:0,class:`f`},It=[`placeholder`],Lt={class:`f-grid`},Rt={class:`f`},zt=[`value`],Bt={key:0,class:`f-grid driver-form`},Vt={key:0},Ht=[`onUpdate:modelValue`],Ut=[`value`],Wt=[`onUpdate:modelValue`,`type`,`placeholder`],Gt={key:2,class:`hint`},Kt={class:`test-row`},qt=[`disabled`],Jt={key:1,class:`m-err`},Yt={class:`m-actions`},Xt=[`disabled`,`title`],Zt={class:`modal`},Qt={class:`m-title`},$t={class:`sec-label`},en={class:`tpl-table`},tn={class:`mono dim`},nn={class:`mono range`},rn={class:`right actions`},an=[`onClick`],on=[`onClick`],sn={key:0},cn={colspan:`3`,class:`empty`},ln={class:`sec-label`},un={class:`f-grid`},dn={class:`f`},fn=[`placeholder`],pn={class:`f`},mn={class:`f`},hn=[`placeholder`],gn={class:`f`},_n=[`placeholder`],vn={class:`f`},yn={class:`f`},bn={class:`f`},xn={class:`f`},Sn=[`value`],Cn={class:`f`},wn={class:`hint`},Tn={class:`f`},En={class:`hint`},Dn={key:0,class:`m-err`},On={class:`m-actions`},kn=[`disabled`],An={class:`sec-label`},jn={class:`tpl-table`},Mn={class:`mono dim`},Nn={class:`mono range`},Pn={class:`right actions`},Fn=[`onClick`],In={class:`aw-tile opt-card`},Ln={class:`opt-count mono`},Rn={class:`opt-filters`},zn={value:``},Bn=[`value`],Vn={value:``},Hn=[`value`],Un={key:0,class:`opt-empty`},Wn={class:`opt-list`},Gn={class:`opt-line1`},Kn={class:`opt-node`},qn={class:`mono opt-params`},Jn={class:`mono opt-time`},Yn=[`disabled`,`onClick`],Xn=[`onClick`],Zn={class:`opt-line2 mono`},Qn={key:1,class:`opt-open-hint`},$n={key:2,class:`opt-agg`},er={key:3,class:`opt-agg`},tr={key:0,class:`opt-series`},nr={class:`opt-spark`,viewBox:`0 0 240 36`,preserveAspectRatio:`none`},rr=[`points`],ir={class:`mono`},ar={key:0,class:`opt-empty`},or={class:`aw-tile table-card`},sr={class:`tbl-toolbar`},cr={class:`filters`},lr={class:`flt`},ur={value:``},dr=[`value`],fr={value:`none`},pr={class:`flt`},mr={value:``},hr=[`value`],gr={value:`none`},_r=[`title`],vr={value:``},yr={value:`on`},br={value:`off`},xr={class:`flt`},Sr={value:``},Cr={value:`ok`},wr={value:`warn`},Tr={value:`alarm`},Er={value:`offline`},Dr={class:`flt`},Or={value:``},kr=[`value`],Ar={class:`flt`},jr={value:``},Mr=[`value`],Nr=[`title`],Pr={value:``},Fr={value:`live`},Ir={value:`hour`},Lr={value:`day`},Rr={value:`old`},zr={value:`never`},Br={class:`flt`},Vr=[`placeholder`],Hr={class:`count mono`},Ur={class:`ops-panels`},Wr={class:`panel-head`},Gr={class:`panel-body`},Kr={key:0,class:`panel-empty`},qr={class:`mono dim`},Jr={class:`mono`},Yr={key:0,class:`esc mono`},Xr=[`onClick`],Zr={class:`ops-panel event-panel`},Qr={class:`panel-head`},$r={class:`panel-body`},ei={key:0,class:`panel-empty`},ti={class:`mono dim t`},ni=[`title`],ri=[`title`],ii=[`title`],ai={class:`right`},oi={key:0,class:`vs-pad`,"aria-hidden":`true`},si={key:1,class:`vs-pad`,"aria-hidden":`true`},ci={key:2},li={colspan:`11`},ui={class:`pane-empty`,style:{"min-height":`120px`}},di={class:`pe-sub`},fi={key:3},pi={colspan:`11`},mi={class:`pane-empty`,style:{"min-height":`90px`}},hi={class:`pe-sub`},gi={key:6,class:`err`},_i=42,vi=8,yi=T(a({__name:`index`,setup(a){let{t:T}=ie();se({layout:`default`}),ne({title:()=>T(`titles.daq`)});let O=pe(),k=me(),ge=oe(),_e=d(()=>k.lines.some(e=>k.lineStateOf(e.id).active)),ve=D();function ye(e){return{write:T(`logs.kind.write`),manual:T(`logs.kind.manual`),alarm:T(`logs.kind.alarm`),line:T(`logs.kind.line`),recipe:T(`logs.kind.recipe`),rollback:T(`logs.kind.rollback`),daq:T(`logs.kind.daq`),system:T(`logs.kind.system`)}[e]??(e||T(`logs.kind.system`))}function be(e){let t=new Date(e);return Number.isFinite(t.getTime())?`${String(t.getHours()).padStart(2,`0`)}:${String(t.getMinutes()).padStart(2,`0`)}:${String(t.getSeconds()).padStart(2,`0`)}`:``}async function xe(t){try{await O.ackAlarm(t),e.success(T(`daq.k1acked144`))}catch(t){e.error(E(t))}}let Se=null;i(()=>{ge.ensureConnected(),Se=O.ensureWsFeed(),ve.ensureLive(),O.load(),O.fetchAlarms(),k.load(),ki.load(),k.loadOptimizations(),ce(()=>{O.load(),O.fetchAlarms()},5e3,{bgMs:3e4}),ce(()=>{k.load()},15e3,{bgMs:6e4})}),r(()=>{Se?.()});let A=f({lineId:``,deviceId:``,template:``,driver:``,lineRun:``,state:``,time:``,search:``}),Ce=d(()=>!!(A.lineId||A.deviceId||A.template||A.driver||A.lineRun||A.state||A.time||A.search.trim()));function we(){A.lineId=``,A.deviceId=``,A.template=``,A.driver=``,A.lineRun=``,A.state=``,A.time=``,A.search=``}let Te=d(()=>{let e=new Map;for(let t of O.nodes)e.set(t.templateRef,(e.get(t.templateRef)??0)+1);return[...e.entries()].map(([e,t])=>({ref:e,count:t,label:Vi(e)}))}),Ee=d(()=>{let e=new Map;for(let t of O.nodes)e.set(t.driver,(e.get(t.driver)??0)+1);return[...e.entries()].map(([e,t])=>({kind:e,count:t,label:O.meta.drivers.find(t=>t.kind===e)?.label??e}))});function De(e){if(!e.lastAt)return`never`;let t=Date.now()-Date.parse(e.lastAt);return t<=3e5?`live`:t<=36e5?`hour`:t<=864e5?`day`:`old`}function Oe(e){return!A.time||De(e)===A.time}function ke(e){let t=A.search.trim().toLowerCase();return!t||e.name.toLowerCase().includes(t)||e.id.toLowerCase().includes(t)}let j=y(!1),Ae=y(!1),M=y(``),N=y(``),P=y({}),je=y(``),Me=d(()=>k.recipes.filter(e=>!M.value||e.lineId===M.value));function Ne(e){return{open:`daq.k1optst001`,judged:`daq.k1optst008`,"judged-keep":`daq.k1optst002`,"rolled-back":`daq.k1optst003`,superseded:`daq.k1optst004`,"superseded-manual":`daq.k1optst005`,"closed-line-stop":`daq.k1optst006`,failed:`daq.k1optst007`}[e]??`daq.k1optst001`}async function Pe(){j.value=!j.value,j.value&&(Ae.value=!0,await F())}async function F(){await k.loadOptimizations({lineId:M.value||void 0,recipeId:N.value||void 0})}function Fe(){N.value&&!Me.value.some(e=>e.id===N.value)&&(N.value=``),F()}async function Ie(e){je.value=e;try{let t=await k.optimizationSeries(e);P.value={...P.value,[e]:t}}finally{je.value=``}}function Le(e,t=240,n=36){let r=e.map(e=>e.value??e.avg??0).filter(Number.isFinite);if(r.length<2)return``;let i=Math.min(...r),a=Math.max(...r)-i||1;return r.map((e,o)=>`${o/(r.length-1)*t},${n-(e-i)/a*n}`).join(` `)}async function Re(e){await k.rollbackOptimization(e),await F()}function I(e){return e==null?`--`:String(Number(e.toFixed(2)))}let yi=d(()=>{let e=new Map;for(let t of O.nodes)for(let n of t.deviceIds??(t.deviceBindingId?[t.deviceBindingId]:[]))e.set(n,(e.get(n)??0)+1);return ki.twins.filter(t=>e.has(t.id)).map(t=>({id:t.id,name:Ai.get(t.id)??t.name,count:e.get(t.id)}))});function bi(e){if(!A.lineRun)return!0;let t=!!e.lineId&&k.lineStateOf(e.lineId).active;return A.lineRun===`on`?t:!t}let L=d(()=>k.lines.find(e=>e.id===A.lineId)??null),R=d(()=>L.value?k.lineStateOf(L.value.id):null);function xi(e){if(!e.lastAt)return!0;let t=e.intervalMs??O.controller.defaultIntervalMs;return Date.now()-Date.parse(e.lastAt)>Math.max(t*4,12e3)}function Si(e){return e.enabled?e.lineId?k.lineStateOf(e.lineId).active?!O.controller.running||xi(e)?`offline`:e.state:`idle`:`unassigned`:`disabled`}let z=d(()=>O.nodes.filter(e=>{if(A.lineId&&(A.lineId===`none`?e.lineId:(e.lineId??``)!==A.lineId))return!1;let t=e.deviceIds??(e.deviceBindingId?[e.deviceBindingId]:[]);return!(A.deviceId&&(A.deviceId===`none`?t.length>0:!t.includes(A.deviceId))||A.template&&e.templateRef!==A.template||A.driver&&e.driver!==A.driver||!bi(e)||A.state&&Si(e)!==A.state||!Oe(e)||!ke(e))})),Ci=y(null),B=y(0),V=y(60),wi=d(()=>{let e=z.value,t=Math.min(B.value,Math.max(0,e.length-1));return e.slice(t,V.value)}),Ti=d(()=>B.value*_i),Ei=d(()=>Math.max(0,(z.value.length-V.value)*_i)),Di=0;function Oi(){let e=Ci.value;if(!e)return;let t=z.value.length,n=window.innerHeight||800,r=e.getBoundingClientRect().top+window.scrollY+40,i=Math.floor((window.scrollY-r)/_i),a=Math.ceil(n/_i)+16,o=Math.max(0,Math.min(i-vi,Math.max(0,t-1))),s=Math.max(o,Math.min(t,o+a));o!==B.value&&(B.value=o),s!==V.value&&(V.value=s)}function H(){Di||=requestAnimationFrame(()=>{Di=0,Oi()})}i(()=>{Oi(),window.addEventListener(`scroll`,H,{passive:!0}),window.addEventListener(`resize`,H,{passive:!0})}),r(()=>{window.removeEventListener(`scroll`,H),window.removeEventListener(`resize`,H),Di&&cancelAnimationFrame(Di)}),t(()=>z.value.length,()=>{B.value=0,V.value=Math.min(z.value.length,V.value||60),H()});let ki=he(),Ai=new Map;t(()=>ki.twins,e=>{for(let t of e)Ai.set(t.id,t.name)},{immediate:!0,deep:!0});let U=y(!1),W=y(`mock`),G=y(fe[0]?.key??`temp-tc`),K=y(`modbus-tcp`),q=y(``),ji=y(null),J=y({}),Mi=f({kind:`none`,scale:1,offset:0}),Ni=y(!1),Y=y(null),Pi=y(!1),Fi=y(``),Ii=d(()=>de.find(e=>e.kind===K.value)),Li=d(()=>Ii.value?.configFields??[]),Ri=e=>O.meta.drivers.find(t=>t.kind===e)?.status!==`planned`&&O.meta.driverAvailable?.[e]!==!1;t(K,()=>{let e={};for(let t of Li.value)t.default!==void 0&&(e[t.key]=t.default);J.value=e,Y.value=null},{immediate:!0});async function zi(){Ni.value=!0,Y.value=null;try{Y.value=await O.testDriver(K.value,J.value)}catch(e){Y.value={ok:!1,message:E(e)}}finally{Ni.value=!1}}async function Bi(){Pi.value=!0,Fi.value=``;try{let e=Mi.kind===`linear`?{kind:`linear`,scale:Number(Mi.scale),offset:Number(Mi.offset)}:void 0;if(W.value===`mock`)await O.createFromTemplate(`daq-${G.value}`,{name:q.value?{name:q.value}.name:void 0,transform:e});else{for(let e of Li.value)if(e.required&&!J.value[e.key]&&J.value[e.key]!==0)throw Error(T(`daq.kyuadl0125`,{p0:e.label}));let t=O.templates.find(e=>e.key===G.value);await O.createFromTemplate(`daq-${G.value}`,{name:q.value||void 0,driver:K.value,driverConfig:{...J.value},transform:e,intervalMs:ji.value,unit:t?.unit,min:t?.min,max:t?.max,decimals:t?.decimals})}U.value=!1,q.value=``,Y.value=null}catch(e){Fi.value=E(e)}finally{Pi.value=!1}}function Vi(e){let t=O.templates.find(t=>t.key===le(e));return t?`${t.name} · ${t.ch}`:e||`-`}let Hi=y(!1),X=y(null),Ui=y(!1),Z=y(``),Q=y(``),$=f({name:``,ch:``,code:``,unit:``,min:0,max:100,base:50,amp:2,decimals:2,icon:`thermo`}),Wi={thermo:T(`daq.k422b8079`),pressure:T(`daq.k3x6ff080`),tension:T(`daq.k3z9xc081`),encoder:T(`daq.k3subk4082`),camera:T(`daq.k47atw083`),gateway:T(`daq.kz7yhbj084`)},Gi=d(()=>O.templates.filter(e=>!e.builtin)),Ki=d(()=>O.templates.filter(e=>e.builtin));function qi(e,t=!1){$.name=t?T(`daq.k2hbo3c126`,{p0:e.name}):e.name,$.ch=e.ch,$.code=e.code,$.unit=e.unit,$.min=e.min,$.max=e.max,$.base=e.base,$.amp=e.amp,$.decimals=e.decimals,$.icon=e.icon}function Ji(){X.value=null,Z.value=``,Q.value=``,qi({key:``,name:``,code:``,ch:``,unit:``,base:50,amp:2,min:0,max:100,decimals:2,icon:`thermo`})}function Yi(e){X.value=e.key,Z.value=``,qi(e)}function Xi(e){X.value=null,Z.value=``,qi(e,!0)}async function Zi(){Ui.value=!0,Z.value=``;try{let e=e=>{let t=Number(e);return e===``||e==null||!Number.isFinite(t)?void 0:t},t={name:$.name.trim(),ch:$.ch.trim()||void 0,code:$.code.trim()||void 0,unit:$.unit.trim(),min:e($.min),max:e($.max),base:e($.base),amp:e($.amp),decimals:e($.decimals),icon:$.icon};X.value?await O.updateTemplate(X.value,t):await O.createTemplate(t),Ji()}catch(e){Z.value=E(e)}finally{Ui.value=!1}}async function Qi(e){if(Q.value!==e.key){Q.value=e.key;return}try{await O.removeTemplate(e.key)}catch(e){Z.value=E(e)}finally{Q.value=``}}let $i=y(!1);async function ea(){$i.value=!0;try{await O.reconnectInfra()}catch{}finally{$i.value=!1}}return(e,t)=>{let r=re,i=ze,a=ae;return s(),m(`div`,Be,[p(`div`,Ve,[p(`div`,null,[t[36]||=p(`p`,{class:`aw-kicker`},` AGENTWORKSHOP / DAQ CONSOLE `,-1),p(`h1`,null,o(e.$t(`daq.k1emg364011`)),1),p(`p`,He,o(e.$t(`daq.k1wmg2bz012`)),1)]),p(`div`,Ue,[p(`span`,{class:`badge`,title:e.$t(`daq.k1tsdbtip133`)},`TSDB · `+o(x(O).meta.tsdb),9,We),p(`span`,{class:`badge`,title:e.$t(`daq.k1queuet134`)},`QUEUE · `+o(x(O).meta.queue),9,Ge)])]),x(O).loaded&&L.value&&R.value?(s(),m(`div`,{key:0,class:c([`infra-banner`,{good:R.value.active}])},[p(`span`,{class:c(R.value.active?`i-tabler-circle-check`:`i-tabler-info-circle`)},null,2),p(`span`,Ke,[R.value.active?(s(),m(h,{key:0},[S(o(e.$t(`daq.k3ktxbr085`))+o(L.value.name)+`」`+o(e.$t(`daq.k15lvw0o105`)),1),p(`b`,null,o(R.value.productName),1),t[37]||=S(` · Recipe:`,-1),p(`b`,null,o(R.value.recipeName),1),p(`small`,qe,o(e.$t(`daq.k400lb086`))+` `+o(R.value.runId?.slice(0,8))+` · `+o(e.$t(`daq.k3zkt2106`))+` `+o(R.value.startedAt?.slice(11,19))+` `+o(e.$t(`daq.k69vag8108`))+` `+o(R.value.taggedSamples)+` `+o(e.$t(`daq.k4118o092`)),1)],64)):(s(),m(h,{key:1},[S(o(e.$t(`daq.k3ktxbr085`))+o(L.value.name)+`」`+o(e.$t(`daq.k12uge2o107`)),1)],64))]),u(r,{class:`pill-btn`,to:`/dcw/${L.value.id}`},{default:b(()=>[S(o(R.value.active?e.$t(`daq.k1ukoy0v093`):e.$t(`daq.k1cg78i8109`)),1)]),_:1},8,[`to`])],2)):x(O).loaded&&!_e.value?(s(),m(`div`,Je,[t[38]||=p(`span`,{class:`i-tabler-info-circle`},null,-1),p(`span`,Ye,[S(o(e.$t(`daq.k19onw5w013`)),1),u(r,{to:`/dcw`},{default:b(()=>[S(o(e.$t(`daq.k1b2tk5c014`)),1)]),_:1}),S(o(e.$t(`daq.k1u9wnlg015`)),1)])])):g(``,!0),x(O).meta.infra?.degraded?(s(),m(`div`,Xe,[t[39]||=p(`span`,{class:`i-tabler-alert-triangle`},null,-1),p(`span`,Ze,o(x(O).meta.infra.warning),1),p(`button`,{class:`pill-btn`,disabled:$i.value,onClick:ea},o($i.value?e.$t(`daq.k1ld43ur094`):e.$t(`daq.kzg9805110`)),9,Qe)])):g(``,!0),x(O).alarms.length?(s(),m(`div`,$e,[p(`span`,et,[t[40]||=p(`span`,{class:`i-tabler-bell-ringing bell`},null,-1),S(` `+o(e.$t(`daq.k1alarm141`))+` `,1),p(`b`,tt,o(x(O).alarms.length),1)]),p(`div`,nt,[(s(!0),m(h,null,l(x(O).alarms,t=>(s(),m(`span`,{key:t.id,class:`alarm-item`,title:e.$t(`daq.k1esc143`,{p0:t.escalation})},[p(`b`,null,o(t.nodeName),1),p(`span`,it,o(t.metric),1),p(`span`,at,o(t.value)+` `+o(t.rule===`lt-min`?`<`:`>`)+` `+o(t.threshold),1),t.escalation>0?(s(),m(`small`,ot,`+`+o(t.escalation),1)):g(``,!0),p(`button`,{class:`mini-btn ack`,onClick:e=>xe(t.id)},o(e.$t(`daq.k1ack142`)),9,st)],8,rt))),128))])])):g(``,!0),p(`section`,ct,[p(`div`,lt,[p(`div`,ut,[p(`button`,{class:c([`aw-pill`,{running:x(O).controller.running}]),title:e.$t(`daq.k1snap145`),onClick:t[0]||=e=>x(O).controllerAction(x(O).controller.running?`pause`:`resume`)},[p(`span`,{class:c(x(O).controller.running?`i-tabler-player-pause`:`i-tabler-player-play`)},null,2),S(` `+o(x(O).controller.running?e.$t(`daq.kpui00095`):e.$t(`daq.knxpdpt111`)),1)],10,dt),p(`label`,ft,[S(o(e.$t(`daq.k1ifahxj016`))+` `,1),_(p(`input`,{"onUpdate:modelValue":t[1]||=e=>x(O).controller.defaultIntervalMs=e,type:`number`,min:`200`,max:`60000`,step:`100`,onChange:t[2]||=e=>x(O).controllerAction(`config`,x(O).controller.defaultIntervalMs)},null,544),[[w,x(O).controller.defaultIntervalMs,void 0,{number:!0}]]),t[41]||=S(`ms `,-1)]),p(`label`,{class:`cycle mono`,title:e.$t(`daq.k1e8lcoo001`)},[S(o(e.$t(`daq.k1if98n0017`))+` `,1),_(p(`input`,{"onUpdate:modelValue":t[3]||=e=>x(O).controller.defaultPublishIntervalMs=e,type:`number`,min:`0`,max:`60000`,step:`100`,onChange:t[4]||=e=>x(O).controllerAction(`config`,x(O).controller.defaultIntervalMs,x(O).controller.defaultPublishIntervalMs)},null,544),[[w,x(O).controller.defaultPublishIntervalMs,void 0,{number:!0}]]),t[42]||=S(`ms `,-1)],8,pt)]),p(`div`,mt,[p(`span`,ht,[p(`span`,null,o(e.$t(`daq.k45uio067`))+` `+o(x(O).controller.nodesOnline)+`/`+o(x(O).controller.nodesTotal),1),t[43]||=p(`span`,{class:`sep`},`·`,-1),p(`span`,{title:e.$t(`daq.k1yztsu4002`)},o(e.$t(`daq.k3xagp087`))+` `+o(x(O).meta.produced),9,gt),t[44]||=p(`span`,{class:`sep`},`·`,-1),p(`span`,{title:e.$t(`daq.ko09iha003`)},o(e.$t(`daq.k427eu088`))+` `+o(x(O).meta.consumed),9,_t),t[45]||=p(`span`,{class:`sep`},`·`,-1),p(`span`,{class:c({warn:(x(O).meta.dropped??0)>0}),title:e.$t(`daq.k1droptip135`)},o(e.$t(`daq.k3w8go089`))+` `+o(x(O).meta.dropped),11,vt),t[46]||=p(`span`,{class:`sep`},`·`,-1),p(`span`,{title:e.$t(`daq.kj1jbmw004`)},o(e.$t(`daq.k3wusd090`))+` `+o(x(O).meta.samplesStored),9,yt)]),p(`button`,{class:`aw-pill outline add-btn`,onClick:t[5]||=e=>{Hi.value=!0,Ji()}},[t[47]||=p(`span`,{class:`i-tabler-adjustments-horizontal`},null,-1),S(` `+o(e.$t(`daq.k1f5cv0s018`)),1)]),p(`button`,{class:`aw-pill add-btn`,onClick:t[6]||=e=>U.value=!0},[t[48]||=p(`span`,{class:`i-tabler-plus`},null,-1),S(` `+o(e.$t(`daq.k1fn0ukb019`)),1)])])]),p(`div`,bt,[p(`span`,xt,[t[49]||=p(`span`,{class:`i-tabler-route`},null,-1),S(` `+o(e.$t(`daq.k1b2o3b6020`)),1),p(`small`,St,o(x(k).lines.length),1)]),p(`div`,Ct,[(s(!0),m(h,null,l(x(k).lines,i=>(s(),v(r,{key:i.id,class:c([`line-pill`,{on:x(k).lineStateOf(i.id).active}]),style:n({"--lc":i.color}),to:`/dcw/${i.id}`,title:x(k).lineStateOf(i.id).active?e.$t(`daq.k3v957u120`,{p0:i.name,p1:x(k).lineStateOf(i.id).productName,p2:x(k).lineStateOf(i.id).recipeName}):e.$t(`daq.k1x7jnru121`,{p0:i.name})},{default:b(()=>[t[50]||=p(`span`,{class:`lp-dot`},null,-1),p(`b`,null,o(i.name),1),x(k).lineStateOf(i.id).active?(s(),m(`small`,wt,o(x(k).lineStateOf(i.id).recipeName??e.$t(`daq.k3vp67i096`)),1)):(s(),m(`small`,Tt,o(e.$t(`daq.k3zgkk021`)),1))]),_:2},1032,[`class`,`style`,`to`,`title`]))),128)),x(k).lines.length===0?(s(),v(r,{key:0,class:`line-pill`,to:`/dcw`},{default:b(()=>[t[51]||=p(`span`,{class:`lp-dot`},null,-1),p(`b`,null,o(e.$t(`daq.k1el12b1022`)),1),p(`small`,Et,o(e.$t(`daq.k8jxxe8023`)),1)]),_:1})):g(``,!0)])])]),U.value?(s(),m(`div`,{key:4,class:`modal-mask`,onClick:t[14]||=ee(e=>U.value=!1,[`self`])},[p(`div`,Dt,[p(`h3`,Ot,o(e.$t(`daq.k19rioqa024`)),1),p(`div`,kt,[p(`button`,{class:c([`seg`,{on:W.value===`mock`}]),onClick:t[7]||=e=>W.value=`mock`},o(e.$t(`daq.k1p5c1un025`)),3),p(`button`,{class:c([`seg`,{on:W.value===`real`}]),onClick:t[8]||=e=>W.value=`real`},o(e.$t(`daq.k1cbcp3o026`)),3)]),p(`div`,At,[p(`label`,jt,[p(`span`,null,o(e.$t(`daq.k1fsgerc027`)),1),_(p(`select`,{"onUpdate:modelValue":t[9]||=e=>G.value=e,class:`inp`},[(s(!0),m(h,null,l(x(O).templates,t=>(s(),m(`option`,{key:t.key,value:t.key},o(t.name)+` · `+o(t.ch)+`(`+o(t.min)+`~`+o(t.max)+` `+o(t.unit)+`)`+o(t.builtin?``:e.$t(`daq.kr45rk9097`)),9,Mt))),128))],512),[[C,G.value]])]),p(`label`,Nt,[p(`span`,null,o(e.$t(`daq.k1ce2k1y028`)),1),_(p(`input`,{"onUpdate:modelValue":t[10]||=e=>q.value=e,class:`inp`,placeholder:e.$t(`daq.kgpxzy3005`)},null,8,Pt),[[w,q.value]])]),W.value===`real`?(s(),m(`label`,Ft,[p(`span`,null,o(e.$t(`daq.k13mfsfc029`)),1),_(p(`input`,{"onUpdate:modelValue":t[11]||=e=>ji.value=e,type:`number`,min:`1000`,max:`60000`,step:`500`,class:`inp`,placeholder:e.$t(`daq.k1eg1000a136`)},null,8,It),[[w,ji.value,void 0,{number:!0}]])])):g(``,!0)]),W.value===`real`?(s(),m(h,{key:0},[p(`div`,Lt,[p(`label`,Rt,[p(`span`,null,o(e.$t(`daq.k1kt87rx030`)),1),_(p(`select`,{"onUpdate:modelValue":t[12]||=e=>K.value=e,class:`inp`},[(s(!0),m(h,null,l(x(de).filter(e=>e.status!==`planned`),t=>(s(),m(`option`,{key:t.kind,value:t.kind},o(t.label)+o(Ri(t.kind)?``:e.$t(`daq.kjbqphp098`)),9,zt))),128))],512),[[C,K.value]])])]),Li.value.length?(s(),m(`div`,Bt,[(s(!0),m(h,null,l(Li.value,e=>(s(),m(`label`,{key:e.key,class:`f`},[p(`span`,null,[S(o(e.label),1),e.required?(s(),m(`em`,Vt,`*`)):g(``,!0)]),e.type===`select`?_((s(),m(`select`,{key:0,"onUpdate:modelValue":t=>J.value[e.key]=t,class:`inp`},[(s(!0),m(h,null,l(e.options,e=>(s(),m(`option`,{key:e.value,value:e.value},o(e.label),9,Ut))),128))],8,Ht)),[[C,J.value[e.key]]]):_((s(),m(`input`,{key:1,"onUpdate:modelValue":t=>J.value[e.key]=t,type:e.type===`number`?`number`:`text`,placeholder:e.placeholder,class:`inp`},null,8,Wt)),[[te,J.value[e.key]]]),e.hint?(s(),m(`small`,Gt,o(e.hint),1)):g(``,!0)]))),128))])):g(``,!0),p(`div`,Kt,[p(`button`,{class:`pill-btn`,disabled:Ni.value,onClick:zi},o(Ni.value?e.$t(`daq.k1fsh720099`):e.$t(`daq.k1fstglk112`)),9,qt),Y.value?(s(),m(`span`,{key:0,class:c([`test-result`,Y.value.ok?`ok`:`bad`])},[S(o(Y.value.ok?`✓`:`✗`)+` `+o(Y.value.message),1),Y.value.latencyMs==null?g(``,!0):(s(),m(h,{key:0},[S(`(`+o(Y.value.latencyMs)+`ms)`,1)],64))],2)):g(``,!0)])],64)):g(``,!0),Fi.value?(s(),m(`p`,Jt,o(Fi.value),1)):g(``,!0),p(`div`,Yt,[p(`button`,{class:`aw-pill outline`,onClick:t[13]||=e=>U.value=!1},o(e.$t(`daq.k3xdnn031`)),1),p(`button`,{class:`aw-pill`,disabled:Pi.value||W.value===`real`&&Y.value!=null&&!Y.value.ok,title:W.value===`real`&&!(Y.value&&Y.value.ok)?e.$t(`daq.k1needtst137`):``,onClick:Bi},o(Pi.value?e.$t(`daq.k1bg4759100`):W.value===`real`?e.$t(`daq.k7pxjxo113`):e.$t(`daq.k1bge46t118`)),9,Xt)])])])):g(``,!0),Hi.value?(s(),m(`div`,{key:5,class:`modal-mask`,onClick:t[25]||=ee(e=>Hi.value=!1,[`self`])},[p(`div`,Zt,[p(`h3`,Qt,o(e.$t(`daq.k11mv96s032`)),1),p(`p`,$t,o(e.$t(`daq.ktji4ky033`)),1),p(`table`,en,[p(`tbody`,null,[(s(!0),m(h,null,l(Gi.value,t=>(s(),m(`tr`,{key:t.key},[p(`td`,null,[p(`b`,null,o(t.name),1),p(`small`,tn,o(t.code),1)]),p(`td`,nn,o(t.min)+`~`+o(t.max)+` `+o(t.unit)+` · `+o(t.decimals)+` `+o(e.$t(`daq.k48oi091`)),1),p(`td`,rn,[p(`button`,{class:`mini-btn`,onClick:e=>Yi(t)},o(e.$t(`daq.k45eb0034`)),9,an),p(`button`,{class:`mini-btn danger`,onClick:e=>Qi(t)},o(Q.value===t.key?e.$t(`daq.k1hhheu3101`):e.$t(`daq.k3xakp114`)),9,on)])]))),128)),Gi.value.length?g(``,!0):(s(),m(`tr`,sn,[p(`td`,cn,o(e.$t(`daq.kztvzbo035`)),1)]))])]),p(`p`,ln,o(X.value?e.$t(`daq.k1iiph0s102`):e.$t(`daq.k1efixrj115`)),1),p(`div`,un,[p(`label`,dn,[p(`span`,null,[S(o(e.$t(`daq.k3xhia036`)),1),t[52]||=p(`em`,null,`*`,-1)]),_(p(`input`,{"onUpdate:modelValue":t[15]||=e=>x($).name=e,class:`inp`,placeholder:e.$t(`daq.k5opd2t006`)},null,8,fn),[[w,x($).name]])]),p(`label`,pn,[p(`span`,null,[S(o(e.$t(`daq.k3x4ef037`)),1),t[53]||=p(`em`,null,`*`,-1)]),_(p(`input`,{"onUpdate:modelValue":t[16]||=e=>x($).unit=e,class:`inp`,placeholder:`如 %RH`},null,512),[[w,x($).unit]])]),p(`label`,mn,[p(`span`,null,o(e.$t(`daq.k1l477m0038`)),1),_(p(`input`,{"onUpdate:modelValue":t[17]||=e=>x($).ch=e,class:`inp`,placeholder:e.$t(`daq.kk8o4tl007`)},null,8,hn),[[w,x($).ch]])]),p(`label`,gn,[p(`span`,null,o(e.$t(`daq.k1ayxrqb039`)),1),_(p(`input`,{"onUpdate:modelValue":t[18]||=e=>x($).code=e,class:`inp`,placeholder:e.$t(`daq.kzn3l7l008`)},null,8,_n),[[w,x($).code]])]),p(`label`,vn,[p(`span`,null,[S(o(e.$t(`daq.k1l9jv5m040`)),1),t[54]||=p(`em`,null,`*`,-1)]),_(p(`input`,{"onUpdate:modelValue":t[19]||=e=>x($).min=e,type:`number`,class:`inp`},null,512),[[w,x($).min,void 0,{number:!0}]])]),p(`label`,yn,[p(`span`,null,[S(o(e.$t(`daq.k1l9jv4p041`)),1),t[55]||=p(`em`,null,`*`,-1)]),_(p(`input`,{"onUpdate:modelValue":t[20]||=e=>x($).max=e,type:`number`,class:`inp`},null,512),[[w,x($).max,void 0,{number:!0}]])]),p(`label`,bn,[p(`span`,null,o(e.$t(`daq.k3mxmcx042`)),1),_(p(`input`,{"onUpdate:modelValue":t[21]||=e=>x($).decimals=e,type:`number`,min:`0`,max:`4`,class:`inp`},null,512),[[w,x($).decimals,void 0,{number:!0}]])]),p(`label`,xn,[p(`span`,null,o(e.$t(`daq.k3xx56043`)),1),_(p(`select`,{"onUpdate:modelValue":t[22]||=e=>x($).icon=e,class:`inp`},[(s(!0),m(h,null,l(x(ue),e=>(s(),m(`option`,{key:e,value:e},o(Wi[e]),9,Sn))),128))],512),[[C,x($).icon]])]),p(`label`,Cn,[p(`span`,null,o(e.$t(`daq.k1f4eknv044`)),1),_(p(`input`,{"onUpdate:modelValue":t[23]||=e=>x($).base=e,type:`number`,class:`inp`},null,512),[[w,x($).base,void 0,{number:!0}]]),p(`small`,wn,o(e.$t(`daq.kytd15s045`)),1)]),p(`label`,Tn,[p(`span`,null,o(e.$t(`daq.k1f4ifpo046`)),1),_(p(`input`,{"onUpdate:modelValue":t[24]||=e=>x($).amp=e,type:`number`,class:`inp`},null,512),[[w,x($).amp,void 0,{number:!0}]]),p(`small`,En,o(e.$t(`daq.ksp2aji047`)),1)])]),Z.value?(s(),m(`p`,Dn,o(Z.value),1)):g(``,!0),p(`div`,On,[p(`button`,{class:`aw-pill outline`,onClick:Ji},o(e.$t(`daq.k48p40048`)),1),p(`button`,{class:`pill-btn`,disabled:Ui.value,onClick:Zi},o(Ui.value?e.$t(`daq.k1b38d59103`):X.value?e.$t(`daq.k1b39281116`):e.$t(`daq.k1b3dtga119`)),9,kn)]),p(`p`,An,o(e.$t(`daq.k1w8s84s049`)),1),p(`table`,jn,[p(`tbody`,null,[(s(!0),m(h,null,l(Ki.value,t=>(s(),m(`tr`,{key:t.key},[p(`td`,null,[p(`b`,null,o(t.name),1),p(`small`,Mn,o(t.code),1)]),p(`td`,Nn,o(t.min)+`~`+o(t.max)+` `+o(t.unit)+` · `+o(t.decimals)+` `+o(e.$t(`daq.k48oi091`)),1),p(`td`,Pn,[p(`button`,{class:`mini-btn`,onClick:e=>Xi(t)},o(e.$t(`daq.k3y694050`)),9,Fn)])]))),128))])])])])):g(``,!0),p(`section`,In,[p(`button`,{class:`opt-head`,onClick:Pe},[t[56]||=p(`span`,{class:`i-tabler-flask`},null,-1),p(`b`,null,o(e.$t(`daq.k1optt001`)),1),p(`span`,Ln,o(x(k).optimizations.length),1),p(`span`,{class:c([`opt-chevron`,{open:j.value}])},null,2)]),p(`div`,{class:c([`opt-body`,{open:j.value}])},[Ae.value?(s(),m(h,{key:0},[p(`div`,Rn,[_(p(`select`,{"onUpdate:modelValue":t[26]||=e=>M.value=e,class:`inp-sel`,onChange:Fe},[p(`option`,zn,o(e.$t(`daq.k1optf001`)),1),(s(!0),m(h,null,l(x(k).lines,e=>(s(),m(`option`,{key:e.id,value:e.id},o(e.name),9,Bn))),128))],544),[[C,M.value]]),_(p(`select`,{"onUpdate:modelValue":t[27]||=e=>N.value=e,class:`inp-sel`,onChange:F},[p(`option`,Vn,o(e.$t(`daq.k1optf004`)),1),(s(!0),m(h,null,l(Me.value,e=>(s(),m(`option`,{key:e.id,value:e.id},o(e.name),9,Hn))),128))],544),[[C,N.value]]),p(`button`,{class:`mini-act`,onClick:F},o(e.$t(`daq.k1optf002`)),1)]),x(k).optimizations.length===0?(s(),m(`p`,Un,o(e.$t(`daq.k1opte001`)),1)):g(``,!0),p(`ul`,Wn,[(s(!0),m(h,null,l(x(k).optimizations.slice(0,30),t=>(s(),m(`li`,{key:t.id,class:c([`opt-row`,t.status])},[p(`div`,Gn,[p(`span`,{class:c([`opt-status`,t.status])},o(e.$t(Ne(t.status))),3),p(`b`,Kn,o(t.nodeName),1),p(`span`,qn,o(t.params[0]?.from??`?`)+` → `+o(t.params[0]?.to),1),p(`span`,Jn,o(t.setAt.slice(5,16).replace(`T`,` `)),1),P.value[t.id]?g(``,!0):(s(),m(`button`,{key:0,class:`mini-act`,disabled:je.value===t.id,onClick:e=>Ie(t.id)},o(e.$t(`daq.k1opta001`)),9,Yn)),t.status===`open`?(s(),m(`button`,{key:1,class:`mini-act danger`,onClick:e=>Re(t.id)},o(e.$t(`daq.k1opta002`)),9,Xn)):g(``,!0)]),p(`div`,Zn,[t.judge?(s(),m(`span`,{key:0,class:c([`opt-judge`,t.judge.verdict])},o(t.judge.verdict)+`(`+o(t.judge.by)+`): `+o(t.judge.reason.slice(0,70)),3)):t.status===`open`?(s(),m(`span`,Qn,o(e.$t(`daq.k1opto001`)),1)):g(``,!0),t.aggPending?(s(),m(`span`,$n,o(e.$t(`daq.k1optw001`)),1)):t.windowAgg&&t.windowAgg.channels.length?(s(),m(`span`,er,[(s(!0),m(h,null,l(t.windowAgg.channels,t=>(s(),m(h,{key:t.daqNodeId},[S(o(t.ch)+` `+o(I(t.min))+`~`+o(I(t.max))+`(`+o(e.$t(`daq.k1optw002`))+o(t.breaches<0?`-`:t.breaches)+`) `,1)],64))),128))])):g(``,!0)]),P.value[t.id]?(s(),m(`div`,tr,[(s(!0),m(h,null,l(P.value[t.id]?.channels??[],e=>(s(),m(`div`,{key:e.nodeId,class:`opt-ch`},[(s(),m(`svg`,nr,[p(`polyline`,{points:Le(e.points)},null,8,rr)])),p(`span`,ir,o(e.ch)+` `+o(I(e.points.at(-1)?.value??e.points.at(-1)?.avg))+o(e.unit),1)]))),128)),(P.value[t.id]?.channels.length??0)===0?(s(),m(`p`,ar,o(e.$t(`daq.k1opte002`)),1)):g(``,!0)])):g(``,!0)],2))),128))])],64)):g(``,!0)],2)]),u(a,{spinning:!x(O).loaded&&!x(O).error},{default:b(()=>[p(`section`,or,[p(`div`,sr,[p(`div`,cr,[p(`label`,lr,[p(`span`,null,o(e.$t(`daq.k3wj9n051`)),1),_(p(`select`,{"onUpdate:modelValue":t[28]||=e=>x(A).lineId=e,class:`inp-sel`},[p(`option`,ur,o(e.$t(`daq.k1bkl9uj052`)),1),(s(!0),m(h,null,l(x(k).lines,e=>(s(),m(`option`,{key:e.id,value:e.id},o(e.name),9,dr))),128)),p(`option`,fr,o(e.$t(`daq.k3ootr6053`)),1)],512),[[C,x(A).lineId]])]),p(`label`,pr,[p(`span`,null,o(e.$t(`daq.k1i8rtqt054`)),1),_(p(`select`,{"onUpdate:modelValue":t[29]||=e=>x(A).deviceId=e,class:`inp-sel`},[p(`option`,mr,o(e.$t(`daq.k1bkw4m2055`)),1),(s(!0),m(h,null,l(yi.value,e=>(s(),m(`option`,{key:e.id,value:e.id},o(e.name)+`(`+o(e.count)+`) `,9,hr))),128)),p(`option`,gr,o(e.$t(`daq.k3own4q056`)),1)],512),[[C,x(A).deviceId]])]),p(`label`,{class:`flt`,title:e.$t(`daq.khb8mru009`)},[p(`span`,null,o(e.$t(`daq.k1b2tkyv057`)),1),_(p(`select`,{"onUpdate:modelValue":t[30]||=e=>x(A).lineRun=e,class:`inp-sel`},[p(`option`,vr,o(e.$t(`daq.k3x4t1058`)),1),p(`option`,yr,o(e.$t(`daq.k1nxm3p7059`)),1),p(`option`,br,o(e.$t(`daq.k1ulx34e060`)),1)],512),[[C,x(A).lineRun]])],8,_r),p(`label`,xr,[p(`span`,null,o(e.$t(`daq.k1iwdfef061`)),1),_(p(`select`,{"onUpdate:modelValue":t[31]||=e=>x(A).state=e,class:`inp-sel`},[p(`option`,Sr,o(e.$t(`daq.k3x4t1058`)),1),p(`option`,Cr,o(e.$t(`daq.k41k5c062`)),1),p(`option`,wr,o(e.$t(`daq.k49z8v063`)),1),p(`option`,Tr,o(e.$t(`daq.k3xmid064`)),1),p(`option`,Er,o(e.$t(`daq.k44c2n065`)),1)],512),[[C,x(A).state]])]),p(`label`,Dr,[p(`span`,null,o(e.$t(`daq.k1flttpl010`)),1),_(p(`select`,{"onUpdate:modelValue":t[32]||=e=>x(A).template=e,class:`inp-sel`},[p(`option`,Or,o(e.$t(`daq.k1flttpl011`)),1),(s(!0),m(h,null,l(Te.value,e=>(s(),m(`option`,{key:e.ref,value:e.ref},o(e.label)+`(`+o(e.count)+`) `,9,kr))),128))],512),[[C,x(A).template]])]),p(`label`,Ar,[p(`span`,null,o(e.$t(`daq.k1fltdrv012`)),1),_(p(`select`,{"onUpdate:modelValue":t[33]||=e=>x(A).driver=e,class:`inp-sel`},[p(`option`,jr,o(e.$t(`daq.k1fltdrv013`)),1),(s(!0),m(h,null,l(Ee.value,e=>(s(),m(`option`,{key:e.kind,value:e.kind},o(e.label)+`(`+o(e.count)+`) `,9,Mr))),128))],512),[[C,x(A).driver]])]),p(`label`,{class:`flt`,title:e.$t(`daq.k1flttim014`)},[p(`span`,null,o(e.$t(`daq.k1flttim015`)),1),_(p(`select`,{"onUpdate:modelValue":t[34]||=e=>x(A).time=e,class:`inp-sel`},[p(`option`,Pr,o(e.$t(`daq.k1flttim016`)),1),p(`option`,Fr,o(e.$t(`daq.k1timlv017`)),1),p(`option`,Ir,o(e.$t(`daq.k1timhr018`)),1),p(`option`,Lr,o(e.$t(`daq.k1timdy019`)),1),p(`option`,Rr,o(e.$t(`daq.k1timld020`)),1),p(`option`,zr,o(e.$t(`daq.k1timnv021`)),1)],512),[[C,x(A).time]])],8,Nr),p(`label`,Br,[p(`span`,null,o(e.$t(`daq.k1fltsrc022`)),1),_(p(`input`,{"onUpdate:modelValue":t[35]||=e=>x(A).search=e,class:`inp-sel flt-search`,type:`search`,placeholder:e.$t(`daq.k1fltsph023`)},null,8,Vr),[[w,x(A).search]])]),Ce.value?(s(),m(`button`,{key:0,class:`mini-btn clear-btn`,onClick:we},o(e.$t(`daq.k1fygck2066`)),1)):g(``,!0)]),p(`span`,Hr,o(z.value.length)+` / `+o(x(O).nodes.length)+` `+o(e.$t(`daq.k45uio067`)),1)]),p(`div`,Ur,[p(`div`,{class:c([`ops-panel alarm-panel`,{live:x(O).alarms.length>0}])},[p(`div`,Wr,[t[57]||=p(`span`,{class:`i-tabler-bell-ringing bell`},null,-1),p(`b`,null,o(e.$t(`daq.k1alarm141`)),1),p(`span`,{class:c([`mono cnt`,{hot:x(O).alarms.length>0}])},o(x(O).alarms.length),3)]),p(`div`,Gr,[x(O).alarms.length===0?(s(),m(`p`,Kr,o(e.$t(`daq.k1evt001`)),1)):(s(!0),m(h,{key:1},l(x(O).alarms,n=>(s(),m(`div`,{key:n.id,class:`alarm-row`},[t[58]||=p(`span`,{class:`i-tabler-alert-triangle tri`},null,-1),p(`b`,null,o(n.nodeName),1),p(`span`,qr,o(n.metric),1),p(`span`,Jr,o(n.value)+` `+o(n.rule===`lt-min`?`<`:`>`)+` `+o(n.threshold),1),n.escalation>0?(s(),m(`small`,Yr,`+`+o(n.escalation),1)):g(``,!0),p(`button`,{class:`mini-btn ack`,onClick:e=>xe(n.id)},o(e.$t(`daq.k1ack142`)),9,Xr)]))),128))])],2),p(`div`,Zr,[p(`div`,Qr,[t[60]||=p(`span`,{class:`i-tabler-activity`},null,-1),p(`b`,null,o(e.$t(`daq.k1evt002`)),1),u(r,{class:`panel-link`,to:`/logs`},{default:b(()=>[S(o(e.$t(`daq.k1evt003`)),1),t[59]||=p(`span`,{class:`i-tabler-arrow-right`},null,-1)]),_:1})]),p(`div`,$r,[x(ve).recent.length===0?(s(),m(`p`,ei,o(e.$t(`daq.k1evt004`)),1)):(s(!0),m(h,{key:1},l(x(ve).recent,(t,n)=>(s(),m(`div`,{key:`${t.at}:${t.actor}:${t.action}:${n}`,class:`evt-row`},[p(`span`,ti,o(be(t.at)),1),p(`span`,{class:c([`src-badge`,t.actorKind])},o(t.actorKind===`agent`?`Agent`:t.actorKind===`user`?e.$t(`logs.src.user`):e.$t(`logs.src.system`)),3),p(`span`,{class:c([`kind-chip`,t.kind])},o(ye(t.kind)),3),p(`span`,{class:`txt`,title:t.summary},o(t.summary),9,ni)]))),128))])])]),p(`table`,{ref_key:`nodesTableRef`,ref:Ci,class:`nodes-table`},[p(`thead`,null,[p(`tr`,null,[p(`th`,null,o(e.$t(`daq.k45uio067`)),1),p(`th`,null,o(e.$t(`daq.k42w8s068`)),1),p(`th`,null,o(e.$t(`daq.k3mv305069`)),1),p(`th`,null,o(e.$t(`daq.k1trnd001`)),1),p(`th`,null,o(e.$t(`daq.k1l6g2ga070`)),1),p(`th`,null,o(e.$t(`daq.k3zi0nf071`)),1),p(`th`,null,o(e.$t(`daq.k4a0la072`)),1),p(`th`,null,o(e.$t(`daq.k3wj9n051`)),1),p(`th`,{title:e.$t(`daq.k1runtipc131`)},o(e.$t(`daq.k1b2tkyv057`)),9,ri),p(`th`,{title:e.$t(`daq.k1prdrtip132`)},o(e.$t(`daq.k1prodrc128`)),9,ii),p(`th`,null,o(e.$t(`daq.k1i8rtqt054`)),1),p(`th`,ai,o(e.$t(`daq.k40aa6073`)),1)])]),p(`tbody`,null,[Ti.value>0?(s(),m(`tr`,oi,[p(`td`,{colspan:11,style:n({height:Ti.value+`px`})},null,4)])):g(``,!0),(s(!0),m(h,null,l(wi.value,e=>(s(),v(i,{key:e.id,n:e},null,8,[`n`]))),128)),Ei.value>0?(s(),m(`tr`,si,[p(`td`,{colspan:11,style:n({height:Ei.value+`px`})},null,4)])):g(``,!0),x(O).loaded&&x(O).nodes.length===0?(s(),m(`tr`,ci,[p(`td`,li,[p(`div`,ui,[p(`p`,di,o(e.$t(`daq.kvhjyc3075`)),1)])])])):x(O).loaded&&z.value.length===0?(s(),m(`tr`,fi,[p(`td`,pi,[p(`div`,mi,[p(`p`,hi,o(e.$t(`daq.k1w20qew076`)),1)])])])):g(``,!0)])],512)])]),_:1},8,[`spinning`]),x(O).error?(s(),m(`p`,gi,[S(o(x(O).error)+`(`,1),u(r,{to:`/workshop`},{default:b(()=>[S(o(e.$t(`daq.k1bhhheq077`)),1)]),_:1}),t[61]||=S(`) `,-1)])):g(``,!0)])}}}),[[`__scopeId`,`data-v-8252d58d`]]);export{yi as default};
@@ -1 +0,0 @@
1
- import{$ as e,P as t,R as n,S as r,Ut as i,V as a,Vt as o,W as s,b as c,d as l,dt as ee,f as u,h as d,i as f,m as p,nt as m,pt as h,tt as te,xt as g,y as _}from"./CSkxz2NX.js";import{c as v,f as ne,l as y,s as re}from"./D6uzXueg.js";import{a as ie}from"./C__m4EhR.js";import{t as ae}from"./BHA40aHa.js";import{n as oe}from"./KZQX7xoM.js";import{t as se}from"./CWoJjWmZ.js";import{t as b}from"./BDNMzG2s2.js";import{t as ce}from"./D0ZBQrN_2.js";import{t as le}from"./CNs_Ozdc2.js";import{a as ue,n as x,t as de}from"./DcsCcxp4.js";import{t as fe}from"./D8qvkfyY.js";import{t as pe}from"./C3J6FYKa.js";var me={class:`page`},he={class:`aw-kicker`},ge={class:`aw-page-head`},_e={key:0,class:`err`},ve={key:1,class:`grid`},ye={class:`col-live`},be={class:`aw-tile value-card`},xe={class:`aw-kicker`},Se={class:`big-val mono`},Ce={class:`facts mono`},we={class:`col-form aw-tile pad`},Te={class:`sec`},Ee={class:`field`},De={class:`field`},Oe={value:``},ke=[`value`],Ae={class:`field`},je=[`value`,`disabled`],Me={class:`field row`},Ne=[`disabled`],Pe={class:`field row`},Fe=[`disabled`],Ie=[`disabled`],Le={class:`field row`},Re=[`disabled`],ze={class:`field`},Be={class:`field`},Ve={class:`field-row`},He={class:`field`},Ue={class:`field`},We={class:`field`},Ge={class:`field`},Ke=[`disabled`],qe={class:`sec mt`},Je={class:`driver-grid`},Ye={key:0},Xe=[`onUpdate:modelValue`],Ze=[`value`],Qe=[`onUpdate:modelValue`,`type`,`placeholder`],$e={class:`test-row`},et=[`disabled`],tt={class:`sec mt`},nt={class:`bind-row`},rt={value:``},it=[`value`],at={class:`col-hist aw-tile pad`},ot={class:`hist-hd`},st={class:`sec`},ct={class:`hist-ctl mono`},lt=[`value`],ut=[`title`],dt=[`placeholder`],ft={class:`raw-table mono`},pt={key:2,class:`aw-tile pad frames-tile`},mt={class:`hist-hd`},ht={class:`sec`},gt={class:`mono frames-n`},_t=[`viewBox`],vt=[`points`],yt={class:`raw-table mono`},bt={key:0,class:`gal`},xt=[`title`,`onClick`],St=[`src`],Ct={class:`mono`},wt={key:1,class:`frames-empty`},Tt=[`src`],S=320,Et=84,Dt=`#35e0a0`,Ot=`rgba(120,135,160,0.18)`,kt=`rgba(140,155,175,0.8)`,At=b(r({__name:`[id]`,setup(r){let{t:b}=oe();le({layout:`default`});let At=ie(),C=l(()=>String(At.params.id??``)),w=de(),jt=fe();jt.load();let T=pe(),E=l(()=>w.nodeById(C.value)??null),D=l(()=>{let e=E.value?ue(E.value.templateRef):``;return w.templates.find(t=>t.key===e)??null}),Mt={ok:b(`daqDetail.k41k5c026`),warn:b(`daqDetail.k49z8v027`),alarm:b(`daqDetail.k3xmid028`),offline:b(`daqDetail.k44c2n029`)},O=()=>{let e=E.value;return!e||!w.controller.running||!e.enabled?`offline`:e.state},Nt=null;n(()=>{Nt=w.ensureWsFeed(),w.load(),T.load(),A.value&&M()}),t(()=>Nt?.());let k=l(()=>D.value?.signalKind??`scalar`),A=l(()=>k.value!==`scalar`),j=l(()=>w.framesOf(C.value));async function M(){C.value&&await w.fetchFrames(C.value,{limit:24}).catch(()=>{})}e(C,()=>{A.value&&M()});let Pt=e=>new Date(e).toLocaleTimeString(`zh-CN`,{hour12:!1}),Ft=e=>Object.entries(e.metrics??{}).slice(0,3).map(([e,t])=>`${e}=${t}`).join(` `),It=l(()=>j.value.find(e=>e.kind===`vector`&&e.points?.length)),Lt=l(()=>{let e=It.value?.points??[];if(e.length<2)return``;let t=Math.min(...e),n=Math.max(...e)-t||1;return e.map((r,i)=>`${(i/(e.length-1)*S).toFixed(1)},${(78-(r-t)/n*72).toFixed(1)}`).join(` `)}),N=h(null);function Rt(e){return e==null?b(`daqDetail.k9vnp9h053`,{p0:w.controller.defaultPublishIntervalMs}):e===0?b(`daqDetail.k1m1zwux030`):`${e}ms`}let P=ee({enabled:!0,driver:`mock`,lineId:``,followGlobal:!0,intervalMs:5e3,calKind:`none`,calScale:1,calOffset:0,publishFollow:!0,publishEveryFrame:!1,publishMs:1e3,unit:``,decimals:1,min:0,max:100,warnLow:null,warnHigh:null});e(E,e=>{e&&(P.enabled=e.enabled,P.lineId=e.lineId??``,P.driver=e.driver,P.followGlobal=e.intervalMs==null,P.intervalMs=e.intervalMs??w.controller.defaultIntervalMs,P.publishFollow=e.publishIntervalMs==null,P.publishEveryFrame=e.publishIntervalMs===0,P.publishMs=e.publishIntervalMs==null?w.controller.defaultPublishIntervalMs:e.publishIntervalMs,P.unit=e.unit,P.decimals=e.decimals,P.min=e.min,P.max=e.max,P.warnLow=e.warnLow,P.warnHigh=e.warnHigh)},{immediate:!0});let F=h({}),I=l(()=>x.find(e=>e.kind===P.driver)?.configFields??[]);e(E,e=>{e&&(F.value={...e.driverConfig})},{immediate:!0}),e(()=>P.driver,()=>{if(I.value.length&&Object.keys(F.value).length===0){let e={};for(let t of I.value)t.default!==void 0&&(e[t.key]=t.default);F.value=e}},{immediate:!0});let L=h(!1),R=h(null);async function zt(){L.value=!0,R.value=null;try{await w.patchNode(C.value,{driver:P.driver,driverConfig:{...F.value}}),R.value=await w.testNode(C.value)}catch(e){R.value={ok:!1,message:ce(e)}}finally{L.value=!1}}let z=h(!1);async function Bt(){let e=E.value;if(!(!e||z.value)){z.value=!0;try{await w.patchNode(e.id,{enabled:P.enabled,driver:P.driver,lineId:P.lineId,driverConfig:{...F.value},intervalMs:P.followGlobal?null:Math.max(1e3,Math.min(6e4,Math.round(P.intervalMs))),publishIntervalMs:P.publishFollow?null:P.publishEveryFrame?0:Math.max(0,Math.min(6e4,Math.round(P.publishMs))),unit:P.unit,decimals:Math.max(0,Math.min(6,Math.round(P.decimals))),min:P.min,max:P.max,warnLow:P.warnLow,warnHigh:P.warnHigh})}finally{z.value=!1}}}function Vt(e){return w.meta.drivers.find(t=>t.kind===e)?.status===`planned`}let B=h(``),Ht=l(()=>(E.value?.deviceIds??(E.value?.deviceBindingId?[E.value.deviceBindingId]:[])).map(e=>T.twins.find(t=>t.id===e)?.name??`${e.slice(0,8)}…`).join(` / `));function Ut(){w.bindNode(C.value,E.value?.deviceBindingId?null:B.value||null)}let Wt=l(()=>T.twins.filter(e=>e.kind!==`daq`&&e.id!==E.value?.id)),V=h([]),H=h(15e3),U=h(!1),Gt=[{label:`1s 桶`,ms:1e3},{label:`5s 桶`,ms:5e3},{label:`15s 桶(默认)`,ms:15e3},{label:`30s 桶`,ms:3e4},{label:`1min 桶`,ms:6e4}];async function W(){if(C.value){U.value=!0;try{let e=await w.samplesOf(C.value,{toMs:Date.now(),bucketMs:H.value||void 0,limit:400});V.value=[...e].reverse()}finally{U.value=!1,qt()}}}let Kt=h(null);function qt(){let e=Kt.value;if(!e)return;let t=Math.min(window.devicePixelRatio||1,2),n=e.clientWidth,r=e.clientHeight;(e.width!==n*t||e.height!==r*t)&&(e.width=n*t,e.height=r*t);let i=e.getContext(`2d`);if(!i)return;i.setTransform(t,0,0,t,0,0),i.clearRect(0,0,n,r);for(let e=1;e<4;e++)i.strokeStyle=Ot,i.beginPath(),i.moveTo(0,r/4*e),i.lineTo(n,r/4*e),i.stroke();let a=V.value;if(a.length<2)return;let o=1/0,s=-1/0;for(let e of a){let t=e.value??e.avg??e.min??0;o=Math.min(o,t),s=Math.max(s,t)}let c=Math.max(s-o,1e-9);i.strokeStyle=kt,i.font=`10px monospace`,i.fillStyle=kt,i.fillText(s.toFixed(2),4,11),i.fillText(o.toFixed(2),4,r-4),i.strokeStyle=Dt,i.lineWidth=1.6,i.beginPath(),a.forEach((e,t)=>{let s=t/(a.length-1)*n,l=r-((e.value??e.avg??0)-o)/c*(r-16)-8;t===0?i.moveTo(s,l):i.lineTo(s,l)}),i.stroke()}let G=h(null),K=null,q=``;function J(){let e=G.value,t=E.value;if(!e||!t||t.hist.length<2)return;let n=`${t.hist.length}:${t.hist[t.hist.length-1]}:${t.hist[0]}`;if(n===q)return;q=n;let r=Math.min(window.devicePixelRatio||1,2),i=e.clientWidth,a=e.clientHeight;(e.width!==i*r||e.height!==a*r)&&(e.width=i*r,e.height=a*r);let o=e.getContext(`2d`);if(!o)return;o.setTransform(r,0,0,r,0,0),o.clearRect(0,0,i,a);let s=Math.max(...t.hist),c=Math.min(...t.hist),l=Math.max(s-c,1e-9);o.strokeStyle=`rgba(65,200,244,0.9)`,o.lineWidth=1.5,o.beginPath(),t.hist.forEach((e,n)=>{let r=n/(t.hist.length-1)*i,s=a-(e-c)/l*(a-6)-3;n===0?o.moveTo(r,s):o.lineTo(r,s)}),o.stroke()}let Y=null,X=!1;function Jt(){X=document.hidden,X||(J(),Q.value&&W())}let Z=h(0),Q=l(()=>{let e=w.controller.minQueryDisplayIntervalMs??500,t=Z.value>0?Z.value:w.controller.queryDisplayIntervalMs??0;return t>0?Math.max(e,t):0}),$=null;function Yt(){$&&=(clearInterval($),null);let e=Q.value;e&&($=se(()=>{document.hidden||U.value||W()},e))}return n(()=>{W(),K=se(()=>{X||J()},800),document.addEventListener(`visibilitychange`,Jt),typeof ResizeObserver<`u`&&(Y=new ResizeObserver(()=>{q=``,J(),qt()}),G.value&&Y.observe(G.value)),Yt()}),t(()=>{K&&clearInterval(K),$&&clearInterval($),document.removeEventListener(`visibilitychange`,Jt),Y?.disconnect(),Y=null}),e(H,()=>void W()),e(Q,()=>Yt()),(e,t)=>{let n=ae;return a(),d(`div`,me,[u(`p`,he,[c(n,{to:`/daq`,class:`back`},{default:te(()=>[_(i(e.$t(`daqDetail.k1emg364001`)),1)]),_:1}),_(` / NODE `+i(C.value.slice(0,8).toUpperCase()),1)]),u(`div`,ge,[u(`h1`,null,i(E.value?.name??C.value),1),u(`span`,{class:o([`st-pill`,[O()]])},i(Mt[O()]),3)]),!E.value&&g(w).error?(a(),d(`p`,_e,[_(i(g(w).error)+`(`,1),c(n,{to:`/workshop`},{default:te(()=>[_(i(e.$t(`daqDetail.k1bhhheq002`)),1)]),_:1}),t[21]||=_(`) `,-1)])):p(``,!0),E.value?(a(),d(`div`,ve,[u(`section`,ye,[u(`div`,be,[u(`p`,xe,i(e.$t(`daqDetail.k1fx2vik032`))+` `+i(D.value?.ch??`-`),1),u(`div`,Se,[_(i(E.value.value==null?`--`:E.value.value.toFixed(E.value.decimals)),1),u(`small`,null,i(E.value.unit),1)]),u(`canvas`,{ref_key:`liveCanvas`,ref:G,class:`live-canvas`},null,512),u(`dl`,Ce,[u(`div`,null,[u(`dt`,null,i(e.$t(`daqDetail.k4a0la003`)),1),u(`dd`,null,i(E.value.driver)+i(Vt(E.value.driver)?e.$t(`daqDetail.kz8zr9v035`):``),1)]),u(`div`,null,[u(`dt`,null,i(e.$t(`daqDetail.k3xg3w004`)),1),u(`dd`,null,i(E.value.intervalMs??e.$t(`daqDetail.k9vnp9h053`,{p0:g(w).controller.defaultIntervalMs})),1)]),u(`div`,null,[u(`dt`,null,i(e.$t(`daqDetail.k3w6td005`)),1),u(`dd`,null,i(Rt(E.value.publishIntervalMs)),1)]),u(`div`,null,[u(`dt`,null,i(e.$t(`daqDetail.k3x5tpx006`)),1),u(`dd`,null,i(E.value.warnLow??`-∞`)+` ~ `+i(E.value.warnHigh??`+∞`),1)]),u(`div`,null,[u(`dt`,null,i(e.$t(`daqDetail.k1hjj0jf007`)),1),u(`dd`,null,i(E.value.min)+` ~ `+i(E.value.max),1)]),u(`div`,null,[u(`dt`,null,i(e.$t(`daqDetail.k1i8rtqt008`)),1),u(`dd`,null,i(Ht.value||e.$t(`daqDetail.k3own4q036`)),1)])])])]),u(`section`,we,[u(`h3`,Te,i(e.$t(`daqDetail.kd9d69j009`)),1),u(`form`,{class:`form-grid`,onSubmit:ne(Bt,[`prevent`])},[u(`label`,Ee,[u(`span`,null,i(e.$t(`daqDetail.k1iw7tbf010`)),1),u(`button`,{type:`button`,class:o([`toggle`,{on:P.enabled}]),onClick:t[0]||=e=>P.enabled=!P.enabled},i(P.enabled?e.$t(`daqDetail.k3w3j8f037`):e.$t(`daqDetail.k3n5aaj045`)),3)]),u(`label`,De,[u(`span`,null,i(e.$t(`daqDetail.k12k23od011`)),1),m(u(`select`,{"onUpdate:modelValue":t[1]||=e=>P.lineId=e,class:`input`},[u(`option`,Oe,i(e.$t(`daqDetail.k3ootr6012`)),1),(a(!0),d(f,null,s(g(jt).lines,e=>(a(),d(`option`,{key:e.id,value:e.id},i(e.name),9,ke))),128))],512),[[v,P.lineId]])]),u(`label`,Ae,[u(`span`,null,i(e.$t(`daqDetail.k1l6smxo013`)),1),m(u(`select`,{"onUpdate:modelValue":t[2]||=e=>P.driver=e,class:`input`},[(a(!0),d(f,null,s(g(x),t=>(a(),d(`option`,{key:t.kind,value:t.kind,disabled:t.status===`planned`},i(t.label)+i(t.status===`planned`?e.$t(`daqDetail.kz8zr9v035`):``),9,je))),128))],512),[[v,P.driver]])]),u(`label`,Me,[u(`button`,{type:`button`,class:o([`toggle slim`,{on:P.followGlobal}]),onClick:t[3]||=e=>P.followGlobal=!P.followGlobal},i(P.followGlobal?e.$t(`daqDetail.k1k2ueyq038`):e.$t(`daqDetail.k1cgi8fy046`)),3),m(u(`input`,{"onUpdate:modelValue":t[4]||=e=>P.intervalMs=e,type:`number`,min:`1000`,max:`60000`,step:`500`,class:`input`,disabled:P.followGlobal},null,8,Ne),[[y,P.intervalMs,void 0,{number:!0}]]),t[22]||=u(`small`,null,`ms`,-1)]),u(`label`,Pe,[u(`button`,{type:`button`,class:o([`toggle slim`,{on:P.calKind===`linear`}]),title:`采集标定 decoder:物理值 = scale × PLC采集值 + offset`,onClick:t[5]||=e=>P.calKind=P.calKind===`linear`?`none`:`linear`},i(P.calKind===`linear`?e.$t(`daqDetail.k1eru4r1039`):e.$t(`daqDetail.k3oktae047`)),3),m(u(`input`,{"onUpdate:modelValue":t[6]||=e=>P.calScale=e,type:`number`,step:`0.1`,class:`input`,disabled:P.calKind!==`linear`,title:`decode 斜率(≠0)`},null,8,Fe),[[y,P.calScale,void 0,{number:!0}]]),m(u(`input`,{"onUpdate:modelValue":t[7]||=e=>P.calOffset=e,type:`number`,step:`0.1`,class:`input`,disabled:P.calKind!==`linear`,title:`decode 截距`},null,8,Ie),[[y,P.calOffset,void 0,{number:!0}]]),t[23]||=u(`small`,null,`decoder`,-1)]),u(`label`,Le,[u(`button`,{type:`button`,class:o([`toggle slim`,{on:P.publishFollow}]),onClick:t[8]||=e=>P.publishFollow=!P.publishFollow},i(P.publishFollow?e.$t(`daqDetail.k1k2t5o7040`):e.$t(`daqDetail.k1cggz5f048`)),3),u(`span`,{class:o([`toggle slim`,{on:P.publishEveryFrame}]),style:{cursor:`pointer`},onClick:t[9]||=e=>P.publishEveryFrame=!P.publishEveryFrame},i(P.publishEveryFrame?e.$t(`daqDetail.k41mvv041`):e.$t(`daqDetail.k3n42dj049`)),3),m(u(`input`,{"onUpdate:modelValue":t[10]||=e=>P.publishMs=e,type:`number`,min:`0`,max:`60000`,step:`100`,class:`input`,disabled:P.publishFollow||P.publishEveryFrame},null,8,Re),[[y,P.publishMs,void 0,{number:!0}]]),t[24]||=u(`small`,null,`ms`,-1)]),u(`label`,ze,[u(`span`,null,i(e.$t(`daqDetail.k3x4ef014`)),1),m(u(`input`,{"onUpdate:modelValue":t[11]||=e=>P.unit=e,class:`input`},null,512),[[y,P.unit]])]),u(`label`,Be,[u(`span`,null,i(e.$t(`daqDetail.k3mxmcx015`)),1),m(u(`input`,{"onUpdate:modelValue":t[12]||=e=>P.decimals=e,type:`number`,min:`0`,max:`6`,class:`input`},null,512),[[y,P.decimals,void 0,{number:!0}]])]),u(`div`,Ve,[u(`label`,He,[u(`span`,null,i(e.$t(`daqDetail.k1l9jv5m016`)),1),m(u(`input`,{"onUpdate:modelValue":t[13]||=e=>P.min=e,type:`number`,step:`any`,class:`input`},null,512),[[y,P.min,void 0,{number:!0}]])]),u(`label`,Ue,[u(`span`,null,i(e.$t(`daqDetail.k1md63hm017`)),1),m(u(`input`,{"onUpdate:modelValue":t[14]||=e=>P.warnLow=e,type:`number`,step:`any`,class:`input`},null,512),[[y,P.warnLow,void 0,{number:!0}]])]),u(`label`,We,[u(`span`,null,i(e.$t(`daqDetail.k1md63gp018`)),1),m(u(`input`,{"onUpdate:modelValue":t[15]||=e=>P.warnHigh=e,type:`number`,step:`any`,class:`input`},null,512),[[y,P.warnHigh,void 0,{number:!0}]])]),u(`label`,Ge,[u(`span`,null,i(e.$t(`daqDetail.k1l9jv4p019`)),1),m(u(`input`,{"onUpdate:modelValue":t[16]||=e=>P.max=e,type:`number`,step:`any`,class:`input`},null,512),[[y,P.max,void 0,{number:!0}]])])]),u(`button`,{class:`aw-pill`,type:`submit`,disabled:z.value},i(z.value?e.$t(`daqDetail.k1as0g50042`):e.$t(`daqDetail.ksn9cgo050`)),9,Ke)],32),I.value.length?(a(),d(f,{key:0},[u(`h3`,qe,i(e.$t(`daqDetail.k1p9gioa033`))+` `+i(g(x).find(e=>e.kind===P.driver)?.label),1),u(`div`,Je,[(a(!0),d(f,null,s(I.value,e=>(a(),d(`label`,{key:e.key,class:`field`},[u(`span`,null,[_(i(e.label),1),e.required?(a(),d(`em`,Ye,`*`)):p(``,!0)]),e.type===`select`?m((a(),d(`select`,{key:0,"onUpdate:modelValue":t=>F.value[e.key]=t,class:`input`},[(a(!0),d(f,null,s(e.options,e=>(a(),d(`option`,{key:e.value,value:e.value},i(e.label),9,Ze))),128))],8,Xe)),[[v,F.value[e.key]]]):m((a(),d(`input`,{key:1,"onUpdate:modelValue":t=>F.value[e.key]=t,type:e.type===`number`?`number`:`text`,placeholder:e.placeholder,class:`input`},null,8,Qe)),[[re,F.value[e.key]]])]))),128))]),u(`div`,$e,[u(`button`,{class:`pill-btn`,disabled:L.value,onClick:zt},i(L.value?e.$t(`daqDetail.k1fsh720043`):e.$t(`daqDetail.k1fstglk051`)),9,et),R.value?(a(),d(`span`,{key:0,class:o([`test-out mono`,R.value.ok?`ok`:`bad`])},i(R.value.ok?`✓`:`✗`)+` `+i(R.value.message),3)):p(``,!0)])],64)):p(``,!0),u(`h3`,tt,i(e.$t(`daqDetail.k1ie6qju020`)),1),u(`div`,nt,[m(u(`select`,{"onUpdate:modelValue":t[17]||=e=>B.value=e,class:`input grow`},[u(`option`,rt,i(e.$t(`daqDetail.kjobzu3021`)),1),(a(!0),d(f,null,s(Wt.value,e=>(a(),d(`option`,{key:e.id,value:e.id},i(e.name),9,it))),128))],512),[[v,B.value]]),u(`button`,{class:`pill-btn`,onClick:Ut},i(Ht.value?e.$t(`daqDetail.k479eh044`):e.$t(`daqDetail.k452a8052`)),1)])]),u(`section`,at,[u(`div`,ot,[u(`h3`,st,i(e.$t(`daqDetail.k1i535i5034`))+i(g(w).meta.tsdb)+`) `,1),u(`div`,ct,[m(u(`select`,{"onUpdate:modelValue":t[18]||=e=>H.value=e,class:`input`},[(a(),d(f,null,s(Gt,e=>u(`option`,{key:e.ms,value:e.ms},i(e.label),9,lt)),64))],512),[[v,H.value,void 0,{number:!0}]]),u(`label`,{class:`refresh-ctl`,title:e.$t(`daqDetail.k1rfrshint001`,{p0:g(w).controller.minQueryDisplayIntervalMs??500})},[t[25]||=u(`span`,{class:`i-tabler-refresh`},null,-1),m(u(`input`,{"onUpdate:modelValue":t[19]||=e=>Z.value=e,type:`number`,min:0,max:`600000`,step:`500`,placeholder:String(g(w).controller.queryDisplayIntervalMs??5e3)},null,8,dt),[[y,Z.value,void 0,{number:!0}]]),t[26]||=_(`ms `,-1)],8,ut),u(`button`,{class:`pill-btn`,onClick:W},i(e.$t(`daqDetail.k3x1jg022`)),1)])]),u(`canvas`,{ref_key:`chartCanvas`,ref:Kt,class:`hist-canvas`},null,512),u(`table`,ft,[u(`thead`,null,[u(`tr`,null,[u(`th`,null,i(e.$t(`daqDetail.k40vsf023`)),1),u(`th`,null,i(e.$t(`daqDetail.k48v5024`)),1),u(`th`,null,i(e.$t(`daqDetail.k4bza025`)),1)])]),u(`tbody`,null,[(a(!0),d(f,null,s(V.value.filter(e=>e.value!=null).slice(-12).reverse(),(e,t)=>(a(),d(`tr`,{key:t},[u(`td`,null,i(new Date(e.at).toLocaleTimeString(`zh-CN`,{hour12:!1})),1),u(`td`,null,i(e.value.toFixed(E.value?.decimals??2)),1),u(`td`,null,i(e.state),1)]))),128))])])])])):p(``,!0),A.value?(a(),d(`section`,pt,[u(`div`,mt,[u(`h3`,ht,[_(i(k.value===`image`?e.$t(`daqDetail.kfrm0001`):e.$t(`daqDetail.kfrm0002`))+` `,1),u(`span`,gt,i(j.value.length),1)]),u(`button`,{class:`pill-btn`,onClick:M},i(e.$t(`daqDetail.k3x1jg022`)),1)]),k.value===`vector`?(a(),d(f,{key:0},[(a(),d(`svg`,{class:`vec-svg`,viewBox:`0 0 ${S} ${Et}`,preserveAspectRatio:`none`},[u(`polyline`,{points:Lt.value,fill:`none`,stroke:`var(--accent)`,"stroke-width":`1.5`},null,8,vt)],8,_t)),u(`table`,yt,[u(`thead`,null,[u(`tr`,null,[u(`th`,null,i(e.$t(`daqDetail.k40vsf023`)),1),u(`th`,null,i(e.$t(`daqDetail.kfrm0004`)),1),u(`th`,null,i(e.$t(`daqDetail.kfrm0005`)),1)])]),u(`tbody`,null,[(a(!0),d(f,null,s(j.value.filter(e=>e.kind===`vector`).slice(0,12),e=>(a(),d(`tr`,{key:e.at},[u(`td`,null,i(Pt(e.at)),1),u(`td`,null,i(e.points?.length??0),1),u(`td`,null,i(Ft(e)),1)]))),128))])])],64)):(a(),d(f,{key:1},[j.value.length?(a(),d(`div`,bt,[(a(!0),d(f,null,s(j.value,t=>(a(),d(`figure`,{key:t.at,class:`gal-item`,title:e.$t(`daqDetail.kfrm0006`),onClick:e=>N.value=t},[u(`img`,{src:t.thumbUrl,loading:`lazy`,alt:`daq frame`},null,8,St),u(`figcaption`,Ct,i(Pt(t.at))+` · `+i(Ft(t)),1)],8,xt))),128))])):(a(),d(`p`,wt,i(e.$t(`daqDetail.kfrm0003`)),1)),N.value?(a(),d(`div`,{key:2,class:`gal-full`,onClick:t[20]||=e=>N.value=null},[u(`img`,{src:N.value.contentUrl??N.value.thumbUrl,alt:`daq frame full`},null,8,Tt)])):p(``,!0)],64))])):p(``,!0)])}}}),[[`__scopeId`,`data-v-680686c6`]]);export{At as default};
@@ -1 +0,0 @@
1
- import{dt as e}from"./CSkxz2NX.js";import{t}from"./36oeS8_R.js";import{t as n}from"./D0ZBQrN_2.js";import{t as r}from"./BDmh31hl.js";var i=[{key:`temp-sp`,name:`温度设定器`,code:`TEMP · SP`,ch:`烘箱温度设定`,unit:`℃`,min:150,max:200,decimals:1,icon:`thermo`,semantics:`烘箱/熔体温度设定:升高使热塑温度上升(成膜更均匀但能耗高、过热降解风险),降低则偏冷易厚度不均。调整后需等待热惯性(数十秒级)再评估效果。`},{key:`speed-sp`,name:`速度设定器`,code:`LINE · SP`,ch:`产线速度设定`,unit:`m/min`,min:280,max:360,decimals:0,icon:`encoder`,semantics:`产线速度设定:升速提高产能但缩短物料受热时间(温度补偿需联动),降速利于精细工艺。速度变化会同步影响张力与厚度分布。`},{key:`tension-sp`,name:`张力设定器`,code:`TENSION · SP`,ch:`膜张力设定`,unit:`kN`,min:18,max:26,decimals:1,icon:`tension`,semantics:`膜张力设定:张力过大易断膜/拉伸变形,过小则跑偏起皱。调整需平缓,并与速度联动观察。`},{key:`pressure-sp`,name:`压力设定器`,code:`PRESSURE · SP`,ch:`熔体压力设定`,unit:`MPa`,min:.6,max:1.2,decimals:2,icon:`pressure`,semantics:`熔体压力设定:反映挤出/泵送负荷,压力偏高提示阻力大或温度偏低,偏低可能是料位不足。调整需小幅步进。`}],a=[{kind:`mock`,label:`Mock 模拟 PLC`,status:`builtin`,configFields:[]},{kind:`modbus-tcp`,label:`Modbus TCP(PLC/网关 写保持寄存器)`,status:`real`,configFields:[{key:`host`,label:`设备地址(host)`,type:`string`,required:!0,placeholder:`192.168.1.10`,hint:`PLC 或 Modbus 网关 IP`},{key:`port`,label:`端口`,type:`number`,default:502,hint:`Modbus TCP 标准端口 502`},{key:`unitId`,label:`单元号(unitId)`,type:`number`,default:1,hint:`从站地址,常见 1`},{key:`register`,label:`写寄存器地址`,type:`number`,required:!0,placeholder:`40021`,hint:`4xxxx=保持寄存器(写);回读同址校验`},{key:`dataType`,label:`数据类型`,type:`select`,default:`float32`,options:[{value:`int16`,label:`int16(1 寄存器)`},{value:`uint16`,label:`uint16(1 寄存器)`},{value:`int32`,label:`int32(2 寄存器)`},{value:`uint32`,label:`uint32(2 寄存器)`},{value:`float32`,label:`float32(2 寄存器,常用)`}]},{key:`byteOrder`,label:`字节序`,type:`select`,default:`big`,options:[{value:`big`,label:`大端(AB CD)`},{value:`little`,label:`小端(CD AB)`},{value:`wordSwap`,label:`字交换(CD AB / 交换单字)`}]},{key:`engMin`,label:`工程量程下限`,type:`number`,hint:`线性换算:eng ∈ [engMin, engMax] ↔ raw ∈ [rawMin, rawMax];float32 且未填原始量程时 raw=eng`},{key:`engMax`,label:`工程量程上限`,type:`number`},{key:`rawMin`,label:`原始值下限`,type:`number`,hint:`如 int16 用 0~2000 表示 0.1 分辨率`},{key:`rawMax`,label:`原始值上限`,type:`number`}]},{kind:`opcua`,label:`OPC UA(PLC/MES 写节点值)`,status:`real`,configFields:[{key:`endpoint`,label:`端点(endpoint)`,type:`string`,required:!0,placeholder:`opc.tcp://192.168.1.10:4840`,hint:`OPC UA 服务器地址`},{key:`nodeId`,label:`节点 ID(NodeId)`,type:`string`,required:!0,placeholder:`ns=2;s=Channel1.Device1.SetTemp`,hint:`要写入的变量节点`},{key:`securityMode`,label:`安全策略`,type:`select`,default:`None`,options:[{value:`None`,label:`None(无加密,内网常用)`},{value:`Sign`,label:`Sign(签名)`},{value:`SignAndEncrypt`,label:`SignAndEncrypt(签名+加密)`}]},{key:`username`,label:`用户名(可选)`,type:`string`},{key:`password`,label:`密码(可选)`,type:`string`}]},{kind:`modbus-rtu`,label:`Modbus RTU over TCP(串口网关 写保持寄存器)`,status:`real`,configFields:[{key:`host`,label:`网关地址(host)`,type:`string`,required:!0,placeholder:`192.168.1.50`,hint:`串口服务器/RTU 转 TCP 网关 IP`},{key:`port`,label:`端口`,type:`number`,default:502,hint:`网关透传端口(常见 502 / 8899 / 26)`},{key:`unitId`,label:`从站地址(unitId)`,type:`number`,default:1,hint:`RS-485 总线上的从站地址`},{key:`register`,label:`写寄存器地址`,type:`number`,required:!0,placeholder:`40021`,hint:`4xxxx=保持寄存器(写);回读同址校验`},{key:`dataType`,label:`数据类型`,type:`select`,default:`float32`,options:[{value:`int16`,label:`int16(1 寄存器)`},{value:`uint16`,label:`uint16(1 寄存器)`},{value:`int32`,label:`int32(2 寄存器)`},{value:`uint32`,label:`uint32(2 寄存器)`},{value:`float32`,label:`float32(2 寄存器,常用)`}]},{key:`byteOrder`,label:`字节序`,type:`select`,default:`big`,options:[{value:`big`,label:`大端(AB CD)`},{value:`little`,label:`小端(CD AB)`},{value:`wordSwap`,label:`字交换(CD AB / 交换单字)`}]},{key:`engMin`,label:`工程量程下限`,type:`number`,hint:`线性换算:eng ∈ [engMin, engMax] ↔ raw ∈ [rawMin, rawMax];float32 且未填原始量程时 raw=eng`},{key:`engMax`,label:`工程量程上限`,type:`number`},{key:`rawMin`,label:`原始值下限`,type:`number`},{key:`rawMax`,label:`原始值上限`,type:`number`}]},{kind:`mqtt`,label:`MQTT(发布设定值到 Broker)`,status:`real`,configFields:[{key:`host`,label:`Broker 地址(host)`,type:`string`,required:!0,placeholder:`192.168.1.20`,hint:`MQTT Broker 地址(与边缘网关约定同一 Broker)`},{key:`port`,label:`端口`,type:`number`,default:1883,hint:`MQTT TCP 端口 1883`},{key:`topic`,label:`下发主题(topic)`,type:`string`,required:!0,placeholder:`factory/line1/setpoint`,hint:`网关订阅的控制主题(勿与采集主题相同)`},{key:`jsonKey`,label:`JSON 键(可选)`,type:`string`,placeholder:`setpoint`,hint:`留空 = 纯数字报文;填写 = {"键":值} JSON 报文`},{key:`qos`,label:`QoS`,type:`number`,default:1,hint:`0=至多一次 1=至少一次(推荐)`},{key:`username`,label:`用户名(可选)`,type:`string`},{key:`password`,label:`密码(可选)`,type:`string`}]},{kind:`http`,label:`HTTP/REST(POST 设定值)`,status:`real`,configFields:[{key:`url`,label:`写接口地址(URL)`,type:`string`,required:!0,placeholder:`http://192.168.1.30/api/setpoint`,hint:`接收设定值的 HTTP 接口(POST JSON)`},{key:`bodyKey`,label:`JSON 键(可选)`,type:`string`,placeholder:`setpoint`,hint:`留空 = {"value": 设定值};填写 = {"键": 设定值}`},{key:`headersJSON`,label:`请求头(可选)`,type:`string`,placeholder:`{"Authorization":"Bearer xxx"}`,hint:`JSON 对象形式的 HTTP 头`}]}],o=[`#3aa0ff`,`#f4c542`,`#35e0a0`,`#41c8f4`,`#b58cff`,`#ff8a5c`],s=(e,t)=>r({base:`/api/workshop/dcw`,path:e,init:t,retries:(t?.method??`GET`).toUpperCase()===`GET`?2:0});function c(){let r=e([]),a=new Map,o=e({running:!0,nodesTotal:0,nodesOnline:0,writesTotal:0,writesFailed:0}),c=e(i.map(e=>({...e}))),l=e([]),u=e([]),d=e([]),f=e([]),p=e([]),m=e({}),h=e([]);function g(e){let t=r.findIndex(t=>t.id===e.id);t>=0?r[t]=Object.assign(r[t],e):(r.push(e),a.set(e.id,r[r.length-1]))}function _(e){if(e.node){if(e.op===`removed`){let t=r.findIndex(t=>t.id===e.node.id);t>=0&&r.splice(t,1),a.delete(e.node.id);return}g(e.node)}}let v=0,y=null;function b(){v++,v===1&&(y=t().subscribe(x));let e=!1;return()=>{e||(e=!0,--v===0&&(y?.(),y=null))}}function x(e){if(e.type===`dcw.written`){let t=e.payload,n=a.get(t.nodeId);n&&(n.value=t.value,n.state=t.ok?`ok`:`error`,n.lastWriteAt=t.at,t.ok&&(n.lastAckAt=t.at)),d.unshift({id:`${t.nodeId}-${t.at}`,nodeId:t.nodeId,nodeName:n?.name??t.nodeId,param:``,eng:t.value,raw:t.raw,ok:t.ok,message:t.message,recipeRunId:t.recipeRunId,at:t.at}),d.length>60&&d.splice(60)}else if(e.type===`dcw.read`){let t=e.payload,n=a.get(t.nodeId);n&&(t.ok&&(n.readValue=t.value),n.lastReadAt=t.at,n.lastReadError=t.ok?null:t.message)}else if(e.type===`dcw.node.changed`)_(e.payload);else if(e.type===`dcw.controller`)Object.assign(o,e.payload);else if(e.type===`dcw.optimization.changed`){let t=e.payload.record,n=h.findIndex(e=>e.id===t.id);n>=0?h[n]=t:h.unshift(t),h.length>200&&(h.length=200)}}async function S(){try{let e=await s(``);r.splice(0,r.length,...e.nodes),a.clear();for(let e of r)a.set(e.id,e);Object.assign(o,e.controller),e.templates?.length&&c.splice(0,c.length,...e.templates.map(e=>({...e}))),l.splice(0,l.length,...e.recipes??[]),u.splice(0,u.length,...e.runs??[]),d.splice(0,d.length,...e.history??[]),f.splice(0,f.length,...e.products??[]),p.splice(0,p.length,...e.lines??[]);for(let e of Object.keys(m))Reflect.deleteProperty(m,e);for(let t of e.lineStates??[])m[t.lineId]=t;C.loaded=!0,C.error=``}catch(e){C.error=n(e)}}let C=e({nodes:r,controller:o,templates:c,recipes:l,runs:u,history:d,products:f,lines:p,lineStates:m,optimizations:h,loaded:!1,error:``,ensureWsFeed:b,load:S,loadOptimizations:async e=>{let t=new URLSearchParams;e?.lineId&&t.set(`lineId`,e.lineId),e?.recipeId&&t.set(`recipeId`,e.recipeId),e?.nodeId&&t.set(`nodeId`,e.nodeId),e?.status&&t.set(`status`,e.status),t.set(`limit`,String(e?.limit??100));let n=await s(`/optimizations?${t.toString()}`);h.splice(0,h.length,...n.records)},fetchLedger:async e=>(await s(`/${e}/param-ledger`)).ledger,optimizationSeries:async(e,t)=>s(`/optimizations/${e}/series${t?`?windowMs=${t}`:``}`),judgeOptimization:async(e,t,n)=>{await s(`/optimizations/${e}/judge`,{method:`POST`,body:JSON.stringify({verdict:t,reason:n})})},rollbackOptimization:async e=>{await s(`/optimizations/${e}/rollback`,{method:`POST`,body:JSON.stringify({})})},rollbackNode:async(e,t)=>{await s(`/journal/node/${e}/rollback`,{method:`POST`,body:JSON.stringify({to:t})})},markGood:async(e,t)=>{await s(`/recipes/${e}/mark-good`,{method:`POST`,body:JSON.stringify({runId:t})})},rollbackRecipeGood:async e=>{await s(`/recipes/${e}/rollback-good`,{method:`POST`,body:JSON.stringify({})})},createFromTemplate:async(e,t)=>{let n=await s(``,{method:`POST`,body:JSON.stringify({templateRef:e,...t})});return g(n.node),n.node},patchNode:async(e,t)=>{await s(`/${e}`,{method:`PATCH`,body:JSON.stringify(t)})},removeNode:async e=>{await s(`/${e}`,{method:`DELETE`});let t=r.findIndex(t=>t.id===e);t>=0&&r.splice(t,1),a.delete(e)},bindNode:async(e,t)=>{g((await s(`/${e}/bind`,{method:`POST`,body:JSON.stringify({deviceId:t})})).node)},write:async(e,t)=>s(`/${e}/write`,{method:`POST`,body:JSON.stringify({value:t})}).then(e=>e.outcome),readNode:async e=>s(`/${e}/read`,{method:`POST`,body:JSON.stringify({})}).then(e=>e.read),testDriver:async(e,t)=>s(`/test-driver`,{method:`POST`,body:JSON.stringify({driver:e,driverConfig:t})}).then(e=>e.test),testNode:async e=>s(`/${e}/test`,{method:`POST`}).then(e=>e.test),startStop:async e=>{let t=await s(`/controller`,{method:`POST`,body:JSON.stringify({action:e})});Object.assign(o,t.controller)},createTemplate:async e=>{let t=await s(`/templates`,{method:`POST`,body:JSON.stringify(e)});return c.push(t.template),t.template},createRecipe:async e=>{let t=await s(`/recipes`,{method:`POST`,body:JSON.stringify(e)});return l.push(t.recipe),t.recipe},updateRecipe:async(e,t)=>{let n=await s(`/recipes/${e}`,{method:`PATCH`,body:JSON.stringify(t)}),r=l.findIndex(t=>t.id===e);return r>=0&&(l[r]=n.recipe),n.recipe},removeRecipe:async e=>{await s(`/recipes/${e}`,{method:`DELETE`});let t=l.findIndex(t=>t.id===e);t>=0&&l.splice(t,1)},applyRecipe:async e=>{let t=await s(`/recipes/${e}/apply`,{method:`POST`});return u.push(t.run),t.run},recipeVersions:async e=>(await s(`/recipes/${e}/versions`)).versions??[],revertRecipe:async(e,t)=>{let n=await s(`/recipes/${e}/revert`,{method:`POST`,body:JSON.stringify(t)}),r=l.findIndex(t=>t.id===e);return r>=0&&(l[r]=n.recipe),n.recipe},closeRun:async e=>{let t=await s(`/runs/${e}/close`,{method:`POST`}),n=u.findIndex(t=>t.id===e);return n>=0&&(u[n]=t.run),t.run},runData:e=>s(`/runs/${e}/data`),nodeById:e=>a.get(e)??r.find(t=>t.id===e),createProduct:async e=>{let t=await s(`/products`,{method:`POST`,body:JSON.stringify(e)});return f.push(t.product),t.product},updateProduct:async(e,t)=>s(`/products/${e}`,{method:`PATCH`,body:JSON.stringify(t)}).then(e=>(w(),e.product)),removeProduct:async e=>{await s(`/products/${e}`,{method:`DELETE`});let t=f.findIndex(t=>t.id===e);t>=0&&f.splice(t,1)},createLine:async e=>{let t=await s(`/lines`,{method:`POST`,body:JSON.stringify(e)});return p.push(t.line),t.line},updateLine:async(e,t)=>{let n=await s(`/lines/${e}`,{method:`PATCH`,body:JSON.stringify(t)}),r=p.findIndex(t=>t.id===e);r>=0&&(p[r]=n.line)},removeLine:async(e,t=!1)=>{await s(`/lines/${e}${t?`?purge=1`:``}`,{method:`DELETE`});let n=p.findIndex(t=>t.id===e);n>=0&&p.splice(n,1),Reflect.deleteProperty(m,e),await S()},startLine:async(e,t)=>{let n=await s(`/lines/${e}/start`,{method:`POST`,body:JSON.stringify({recipeId:t})});m[e]=n.line},stopLine:async e=>{let t=await s(`/lines/${e}/stop`,{method:`POST`});m[e]=t.line},lineStateOf:e=>m[e]??{lineId:e,active:!1,runId:null,recipeId:null,recipeName:null,productId:null,productName:null,startedAt:null,taggedSamples:0},queryLine:e=>{let t=new URLSearchParams;return e.lineId&&t.set(`lineId`,e.lineId),e.productId&&t.set(`productId`,e.productId),e.recipeId&&t.set(`recipeId`,e.recipeId),e.paramKey&&t.set(`paramKey`,e.paramKey),e.nodeId&&t.set(`nodeId`,e.nodeId),e.fromMs!=null&&t.set(`from`,String(e.fromMs)),e.toMs!=null&&t.set(`to`,String(e.toMs)),e.bucketMs!=null&&t.set(`bucketMs`,String(e.bucketMs)),e.limit!=null&&t.set(`limit`,String(e.limit)),s(`/line/query?${t.toString()}`)}});async function w(){try{let e=await s(``);f.splice(0,f.length,...e.products??[]),l.splice(0,l.length,...e.recipes??[])}catch{}}return C}var l=`__dcwStream`;function u(){let e=globalThis;return e[l]||(e[l]=c()),e[l]}export{a as n,o as r,u as t};