Files
2026-07-27 16:46:15 +08:00

13 KiB
Raw Permalink Blame History

车辆数据开放平台 API

在线文档:

  • 简洁中文说明:/open-api/docs/
  • Swagger UI/open-api/swagger/
  • OpenAPI 3.0/open-api/openapi.yaml

Swagger 的认证信息仅保存在当前页面内存中,页面刷新后清除,不会由平台预填或持久化。

模块边界

一期向合作方开放经过预统计的车辆单日用氢量、单日里程和指定时刻总里程,并提供:

  • 32 位无连字符 UUID appKey
  • appKey 启停和起止有效期;
  • appKey 下的 VIN 白名单和逐车起止有效期;
  • 外部调用审计和管理员变更审计。

外部接口与平台后台登录令牌相互独立。appKey 明文只在创建或轮换时返回一次,数据库仅保存 SHA-256 和前 8 位展示前缀。

授权规则

Authorization: Bearer <32位appKey>
Content-Type: application/json

请求需要同时满足:

  1. appKey 状态为 enabled,当前调用时间在 Key 有效期内;
  2. 查询自然日完整落在 Key 有效期内;
  3. 每辆车的授权完整覆盖查询自然日;
  4. 车牌能映射到授权 VIN。

任一车辆未授权时整批返回 403 FORBIDDEN,不会返回部分结果。单日聚合不开放授权首日或结束日的半日数据。

单日用氢量

POST /api/v1/vehicles/hydrogen-consumption/query
{
  "plateNumbers": ["粤A12345", "粤B67890"],
  "date": "2026-07-01"
}

plateNumbers 可选。省略或传空数组时,返回应用在该自然日有效授权的全部车辆;传入时最多 200 个,不允许空字符串或重复值。date 固定为 yyyy-MM-dd

查询全部授权车辆:

{
  "date": "2026-07-01"
}
{
  "code": "SUCCESS",
  "message": "success",
  "data": [
    {
      "vin": "LNB00000000000001",
      "plateNumber": "粤A12345",
      "date": "2026-07-01",
      "hydrogenConsumptionKg": 12.315,
      "status": "NORMAL"
    },
    {
      "plateNumber": "粤B67890",
      "date": "2026-07-01",
      "hydrogenConsumptionKg": null,
      "status": "NO_DATA"
    }
  ],
  "traceId": "4ccf63c4e51d4d4ab9107d931783a53e"
}

单日里程

POST /api/v1/vehicles/mileage/query

date 和可选 plateNumbers 外,里程接口支持可选的 protocolPriority

{
  "plateNumbers": ["粤A12345"],
  "date": "2026-07-01",
  "protocolPriority": ["GB32960", "MQTT", "JT808"]
}

外部协议值只允许 GB32960MQTTJT808。传入时数组必须非空、不能重复;每辆车独立按数组顺序选择第一个有效协议,未列出的协议被完全禁用,不能兜底。不传该字段时保持现网默认选源行为。

支持的典型模式包括:["GB32960","MQTT","JT808"]["JT808","GB32960","MQTT"]["GB32960","MQTT"]["JT808"]

{
  "code": "SUCCESS",
  "message": "success",
  "data": [
    {
      "plateNumber": "粤A12345",
      "date": "2026-07-01",
      "dailyMileageKm": 182.437,
      "totalMileageKm": 12345.679,
      "dataTime": "2026-07-01T23:58:45+08:00",
      "updatedAt": "2026-07-02T05:10:00+08:00",
      "sourceProtocol": "GB32960",
      "status": "NORMAL"
    }
  ],
  "traceId": "b7ff5582ab1a4e13bfb4f10943685599"
}

dailyMileageKm 表示该自然日行驶里程;totalMileageKm 表示同一协议统计记录在该日最后有效时刻的累计总里程;sourceProtocol 是该行实际选中的协议;dataTime 是统计实际采用的最后一条车辆源数据时间;updatedAt 是日统计投影最后更新时间。时间均为带 +08:00 的 ISO 8601。

status=NORMAL 时数据字段均有值;任一关键字段缺失时整车返回 NO_DATA,相关数据字段和 sourceProtocol 均为 null。真实零日里程返回 NORMALdailyMileageKm: 0

里程与时间字段始终取自 sourceProtocol 指定的同一协议统计记录,不跨协议拼接。内部数据源 YUTONG_MQTT 对外统一返回 MQTT

当查询日没有任何有效日里程和累计总里程,但查询日前存在有效累计里程时,接口执行前向填充:

  • dailyMileageKm 返回 0
  • totalMileageKm 沿用此前最近的有效累计总里程;
  • sourceProtocoldataTime 沿用该历史统计记录;
  • updatedAt 返回上一个有效统计周期的计算时间,不伪装成查询日计算时间;
  • 只有查询日前也不存在有效累计里程时才返回 NO_DATA

区间日里程

POST /api/v1/vehicles/mileage/range/query

