现场收资接入_v0.1.md 8.6 KB

现场收资接入(v0.1,2026-09-17)

面向:现场交来的 F:\temp\如东风场数据 这一类目录 → 观澜的 data/raw/<场站>/。 工具:scripts/extract_site_data.py(纯标准库 + 系统 ODBC,不新增任何 pip 依赖)。


1. 现场交来的东西长什么样(2026-09-17 实测)

文件 体量 内容 用途
10分钟数据.zip 3,760 MB 38 件 WTG01.csv … WTG38.csv,表头 TimeStamp,WTG,StationId,cnt_wtc_… 10 分钟 SCADA(观澜 scada_10min 的正源)
1分钟数据.zip 1,548 MB 38 件 01E.csv … 38B.csv(机组代号命名),表头 time_stamp,3#桨电机温度,…(中文列) 1 分钟 SCADA(观澜 scada_1min 的正源)
25年.zip 1,071 MB 25年/<月>/2025-<月>-<类>.zip → .mdb(Access) 分类深度源(每月 12 类)
26年.zip 961 MB 26年/<月>/2026-<月>-<类>.zip → .mdb 同上

年度 zip 内的类目(每月一套):cnt din dot flg grd int prs scd std sum tmp tur。 实测 std.mdb 只有一张表 tblGrid:

TimeStamp | Station | WPSStatus | TimestampStation | CurrentL1..L3 | VoltageL1..L3 |
ActivePower | ReActivePower | ActivePowerExport | ReActivePowerExport | …(23 列)

TimeStamp 为 10 分钟节拍,Station 为机组号(如 91/92)。

2. 接入观澜(命令)

# ① 对账:现场 zip ↔ 现有 data/raw(逐件比大小,不解压十几 GB 就能验,幂等)
python scripts/extract_site_data.py --src "F:\temp\如东风场数据" --verify-raw
#    实测: 10分钟数据.zip → data/raw/如东/scada_10min  38/38 同大小
#          1分钟数据.zip → data/raw/如东/scada_1min    38/38 同大小  ⇒ 现有 raw 输入可追溯

# ② 提取(幂等;已有同大小文件即跳过;--only-missing 只补缺件)
python scripts/extract_site_data.py --src "F:\temp\如东风场数据" --extract-csv --only-missing

# ③ 年度 MDB(深度源)—— 只看结构 / 解出 / 探针
python scripts/extract_site_data.py --src "F:\temp\如东风场数据" --list
python scripts/extract_site_data.py --src "F:\temp\如东风场数据" --extract --year 26 --month 1
python scripts/extract_site_data.py --src "F:\temp\如东风场数据" --probe --class std

# ④ 接上观澜既有链路(体检 → 重算)
python scripts/raw_data_check.py            # 结构/增量/时间空洞体检(R1–R8)
python scripts/rebuild_all.py               # 或门户「数据重算」

3. 读 Access .mdb 的路线(离线、零 pip 依赖)

平台 用什么 前提
Windows .NET System.Data.Odbc + 系统 Microsoft Access Driver (*.mdb, *.accdb) 装了 Office 或 Access Runtime 的机器自带;本机实测可用
Linux mdbtools 的 mdb-export / mdb-tables apt/yum install mdbtools

两条路本器都会先探针:--probe 缺能力时给补救办法并返回 rc=4,不静默、不猜。 (刻意不把 pyodbc 之类的包塞进交付包:ODBC 驱动是系统级前提,装了包也解决不了;改成"探针 + 明确补救"更诚实。)

4. 从 MDB 转 CSV(--to-csv)

python scripts/extract_site_data.py --src <…> --to-csv --class std [--year 26 --month 1] [--turbines WTG01,WTG02]

  • 落点按类目映射:CLASS_TO_RAW(std → scada_10min;其余类目待现场口径确认后才接,未确认前不硬接);
  • 机组号映射:Station 起点 90 ⇒ WTG01(实测 std.mdb 里 Station=91/92);
  • 时间列统一改名 Time,逐机组落 data/raw/如东/<类>/WTG<NN>.csv,追加式写入(同一机组多月叠加)。

5. 还没有的输入(如实列)

观澜要的类 现状 缺什么
故障报警 16 件 2025Q1.xls …(已有) —
风机故障记录 10 件(*.rar / *.xlsx) —
油样报告 0 件 现场 PDF 报告
windcms / m5_cms_tcm 0 件 振动侧 CMS 导出件(取料单第 7、8 项)

6. 落位约定(用户令 2026-09-17:用年度 MDB 归档取代此前的两个 CSV zip)

