# 现场收资接入(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. 接入观澜(命令) ```bash # ① 对账:现场 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.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 输入要不要保留, 故先只做"放进去"这一步。