最长支持 366 天。plateNumbers 可省略,省略时查询整个区间均有效授权的全部车辆;指定时最多 5,000 个。pageSize 为 15,000默认 5,000。

首次请求:

{
  "startDate": "2026-07-01",
  "endDate": "2026-07-23",
  "protocolPriority": ["JT808", "GB32960", "MQTT"],
  "pageSize": 5000
}

响应:

{
  "code": "SUCCESS",
  "message": "success",
  "data": [
    {
      "vin": "LNB00000000000001",
      "plateNumber": "粤A12345",
      "date": "2026-07-01",
      "dailyMileageKm": 182.437,
      "totalMileageKm": 12345.679,
      "dataTime": "2026-07-01T23:58:45+08:00",
      "updatedAt": "2026-07-02T05:10:00+08:00",
      "sourceProtocol": "JT808",
      "status": "NORMAL"
    }
  ],
  "snapshotId": "9f8a74efbf9846349ae5676f3a5c0de8",
  "nextCursor": null,
  "traceId": "4ccf63c4e51d4d4ab9107d931783a53e"
}

protocolPriority 的校验、选源和缺日前向填充规则与单日接口完全一致,并对区间内每辆车、每个自然日独立执行。有下一页时,保持 startDateendDateplateNumbersprotocolPrioritypageSize 不变,把上一页 nextCursor 放入下一次请求。同一次查询的 snapshotId 保持不变。快照有效期为 2 小时。

接口只固化授权车辆清单,不预生成“车辆数 × 天数”的明细;每页读取带复合索引的日统计投影,因此大范围查询不会扫描原始时序明细。

指定时刻总里程

POST /api/v1/vehicles/total-mileage/query

接口返回“不晚于请求时间的最近一条有效总里程记录”。time 使用北京时间,格式必须为 yyyy-MM-dd HH:mm:ss

{
  "vin": "LA9GG68L2PBAF4790",
  "time": "2026-07-21 09:30:00",
  "protocol": "GB32960"
}

protocol 可选,只接受车辆数据中台、接收、统计和开放平台共同使用的唯一规范值:GB32960YUTONG_MQTTJT808。不再接受 32960mqtt808 等别名。未指定时严格按以下优先级查找首个有数据的协议:

GB32960 > YUTONG_MQTT > JT808

协议总里程含义:

协议 含义
GB32960 车辆仪表盘累计总里程,对应 GB/T 32960 整车数据累计里程
YUTONG_MQTT 车辆仪表盘或车端控制器累计总里程,由 MQTT 平台上报
JT808 定位终端累计里程,由 GPS/终端侧计算,不等同于车辆仪表盘里程

三种协议可能使用不同里程源、标定值和重置机制,不能直接拼接成同一条连续里程曲线。响应会返回实际命中的协议和记录时间,调用方应结合时间差判断记录是否足够新。

{
  "code": "SUCCESS",
  "message": "success",
  "data": {
    "vin": "LA9GG68L2PBAF4790",
    "queryTime": "2026-07-21 09:30:00",
    "totalMileageKm": 12345.678,
    "protocol": "GB32960",
    "protocolInput": "GB32960",
    "mileageMeaning": "车辆仪表盘累计总里程GB/T 32960整车数据累计里程",
    "recordTime": "2026-07-21 09:29:45",
    "timeDifferenceSeconds": 15,
    "selectionPolicy": "GB32960 > YUTONG_MQTT > JT808",
    "status": "NORMAL"
  },
  "traceId": "95bddca78133474fa2bf56ecdf758e22"
}

字段说明:

  • recordTime:实际命中的采集记录时间;
  • timeDifferenceSecondsqueryTime - recordTime,单位秒,正常为非负数;
  • protocol:实际采用的采集协议,而不是默认优先级描述;
  • NO_DATA:授权通过,但所有候选协议在请求时间之前都没有有效总里程。

错误码

HTTP code 说明
400 INVALID_REQUEST 请求结构、车牌或数量不正确
400 INVALID_DATE_FORMAT 日期不是 yyyy-MM-dd
400 INVALID_DATETIME_FORMAT 时间不是 yyyy-MM-dd HH:mm:ss
401 UNAUTHORIZED appKey 不存在、停用或过期
403 FORBIDDEN Key 或车辆授权未覆盖查询自然日
500 INTERNAL_ERROR 服务内部异常

管理 API

管理 API 使用车辆数据平台后台 Bearer Tokenadmin 可调用。

POST /api/v2/open-platform/apps
GET  /api/v2/open-platform/apps
PUT  /api/v2/open-platform/apps/{id}
POST /api/v2/open-platform/apps/{id}/rotate-key
GET  /api/v2/open-platform/apps/{id}/vehicles
PUT  /api/v2/open-platform/apps/{id}/vehicles
GET  /api/v2/open-platform/users
POST /api/v2/open-platform/users
PUT  /api/v2/open-platform/users/{id}
GET  /api/v2/open-platform/users/{id}/apps
PUT  /api/v2/open-platform/users/{id}/apps