<安装目录>/data/raw/如东/
├─ scada_mdb/            ← ★ 现场原始收资(Access 按月分类),就地归档
│   ├─ 25年.zip          (1,071,376,695 B, sha256 E451FF68…;内层 25年/1-12月/2025-<月>-<类>.zip)
│   └─ 26年.zip          (1,007,354,282 B, sha256 0B641309…;内层 26年/1-9月/2026-<月>-<类>.zip)
├─ scada_10min/          38 件 WTG01..WTG38.csv(源: 10分钟数据.zip,已对账 38/38 同大小)
├─ scada_1min/           38 件 01E..38B.csv(源: 1分钟数据.zip,已对账 38/38 同大小)
├─ 故障报警/ 风机故障记录/ 油样报告/ windcms/ m5_cms_tcm/
  • 为什么要单开 scada_mdb/:年度归档里是每月 12 类的 Access 库(cnt din dot flg grd int prs scd std sum tmp tur),不是"一台一个 CSV",硬塞进 scada_10min/ 会破坏该目录"平铺 <机组>.csv"的约定。
  • 目录已登记进两份真源:src/windscada/config.py::STATION_SUBDIRS 与 scripts/raw_data_check.py::EXPECT(允许 .zip 原样归档与 .mdb 解出件)⇒ 现场收资体检认它, 不再报"未约定的子目录"。
  • 工具直接吃这个目录(不必再指向 F:\temp): python scripts/extract_site_data.py --src data/raw/如东/scada_mdb --list ⇒ 实测 25年.zip:12 个月 · 12 类;26年.zip:9 个月 · 12 类。

⚠️ 尚未做的一步(等你定):把年度 zip 解出(每月 12 个 .mdb,约十几 GB), 以及是否把 MDB 转成 scada_10min/、scada_1min/ 的 CSV(即"用 MDB 取代现有 CSV")。 }这个决定会影响现有 27 GB 的 CSV 输入要不要保留, 故先只做"放进去"这一步。


7. CSV → MDB(用户令 2026-09-17:仿照 25年.zip/26年.zip 的形态)—— 探路结果

7.1 目标形态(照现场归档抄)

<年>年.zip → <年>年/<月>月/<年>-<月>-<类>.zip → <年>-<月>-<类>.mdb

现场每月 12 类(cnt din dot flg grd int prs scd std sum tmp tur),每类一个 MDB、库内一张表 (如 tblGrid,用 Station 区分机组)。本器同构产出,类名沿用现场叫法:10min / 1min。

7.2 两条必须偏离现场形态的硬限制(Access 引擎,绕不过)

限制 实测冲突 处置
单表 ≤ 255 列 scada_10min/WTG01.csv = 598 列(scada_1min/01E.csv = 79 列) 每库按列拆表 t1/t2/t3(建议每片 250 列),各表首列放 rid 行号便于对齐
单 MDB ≤ 2 GB scada_10min 14.4 GB + scada_1min 12.8 GB 按月分库(不可按年一个库)

7.3 写 MDB 的能力与路线(本机实测,2026-09-17)

  • ✅ 建库可用:ADOX.Catalog COM + Microsoft.ACE.OLEDB.12.0/16.0 提供程序(64 位 PowerShell 下实测 可实例化、$cat.Create("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=x.mdb;") 成功建出 180 KB 库)。
  • ❌ SELECT … INTO [文本源] 不支持:实测报「这种对象类型不支持该操作」。
  • ❌ 用目标库连接去 INSERT INTO … SELECT * FROM [text;…] 也不支持:同样报该错。
  • ✅ 可行方向(下一步要落的就是它):反过来的写法 —— 连接文本源, 用 Jet 的链接语法指向目标库:INSERT INTO [;DATABASE=<目标.mdb>;].[表名] SELECT * FROM [<分片>.csv] (实测语法已被接受:报的是「INSERT 语句语法错误」而非「不支持该操作」;当时两点没对上 —— 方括号里要带结尾分号 [;DATABASE=…;],且目标表列数/列序要与 CSV 完全一致)。
  • ⚠ Linux 侧只能读不能写:mdbtools 无写库能力 ⇒ MDB 生成请在 Windows 上做(或让现场直接给 MDB)。
  • ⚠ 中文字段名(1 分钟数据是中文列名):文本 ISAM 需配 schema.ini(CharacterSet=65001,UTF-8), 否则中文列名/值会按 ANSI 代码页解错。

7.4 尚未做的(下次接手的最短路径)

  1. 在 scripts/extract_site_data.py 增 --csv-to-mdb --month <YYYY-MM> --class {10min,1min}: 按月过滤 → 按 250 列切片写临时分片 CSV(首列 rid)→ 建库 → 按列生成 DDL(CREATE TABLE)→ 按 §7.3 的链接语法 INSERT … SELECT → 打成同名 zip → 读回校验行数/首末行与源 CSV 一致;
  2. 试点:--month 2025-01 --turbines WTG01(1 台 1 月)跑通并逐值对拍;
  3. 全量:38 台 × 21 个月(10min 3 张表/月、1min 1 张表/月),按 §7.2 按月分库。