210 lines
23 KiB
Markdown
210 lines
23 KiB
Markdown
# 开发维护记录
|
||
|
||
## 2026-07-12|需求分析
|
||
|
||
- 研读 `spec-数据管理.md` v1.2、`spec-历史数据.md` v1.1、`code-standards.md` v1.2 和一致性决策基线 v1.0。
|
||
- 确认采用单进程 Go 服务、Handler → Service → Repository、每设备独立协议连接、同设备读写串行、PostgreSQL 当前元数据权威、TDengine 子表由 UUID 派生。
|
||
- 历史查询边界统一为最多 20 点、31 天;曲线默认 2000 样本;表格使用精确半间隔最近邻;CSV 最大 50,000 行。
|
||
|
||
## 技术与视觉决策
|
||
|
||
- 前端使用 Vue 3 + TypeScript + Pinia + Vue Router + Axios + ECharts。
|
||
- 视觉采用深石墨底、荧光绿主色、青色辅助数据序列;避免卡片堆叠,保持工业数据表和图表的高信息密度。
|
||
- 非线性分段轴算法位于 `web/src/components/charts/`,API 和导出只使用原始值。
|
||
- PostgreSQL 使用 pgx 连接池;TDengine 使用官方 Go REST 驱动,连接信息全部来自环境变量。
|
||
|
||
## 已识别问题与处理
|
||
|
||
- 现场给出的读取地址 `DB2.DB2.1186.0` 与规格 `DB{db}.{byte}.{bit}` 冲突。实现严格接受 `DB2.1186.0`;现场测试前需由用户/PLC 工程师确认前一形式是否只是录入笔误。
|
||
- PLC `192.168.107.10:102` 在 2026-07-12 的 TCP 探测未在 30 秒窗口内完成;未执行任何写入。
|
||
- 用户提供的数据库凭据仅用于本次环境验证,不写入代码、示例或日志。
|
||
|
||
## 变更摘要
|
||
|
||
- 新增 PostgreSQL/TDengine 幂等迁移。
|
||
- 新增设备、采集点、写入点、历史数据四个桌面工作区。
|
||
- 新增设备 API、点位/日志列表、历史树、曲线、表格和 CSV 导出。
|
||
- 新增协议注册表、S7/Modbus 地址与配置校验骨架。
|
||
|
||
## 测试记录
|
||
|
||
- PostgreSQL `101.35.54.96:5432`:TCP 可达;目标库最初不存在,已通过受控标识符创建 `aquacontrolai` 并成功执行迁移。
|
||
- TDengine `101.35.54.96:6041`:TCP 可达;已创建/确认数据库及两个超级表,REST 驱动健康检查通过。
|
||
- PLC `192.168.107.10:102`:早期 TCP 探测超时,后续通过 S7 客户端成功连接并完成受控读写联调,详见下方补充记录。
|
||
- `go test ./...`:通过。
|
||
- `npm run build`:通过;Vite 提示 ECharts 主包超过 500 kB,后续可拆为异步图表 chunk。
|
||
- `GET /api/v1/health`:真实数据库配置下返回 `code=0`。
|
||
- Playwright Chromium 1600×1000:历史页可渲染,无框架错误覆盖层;空库状态正确显示 0/20 和空图表。应用内浏览器缺少必需控制入口,按规范使用 Playwright 回退。
|
||
- 视觉比对:应用壳、色板、导航、紧凑工具栏、开放式图表/表格容器与概念一致;空库无法验证多序列曲线、点位树密度和游标数据态。
|
||
|
||
## 2026-07-12|现场 S7 联调补充
|
||
|
||
- 用户确认采集地址为 `DB2.1186.0`、类型 REAL。考虑现场工程记法,校验器仅对 DB 数值地址兼容末尾 `.0`;驱动实际按 DB2、字节偏移 1186 连续读取 4 字节。
|
||
- 写入地址 `MD540` 按 M 区字节偏移 540 连续读写 4 字节 IEEE-754 REAL。
|
||
- PLC 建立连接成功;`DB2.1186.0` 实际读值 `724.0000610351562`,质量 `good`。
|
||
- 写入测试成功:`MD540=10.0`,回读 `10.0`,日志 ID `36d173ec-a496-495b-ba6a-d7048e616afa`。
|
||
- 强制恢复成功:`MD540=0.0`,回读 `0.0`,日志 ID `88c0d3dc-3988-46b9-9e98-d03819f6dbbc`。
|
||
- TDengine REST 驱动不支持在 `USING ... TAGS` 中绑定参数;动态表名仍只由 UUID 派生,标签/字符串采用单引号倍增转义,数值使用 `strconv.FormatFloat`,并增加表名和转义单元测试。
|
||
- 修复 TDengine REST 时间语义:API 的 ISO 8601 时间统一换算为 `Asia/Shanghai` 后生成 TDengine 查询字面量,现场最近一小时查询返回 28 条记录并成功绘制曲线。
|
||
- 修复 `vue-tsc -b` 在 `src/` 旁生成陈旧 `.js` 并覆盖 TypeScript 模块解析的问题:启用 `noEmit`、删除生成物;Playwright 验证控制台无 warning/error。
|
||
- Playwright 1600×1000 验证:历史树 1 个可选现场点位、默认勾选、ECharts canvas 正常、曲线显示真实 TDengine 数据;切换表格模式后渲染 7 行最近邻数据。
|
||
|
||
## 2026-07-12|剩余功能收尾
|
||
|
||
- 补齐设备、采集点、写入点详情 API,采集分组 API,以及三类配置 CSV 导入/导出。
|
||
- CSV 真实回灌验证:三类各 1 行,均为 `created=0, updated=1, failed=0`,名称幂等规则有效且没有产生重复记录。
|
||
- 补齐采集点和写入点新增、编辑、删除弹窗;三类页面导入文件选择与导出下载按钮已接入真实 API。
|
||
- 新增历史保留策略 GET/PUT;更新顺序为 TDengine `ALTER DATABASE KEEP` 成功后再提交 PostgreSQL 生效值。真实环境以 365 天原值回写验证成功。
|
||
- Playwright 逐页验证:设备、采集点、写入点三个新增弹窗均可打开并取消;历史保留配置可见;表格模式渲染 7 行;控制台无 warning/error。
|
||
- 补齐设备列表的协议/启用筛选,采集点和写入点的设备/分组/类型/启用/写入开关筛选,以及统一 `page/page_size`(最大 100)分页;写入日志支持点位、设备、结果和关键词筛选。
|
||
- 历史页新增精确到秒的自定义起止时间输入;快捷时间与自定义时间共用查询缓存键。
|
||
- 最终浏览器回归:三类页面导入/导出入口均可见,三个新增弹窗均可打开;历史页 2 个时间输入、保留策略控件和 7 行表格数据正常;控制台无 warning/error。
|
||
|
||
## 2026-07-12|设备状态展示调整
|
||
|
||
- 设备管理表头由“运行状态”改为“设备状态”。
|
||
- 后端状态映射为:`connected → 在线`、`disconnected → 离线`、`disabled → 禁用`。
|
||
- 前端使用无圆点的文字卡片:在线绿色、离线红色、禁用灰色。
|
||
- 1600×1000 Playwright 回归:设备状态列标题与“离线”红色文字卡片正常显示,控制台无错误。
|
||
- 设备管理表格进一步调整:连接地址拆为“地址”和“端口”;移除“启用”列;新增“最近在线”和“最近离线”。时间由采集引擎连接状态事件维护,接口字段为 `last_online_at`、`last_offline_at`。
|
||
- 真实接口回归返回在线设备时间戳,页面列顺序为:名称、协议、地址、端口、设备状态、最近在线、最近离线、操作。
|
||
|
||
## 2026-07-12|数据采集分组与 REAL 解析调整
|
||
|
||
- 新增 `collection_groups` 表及幂等迁移;启动时同步历史 `group_name` 并删除 `collection_points.valid_min/valid_max`。
|
||
- 新增分组 GET/POST/PUT/DELETE API。删除分组前端二次提示,后端事务内逻辑删除该分组全部采集点;`default` 分组禁止删除。
|
||
- 数据采集页新增左侧分组栏、分组添加/改名/删除操作,新建采集点改为分组下拉选择。
|
||
- 采集列表将“地址 / 类型”拆成“地址”和“类型”;新建/编辑表单移除有效最小值和有效最大值。
|
||
- S7 REAL 解析统一四舍五入到小数点后最多 3 位;采集质量不再执行有效范围判断。
|
||
- 真实数据库验证:分组新增、改名、删除级联均通过;删除后采集点查询总数为 0;现场 REAL 值示例 `1411.719`。
|
||
|
||
## 2026-07-12|设备与采集点弹窗复选框优化
|
||
|
||
- 设备新增弹窗的“启用设备”与采集点新增弹窗的“启用采集”“存储历史”统一为整行可点击的文字卡片控件。
|
||
- 复选框采用隐藏原生控件 + 自定义勾选方块,提供未选中、荧光绿色选中和键盘聚焦态;保留原有 `v-model` 数据绑定,不改变接口语义。
|
||
- 收紧通用表单输入选择器,避免复选框继承文本输入框的 `width: 100%` 导致位置异常。
|
||
- `npm run build`:通过(Vite 仍提示 ECharts 主包超过 500 kB 的既有拆包建议)。
|
||
- Playwright Chromium 回归:设备弹窗 1 个复选框、采集点弹窗 2 个复选框均正常渲染;设备默认勾选后点击可取消,采集点“存储历史”点击后可取消;两个弹窗无控制台错误。
|
||
- 回归截图:`C:\Users\Administrator\AppData\Local\Temp\aquacontrol-device-checkbox-final.png`、`C:\Users\Administrator\AppData\Local\Temp\aquacontrol-collection-checkbox-final.png`。
|
||
|
||
## 2026-07-12|数据写入分组与回读展示调整
|
||
|
||
- 数据写入页新增与数据采集一致的左侧分组栏,分组名称、添加、改名和删除均复用 `collection_groups` 接口;后端改为同步维护采集点和写入点的分组归属,删除分组时两类点位一起逻辑删除。
|
||
- 写入点列表将“地址 / 类型”拆为独立列,移除回读容差列,改为展示该写入点最近一次写入日志中的 `readback_value`;无回读记录时显示“—”。
|
||
- 写入点数据库迁移 `000003_write_points_simplify.up.sql` 合并 `enabled` 与 `write_enabled` 为单一 `write_enabled`,移除 `readback_tolerance`;迁移具备重启幂等性,旧数据先保留原有效权限再删除冗余列。
|
||
- 写入点新增/编辑表单移除回读容差和启用字段,仅保留统一的“允许写入”自定义复选框;CSV 导入/导出同步移除冗余字段。
|
||
- REAL 回读验证保留固定协议精度 `0.0001`,不再作为点位配置或 API 字段暴露。
|
||
- 真实环境回归:`GET /api/v1/write-points` 返回不含 `enabled`、`readback_tolerance`,分组接口同时返回 `collection_count` 与 `write_count`;写入点 CSV 表头已更新为 `write_enabled`。
|
||
- Playwright Chromium 1600×1000:写入页列表、共享分组筛选和新增弹窗均正常;弹窗无“启用/回读容差”,允许写入卡片可切换;控制台无 warning/error。未执行现场 PLC 写入,避免改变控制状态。
|
||
- 回归截图:`C:\Users\Administrator\AppData\Local\Temp\aquacontrol-write-point-table-final.png`、`C:\Users\Administrator\AppData\Local\Temp\aquacontrol-write-point-final.png`。
|
||
|
||
## 2026-07-12|三类数据页面刷新与采集点编辑修复
|
||
|
||
- 修复采集点编辑无法更换所属设备的问题:移除 PostgreSQL 更新语句中对 `history_started_at`、旧设备和旧数据类型的限制,编辑请求现在可以正常提交新的 `device_id`;前端保存失败时显示明确错误提示。
|
||
- 数据采集列表在质量列后新增“更新时间”,取点位 `updated_at` 并按中文本地时间格式展示。
|
||
- 数据采集、设备管理、数据写入均新增“刷新数据”按钮,刷新按钮执行期间禁用并显示旋转图标。
|
||
- 数据采集刷新同时重新加载采集点分组;采集点新增/编辑/删除及 CSV 导入后刷新列表和分组;设备新增/编辑/删除及 CSV 导入后刷新列表;写入点新增/编辑/删除、执行写入及 CSV 导入后刷新列表和共享分组。
|
||
- Playwright Chromium 1600×1000 回归:三个页面刷新按钮各 1 个;采集列表包含“更新时间”;编辑弹窗包含设备选择器;三个页面刷新交互无控制台 warning/error。现场 PLC 写入未执行。
|
||
- 回归截图:`C:\Users\Administrator\AppData\Local\Temp\aquacontrol-collection-refresh-final.png`。
|
||
- 更正“更新时间”字段:列表现在展示实时采集数据 `latest_value.ts`,不再展示配置的 `updated_at`。
|
||
|
||
## 2026-07-12|分组删除改为点位迁移
|
||
|
||
- 删除非 `default` 分组时,后端事务先将该分组下未逻辑删除的采集点和写入点统一迁移到 `default`,再删除分组记录;不再逻辑删除任何点位。
|
||
- 事务内确保 `default` 分组存在,`default` 分组仍禁止删除。
|
||
- 数据采集和数据写入页面的删除确认提示同步改为“自动转移到 default 分组”。
|
||
- 开发验证:使用临时写入点执行“建组→建点→删组”回归,点位保留且 `group_name` 已迁移为 `default`,随后清理临时点;Go 测试和静态检查、前端构建均通过,未执行现场 PLC 写入。
|
||
# 2026-07-12 · 历史数据增强与归档清理
|
||
|
||
## 需求分析
|
||
|
||
- 历史点位树支持分组折叠/展开、分组全选/取消;点位、时间范围和表格间隔变化后自动查询,保留最多 20 个点位限制。
|
||
- 曲线横轴必须与系统时间一致并按选择范围固定起止点;无数据序列不显示;bad 质量值使用虚线;图例状态保留并控制对应曲线;游标采用非吸附、带动画的轴指示器。
|
||
- 曲线高度提升,游标明细最多显示约 5 行并在点位较多时纵向滚动;表格点位列较多时横向滚动。
|
||
- 已逻辑删除点位的历史子表提供显式清理入口,禁用但仍可恢复的点位不纳入清理。
|
||
|
||
## 技术方案与变更
|
||
|
||
- PostgreSQL 新增只读查询已删除采集点 UUID 的方法;TDengine 新增按 UUID 派生子表的安全删除方法,API 增加 `POST /api/v1/history/archive/cleanup`,前端增加清理确认和结果反馈。
|
||
- TDengine REST 驱动返回的本地墙上时间改为显式重建为 `Asia/Shanghai`,避免重复施加时区偏移;表格时间列统一输出上海时区。
|
||
- 历史页面增加自动查询防抖和请求序列保护,曲线传入选定时间范围并动态设置时间刻度;bad 数据拆分为虚线序列,且共享逻辑图例名称。
|
||
|
||
## 验证记录
|
||
|
||
- `go test ./...`:通过。
|
||
- `npm run build`:通过;仅保留既有 ECharts 体积提示。
|
||
- `GET /api/v1/health`:真实 PostgreSQL/TDengine 配置下返回 `code=0`。
|
||
- Playwright Chromium 1600×1000:验证分组全选、点位变更自动曲线查询、曲线/表格切换自动查询、间隔变化自动表格查询;曲线高度 520px;控制台无错误。截图:`C:\Users\Administrator\AppData\Local\Temp\aquacontrol-history-curve-final.png`、`C:\Users\Administrator\AppData\Local\Temp\aquacontrol-history-final.png`。
|
||
- 归档清理接口真实回归时识别并清理了 13 个已逻辑删除点位的历史子表;活跃点位和仅禁用点位未清理。清理为不可逆操作,前端已增加二次确认。
|
||
|
||
## 2026-07-12 · 自定义时间与任意时刻游标
|
||
|
||
- 修复固定快捷范围切换后编辑自定义时间可能被旧范围覆盖的问题:时间输入在 `input` 和 `change` 阶段均同步,先保存被编辑的端点,再校验起止时间,允许用户分两步完成暂时不完整的自定义范围。
|
||
- 游标改为基于鼠标在时间轴上的实际像素位置换算时间,不再使用最近存储点作为游标时间;对每条曲线按前后有效样本进行线性插值,游标表格中的所有曲线使用同一时间戳,边界使用最近有效值,质量戳为 bad 或跨越 bad 样本时保留 bad 标识。
|
||
- 插值结果在游标表格中使用 `≈` 标记,ECharts 轴指示器继续关闭吸附并保留平滑动画;图例隐藏的曲线不参与游标结果。
|
||
|
||
## 2026-07-12 · 本轮验证
|
||
|
||
- Playwright 验证固定范围后编辑起止时间保持 `custom` 状态;鼠标移动到非存储时刻时,两条曲线游标显示相同时间 `2026/7/12 23:08:03`,无控制台错误。
|
||
|
||
## 2026-07-13 · 游标视觉跟随与离开区域保持
|
||
|
||
- 移除 ECharts 默认会吸附存储点的轴指示线,改用图表内独立的垂直游标线;鼠标像素位置先换算为时间,再用 `requestAnimationFrame` 更新线位置,避免在 ECharts 事件处理期间调用 `setOption`。
|
||
- 游标线仅覆盖绘图区,和插值明细使用同一时间;鼠标离开曲线区域不再清空最后一次游标时间和明细数据。
|
||
- 回归验证连续移动得到 `23:41:48`、`23:44:25`、`23:47:00`、`23:49:38` 四个不同时间点;离开图表后仍保留 2 条曲线明细,控制台无错误。
|
||
|
||
## 2026-07-13 · 设备状态与采集成功状态同步
|
||
|
||
- 根因:采集读失败后 `Manager` 将设备状态置为 `disconnected`;缓存连接后续读取成功时此前只更新点位最新数据,没有恢复设备状态,因此设备管理页持续显示离线。
|
||
- 修复:采集成功后调用 `Manager.MarkConnected` 恢复在线状态;`MarkConnected` 与 `MarkDisconnected` 仅在状态发生变化时更新时间戳,避免每个采集周期反复刷新最近在线/离线时间。
|
||
- 验证:真实环境中 PLC1、PLC2、PLC3 均显示 `connected`,40 个采集点的 `latest_value.ts` 持续更新;新增设备状态恢复及时间戳稳定性单元测试。
|
||
|
||
## 2026-07-13 · 启停流程文档与历史曲线断档修复
|
||
|
||
- 维护约定:从本次起,后续每次代码、配置、部署流程或验证方式调整,都必须同步记录到 `docs/development-log.md`。
|
||
- README 启停流程补充:明确项目按前后端分离运行;后端默认 `8080`,前端 Vite 默认 `5173`;应用不会自动读取 `.env`,启动后端前必须先在 PowerShell 中注入环境变量;补充后端、前端启动命令、健康检查命令和按端口停止服务命令。
|
||
- pnpm 构建脚本审批:将 `pnpm-workspace.yaml` 中 `allowBuilds.esbuild` 从占位值修正为 `true`,解决 `esbuild@0.25.12` postinstall 被拦截导致前端无法构建的问题。
|
||
- 启动验证:`.env` 已指向云端数据库,PostgreSQL `101.35.54.96:5432` 与 TDengine REST `101.35.54.96:6041` TCP 连通;`GET http://127.0.0.1:8080/api/v1/health` 与 `GET http://127.0.0.1:5173/api/v1/health` 均返回 `code=0`。
|
||
- 服务停止验证:停止后端 Go 进程与前端 Vite 进程后,`8080` 和 `5173` 均无监听进程。
|
||
- 历史曲线断档根因:曲线查询只返回真实采样点,停机或未采集时段没有显式空值断点;ECharts 在相邻有效点之间会直接连线,因此会把 2026-07-13 02:00 到 08:00 这类无数据时段渲染成连续曲线。
|
||
- 历史曲线修复:后端 `history/query` 按点位 `history_interval` 判断断档,相邻样本间隔超过 `3 × history_interval` 时插入 `value=null, quality=none` 断点;前端游标插值遇到空值或非 good 质量断点时不再跨断档估算,避免提示表显示伪造的连续值。
|
||
- 新增测试:`internal/service/platform/history_test.go` 覆盖长时间无数据插入断点、短时间采集抖动不误判断档。
|
||
- 验证:`go test ./...` 通过;`pnpm build` 通过,仅保留既有 ECharts chunk 体积提示;`pnpm lint` 未通过,原因为项目当前缺少 ESLint 9 所需的 `eslint.config.js`,不是本次变更引入。
|
||
|
||
## 2026-07-13 · TDengine 时间戳时区修复
|
||
|
||
- 现象:TDengine 工具中最新历史数据时间显示为 `2026-07-13 17:50:53.026`,比现场当前时间快 8 小时;页面实时数据时间显示正常。
|
||
- 根因:历史写入使用 `2006-01-02 15:04:05.000` 无时区格式,TDengine REST 链路按 UTC instant 存储;数据库工具按本地时区显示后形成 `+8h` 偏移。历史查询代码此前又把读回时间按上海墙上时间重建,导致页面显示正常但库内物理时间不一致。
|
||
- 验证:临时 TDengine 探测表写入同一时间的两种格式,`plain` 无时区读回为 `2026-07-13T10:10:10.123Z`,`rfc3339` 带 `+08:00` 读回为 `2026-07-13T02:10:10.123Z`,证明无时区写入会偏移 8 小时。
|
||
- 修复:TDengine 写入和查询时间字面量统一改为 RFC3339 样式 `yyyy-MM-ddTHH:mm:ss.SSS+08:00`;读回时间按真实 instant 转换为 `Asia/Shanghai`,不再重建墙上时间。
|
||
- 测试:新增 `TestTDTimeLiteralUsesShanghaiOffset`,锁定 TDengine 时间字面量必须带 `+08:00`。
|
||
- 验证:`go test ./...` 通过;`pnpm build` 通过,仅保留既有 ECharts chunk 体积提示。
|
||
- 运行验证:重启后端后,`8080` 后端健康检查与 `5173` 前端代理健康检查均返回 `code=0`;对点位 `1dd3c3c4-bb27-4b57-bd10-039a6e2a81d9` 查询 `2026-07-13T10:00:00+08:00` 到 `10:30:00+08:00` 区间,TDengine 返回新记录 `2026-07-13 10:05:41.002 +08:00`,证明新写入时间已按本地真实时间入库。
|
||
- 注意:修复只保证后续新写入数据时间正确;已经写入 TDengine 的旧历史行物理时间戳已偏移到未来,如需修正,需要在停采后执行一次受控数据回拨/重写操作,不能自动盲改。
|
||
|
||
## 2026-07-13 · TDengine 旧历史数据时间回拨
|
||
|
||
- 操作前先停止后端采集进程,确认 `8080` 无监听,避免迁移期间继续写入历史数据。
|
||
- 迁移范围:枚举 TDengine `collection_data` 下 40 张 `p_*` 点位子表,共 1562 行历史数据;dry-run 统计 1526 行为旧无时区写入数据,需要整体回拨 8 小时,36 行位于 `2026-07-13 10:00~10:30 +08:00` 修复后新写入窗口,保留原时间不动。
|
||
- 备份:执行前导出 JSONL 本地备份 `C:\Users\ADMINI~1\AppData\Local\Temp\aquacontrolai-tdengine-history-backup-20260713-101548.jsonl`,记录原始时间、修正后时间、点位、设备、质量和值。
|
||
- 修复方式:因时间戳为 TDengine 时序主键,不直接执行盲目 `UPDATE`;脚本逐表读取全量行、计算修正时间、检查修正后同表时间戳冲突,然后 `DROP TABLE` 子表并按原稳定表 `collection_data`、原标签和原数据列重建写回。
|
||
- 结果:实际执行后 `repair_complete rows=1562`,迁移前后总行数一致。
|
||
- 验证:全库最新时间由未来 `18:00` 左右恢复为 `2026-07-13 10:05:46.506 +08:00`;示例点位 `1dd3c3c4-bb27-4b57-bd10-039a6e2a81d9` 最新 5 条为 `10:05:41`、`10:00:53`、`09:50:53`、`09:48:52`、`09:43:55`;该点位 `2026-07-13 02:00~08:00 +08:00` 区间查询结果为 0 条。
|
||
|
||
## 2026-07-13 · 历史数据 CSV 导出列调整
|
||
|
||
- 需求:历史数据表格导出 CSV 时,每个测点只导出一列实际值,不再为每个测点额外导出“质量”列。
|
||
- 修复:`POST /api/v1/history/export` 表头从“时间 + 点位值列 + 点位质量列”改为“时间 + 每个点位一个值列”;行数据仅写入 `value`,无值时留空,不再输出 `good/bad/—` 质量文本。
|
||
- 验证:`go test ./...` 通过;重启后端后调用 `POST /api/v1/history/export` 导出点位 `1dd3c3c4-bb27-4b57-bd10-039a6e2a81d9` 的 `2026-07-13 09:40~10:10 +08:00` 数据,CSV 表头为 `时间,2区PAC投加流量[L/h]`,列数为 2,无质量列。
|
||
|
||
## 2026-07-13 · Modbus TCP 规格文档同步
|
||
|
||
- 根据当前代码和维护记录同步 `spec-数据管理.md`、`spec-历史数据.md` 与一致性决策基线:移除采集有效范围和写入点回读容差旧契约,补充分组表、设备最近在线/离线、写入点单一 `write_enabled`、采集调度/断线恢复当前机制、历史归档清理、断档点、TDengine `+08:00` 时间字面量和历史 CSV 无质量列规则。
|
||
- 明确 `MODBUS_TCP` 需要具备运行时连接、读写和 REAL 字节序适配能力,避免只停留在协议注册和地址校验。
|
||
|
||
## 2026-07-13 · Modbus TCP 运行时驱动
|
||
|
||
- 补齐 `internal/protocol/modbus` 运行时 TCP 客户端:实现 MBAP 报文、事务号校验、异常响应处理、FC1/2/3/4 读取、FC5/6/16 写入,以及 `ABCD/BADC/CDAB/DCBA` REAL 字节序转换。
|
||
- 新增地址校验与 `CDAB` REAL 编解码单元测试,并使用正式协议连接完成读、写和回读验证。
|
||
- 验证:`go test ./...` 通过。
|