13 KiB
车辆数据开放平台 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
请求需要同时满足:
- appKey 状态为
enabled,当前调用时间在 Key 有效期内; - 查询自然日完整落在 Key 有效期内;
- 每辆车的授权完整覆盖查询自然日;
- 车牌能映射到授权 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"]
}
外部协议值只允许 GB32960、MQTT、JT808。传入时数组必须非空、不能重复;每辆车独立按数组顺序选择第一个有效协议,未列出的协议被完全禁用,不能兜底。不传该字段时保持现网默认选源行为。
支持的典型模式包括:["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。真实零日里程返回 NORMAL 和 dailyMileageKm: 0。
里程与时间字段始终取自 sourceProtocol 指定的同一协议统计记录,不跨协议拼接。内部数据源 YUTONG_MQTT 对外统一返回 MQTT。
当查询日没有任何有效日里程和累计总里程,但查询日前存在有效累计里程时,接口执行前向填充:
dailyMileageKm返回0;totalMileageKm沿用此前最近的有效累计总里程;sourceProtocol、dataTime沿用该历史统计记录;updatedAt返回上一个有效统计周期的计算时间,不伪装成查询日计算时间;- 只有查询日前也不存在有效累计里程时才返回
NO_DATA。
区间日里程
POST /api/v1/vehicles/mileage/range/query
最长支持 366 天。plateNumbers 可省略,省略时查询整个区间均有效授权的全部车辆;指定时最多 5,000 个。pageSize 为 1–5,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 的校验、选源和缺日前向填充规则与单日接口完全一致,并对区间内每辆车、每个自然日独立执行。有下一页时,保持 startDate、endDate、plateNumbers、protocolPriority 和 pageSize 不变,把上一页 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 可选,只接受车辆数据中台、接收、统计和开放平台共同使用的唯一规范值:GB32960、YUTONG_MQTT、JT808。不再接受 32960、mqtt、808 等别名。未指定时严格按以下优先级查找首个有数据的协议:
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:实际命中的采集记录时间;timeDifferenceSeconds:queryTime - 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 Token,仅 admin 可调用。
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>
合作伙伴用户可配置账号有效期,并通过 owner、developer、viewer
角色绑定一个或多个应用。密码至少 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 实氢气密度方程,允许 0–70 MPa、220–1000 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