oscbridge

    Checked COMTRADE ASCII recording windows through existing MoonArrow IPC

    comtrade
    arrow
    waveform
    data-validation
    Download zip
    Version
    0.1.0
    License
    MIT
    Last updated
    6 hours ago
    Downloads
    1

    Dependencies

    #Oscbridge:COMTRADE 记录检查与 Arrow 窗口交换

    本地换题候选;尚未创建公开仓库。当前模块名 dongxuan2012/oscbridge 按拟交付账号命名,账号归属、正式仓库与报名换题仍须由团队核实。

    将电力录波的一对 CFG/DAT 作为一个整体检查,按相对时间选择窗口,把样本身份、原始计数、声明侧标定值和状态字段交给现有 MoonArrow 写入 Arrow IPC。下游可以用已有 Arrow 工具消费数据,不必重新实现 COMTRADE 读取和单位映射。

    这里解决的是接收与交换中的可检查约束:错配的通道/行数、时间间隔不一致、无法表示的相邻时间、越界数值,以及窗口抽取后采样号和标定信息丢失。它不识别故障,不提供继电保护结论。

    #与已有工作的关系

    已有工作复用或比较关系
    MoonArrow 0.1.0运行时直接依赖,负责列类型、schema、IPC 编解码;不复制其实现
    python-comtrade成熟的独立读取参考;本项目不是算法首创或对它的全面替代
    OscGrid已有 Python 数据处理和切窗流程;这里的增量是 MoonBit 可调用的数据合同与列式交换接口
    PyArrow独立读取并核对实际产出;仅用于验证,不进入产品运行核心

    公开搜索没有找到同名 MoonBit 接口不能证明“生态空白”。本项目没有已确认采用方,公开研究数据也不冒充客户案例。支持范围、失败行为与未实现项见 PROFILE.md。

    #构建与调用

    已使用的 MoonBit 版本见 .moonbit-version。Node 文件入口要求 Node 24,Python 只用于复现独立验证。

    moon update moon test --target js moon test --target wasm-gc moon build --target js --release cmd/arrow node bin/oscbridge.mjs export input.cfg input.dat new-window.arrow 1 1.1 10000

    不下载公开大文件也能运行最小样例:node examples/small-window.mjs。它读取仓库内两行合成 CFG/DAT,抽取第二行并检查生成的 Arrow 文件;CI 每次提交都运行此样例。

    输出必须是新文件名,所在目录须存在并支持硬链接。窗口是 [1,1.1);预算不足时报错,不截断。成功时 stdout 给出输入和 IPC 哈希回执,失败返回非零。

    MoonBit 程序导入根包与 /arrow 包即可使用,不必经过 Node 文件入口:

    let recording = @oscbridge.parse(cfg_text, dat_text)
    let ipc = @oscbridge_arrow.write_window(recording, 1.0, 1.1, 10000)

    上述代码位于可抛错函数中;导入别名分别配置为 @oscbridge 和 @oscbridge_arrow。调用方可先通过 Recording::window 检查窗口,再把 Bytes 交给自己的存储层。

    #可复现输入与证据

    公开样本、许可、固定哈希与获取步骤见 USE-CASE.md;核验状态只以 evidence/ 中的实际回执为准。升级到 moonc 0.10.14 后,10400 行公开记录与 PyArrow/comtrade 的复核结果见 2026-09-28 回执。支持 COMTRADE-1999 ASCII 单速率、零 skew 的严格子集,保留 DAT 相对时间与 P/S 声明侧;不宣称完整标准兼容、UTC 对齐、全来源适配或真实用户采用。

    代码采用 MIT;公开输入及其派生 IPC 采用源数据 CC BY 4.0 要求。原始 95 MB 归档不随代码分发,署名与变换说明见 THIRD-PARTY-NOTICES.md。

    #本地验收与公开交付(2026-09-28)

    核心实现使用 MoonBit;固定编译器为 moonc 0.10.14+7d59c7ec9。先按本文安装宿主依赖、运行 moon update,再从仓库根目录执行以下与 CI 对齐的检查;可运行任务和适用边界见本文前面的示例与说明。

    moon check --target js --deny-warn moon check --target wasm-gc --deny-warn moon test --target js --deny-warn moon test --target wasm-gc --deny-warn moon build --target js --release cmd/arrow --deny-warn moon package

    跨平台复核(2026-09-28,本地 Ubuntu-D 26.04 WSL2):从当时的源码归档全新解包,固定 moonc 0.10.14+7d59c7ec9 下通过 moon update、moon fmt --check、moon info、严格检查、JS/Wasm-GC 测试及 JS release 构建;Node 24.21.0 跑通本仓一条宿主入口。本次补记仅修改文档,代码与 CI 未变;复核日志在本地交接包中,公开提交后的 GitHub Actions 仍须单独核对。

    本地核验:JS/Wasm-GC 各 6 项测试、仓内两行 Arrow 示例通过;10400 行公开录波又经独立 COMTRADE 读取器与 PyArrow 核对,另有 6 项宿主失败边界检查。 moon package 已完成离线打包预检,它不等于已发布到 Mooncakes。

    公开交付(2026-09-28 核对):尚无本项目正式公开仓库 URL 或 Mooncakes 版本;模块名 dongxuan2012/oscbridge 是拟交付账号形式的本地名称,正式发布前须核实账号归属和发布权限;换题资格、仓库、公开 CI 和首次发布均待团队办理,不能沿用旧题仓库链接。相关远端 CI 与赛事结果仍需以实际记录核对。项目许可见 LICENSE;如使用第三方材料,其来源和许可见仓内相应说明。

    ComtradeError

    pub suberror ComtradeError {
    Rejected(String, Int, String)
    } derive(
    Debug
    )

    Fail-closed parse, bounds, or window error. Line is one-based for source errors and zero for API-argument errors.

    AnalogChannel

    pub(all) struct AnalogChannel {
    number : Int
    number_raw : String
    name : String
    phase : String
    circuit : String
    unit : String
    scale_a : Double
    scale_a_raw : String
    offset_b : Double
    offset_b_raw : String
    minimum : Double
    minimum_raw : String
    maximum : Double
    maximum_raw : String
    primary : Double
    primary_raw : String
    secondary : Double
    secondary_raw : String
    pors : String
    cfg_line_raw : String
    }

    Analog CFG metadata. scaled yields a*raw+b on the side declared by pors; it never applies a primary/secondary ratio conversion. Raw lexemes remain available for audit and output metadata.

    AnalogChannel::scaled

    fn AnalogChannel::scaled(self : AnalogChannel, raw : Double) -> Double raise ComtradeError

    Recording

    pub struct Recording {
    // private fields
    }

    A checked single-rate ASCII COMTRADE profile. Array storage is explicitly private; getters return detached metadata and windows contain deep copies.

    Recording::analog_channels

    fn Recording::analog_channels(self : Recording) -> Array[AnalogChannel]

    Recording::device_id

    fn Recording::device_id(self : Recording) -> String

    Recording::nominal_frequency_hz

    fn Recording::nominal_frequency_hz(self : Recording) -> Double

    Recording::revision

    fn Recording::revision(self : Recording) -> Int

    Recording::sample_count

    fn Recording::sample_count(self : Recording) -> Int

    Recording::sampling_rate_hz

    fn Recording::sampling_rate_hz(self : Recording) -> Double

    Recording::start_datetime_raw

    fn Recording::start_datetime_raw(self : Recording) -> String

    Recording::station_name

    fn Recording::station_name(self : Recording) -> String

    Recording::status_channels

    fn Recording::status_channels(self : Recording) -> Array[StatusChannel]

    Recording::time_multiplier

    fn Recording::time_multiplier(self : Recording) -> Double

    Recording::total_channels

    fn Recording::total_channels(self : Recording) -> Int

    Recording::trigger_datetime_raw

    fn Recording::trigger_datetime_raw(self : Recording) -> String

    Recording::window

    fn Recording::window(self : Recording, start_seconds : Double, end_seconds : Double, max_rows? : Int) -> Window raise ComtradeError

    Select samples in [start_seconds, end_seconds). A zero-width interval is valid and returns an empty caller-owned snapshot. The row and shared channel-value budgets are checked before output arrays are copied.

    Sample

    pub(all) struct Sample {
    sample_number : Int
    raw_ticks : Int64
    time_seconds : Double
    analog_raw : Array[Double]
    status : Array[Bool]
    }

    One data row. Instances returned by Recording::window own fresh value arrays and do not alias the recording's internal buffers.

    StatusChannel

    pub(all) struct StatusChannel {
    number : Int
    number_raw : String
    name : String
    phase : String
    circuit : String
    initial_value : Int
    normal_state_raw : String
    cfg_line_raw : String
    }

    Digital/status CFG metadata. The profile admits only binary values 0 and 1.

    Window

    pub(all) struct Window {
    start_seconds : Double
    end_seconds : Double
    analog_channels : Array[AnalogChannel]
    status_channels : Array[StatusChannel]
    samples : Array[Sample]
    }

    A caller-owned snapshot for a left-closed, right-open interval.

    parse

    fn parse(cfg : String, dat : String) -> Recording raise ComtradeError

    The trial profile is intentionally narrower than IEEE C37.111: revision 1999 declaration, ASCII DAT, one positive sampling-rate segment, zero analog skew, finite bounded values, and binary status values only.