创建应用:

{
  "name": "示例合作方",
  "status": "enabled",
  "validFrom": "2026-07-01T00:00:00+08:00",
  "validTo": "2027-07-01T00:00:00+08:00"
}

创建和轮换响应中的 data.appKey 是唯一一次明文交付机会。轮换后旧 Key 立即失效。

车辆授权 PUT 使用完整替换语义,单次最多 5000 辆:

{
  "vehicles": [
    {
      "vin": "LTEST32960VIN0001",
      "validFrom": "2026-07-01T00:00:00+08:00",
      "validTo": "2027-07-01T00:00:00+08:00"
    }
  ]
}

VIN 必须已存在于平台身份绑定表。

管理员可以从车辆目录按 VIN、车牌或品牌搜索并勾选也可以批量粘贴 VIN 或车牌自动匹配,或者一次选择当前车辆主数据中的全部车辆。批量匹配会报告 未识别项,不会静默忽略。“全部车辆”是保存时点的车辆快照,不会自动包含 以后新增的车辆。

管理端可通过下列接口读取可授权车辆目录:

GET /portal-api/admin/vehicles
Authorization: Bearer <admin-token>

合作伙伴用户可配置账号有效期,并通过 ownerdeveloperviewer 角色绑定一个或多个应用。密码至少 12 位且必须同时包含大小写字母和数字。 连续 5 次登录失败后账号锁定 15 分钟。

内部车辆平台中启用的本地 admin 账号可使用同一用户名和密码登录开放平台。 开放平台校验内部密码哈希后签发独立会话,不复制密码,也不共享两个域名的 浏览器 Token。管理员可在“平台管理”中创建开放应用、合作伙伴账号并配置 车辆与授权有效期。

合作伙伴门户

独立开放平台默认监听 20310,不再与内部平台 20300 共用外部 HTTP 入口。门户 API 使用短期会话 Token数据 API 仍使用应用的 32 位 AppKey。

POST /portal-api/auth/login
POST /portal-api/auth/logout
GET  /portal-api/session
GET  /portal-api/catalog
GET  /portal-api/apps
GET  /portal-api/apps/{id}/vehicles
GET  /portal-api/apps/{id}/audit
POST /portal-api/apps/{id}/rotate-key
PUT  /portal-api/account/password

只有应用 owner 可以在门户轮换 AppKey新 Key 仍只显示一次。门户登录、 密码修改、用户配置和密钥操作均写入审计表。

用氢量统计

当天数据由 vehicle-stat-writer 直接消费 GB32960 fields Kafka 流,统一采用压力法:

剩余氢量 kg = NIST氢气密度(最高氢压 MPa, 最高氢温 ℃) × 车型氢瓶容量 L / 1000
  • 不使用广东扩展直接上报的剩余氢量、飞驰剩余百分比或百公里氢耗推算质量;
  • vehicle-stat-writer 每六小时从 ln_asset_management.vehicle_info → vehicle_model.tank_capacity 同步 VIN 容积到本地 vehicle_hydrogen_tank_capacity
  • 同步完成后一次性加载到进程内存高频帧计算不访问资产库、Redis或MySQL缺少VIN容积时拒绝生成氢量
  • 压力法使用 NIST 实氢气密度方程,允许 070 MPa、2201000 K 的输入范围。

每个有效样本在同一个 MySQL 事务中更新 vehicle_open_hydrogen_stream_state,并投影到 vehicle_open_daily_energy。Kafka offset 只在事务提交成功后提交,因此服务重启或消息重放不会重复累计。状态按 VIN + 日期 + source_endpoint 保存,每条消息只做常数次数据库操作,不扫描当天历史数据。

统计规则:

  • 先按 VIN 和 source_endpoint 分别统计,避免多个采集源的序列交错产生虚假变化;
  • 同一 VIN 优先采用质量正常、样本数量更多的数据源,并记录入库;
  • 每次加氢之间维护质量低水位,只累计新的有效最低质量,避免压力温度波动反复计量;
  • 抖动阈值按该VIN容积对应的 0.2 MPa 质量变化动态计算,最小 0.05 kg、最大 1 kg
  • 质量相对本轮低水位上升超过 max(1 kg, 当前质量×5%) 时识别为加氢并重置低水位;
  • 单次下降超过 OPEN_STAT_HYDROGEN_MAX_DROP_KG 时过滤并标记 SUSPECT,默认 20 kg
  • 至少两条有效样本才标记 OK
  • 对外只返回 quality_status=OK 的结果。

当天接口结果是准实时的进行中累计值。乱序、重复和迟到样本不会覆盖更新的状态;跨日迟到数据由 open-platform-stat 夜间批处理兜底。批处理默认重算昨天和前天,以修正迟到上报,并作为已结束日期的权威结果。

/opt/lingniu-vehicle-platform/current/open-platform-stat \
  -date 2026-07-01 \
  -lookback-days 1

systemctl enable --now lingniu-vehicle-open-stat.timer