openydt-shared

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

openydt CLI 共享基座

openydt CLI Shared Base

本技能是艾科智泊停车开放平台 CLI(
openydt
)的共享基础规则。所有 openydt 域技能(park / parking / trade / coupon / ticket / device / blacklist / visitor / data 等)在执行具体任务前,都应先 Read 本文件,以统一处理配置、签名、状态码、限速与安全。
openydt
把开放平台接口封装成命令行:自动处理签名鉴权(v2/v3)、多授权商 profile、多环境(test/dev/prod),并内置重试与退避。
This skill is the shared basic rule for the Aike Smart Parking Open Platform CLI (
openydt
). All openydt domain skills (park / parking / trade / coupon / ticket / device / blacklist / visitor / data, etc.) should read this document first before executing specific tasks to unify configuration, signature, status code, rate limiting and security handling.
openydt
encapsulates the open platform interfaces into command-line commands: it automatically handles signature authentication (v2/v3), multi-authorizer profiles, multi-environments (test/dev/prod), and has built-in retry and backoff mechanisms.

配置 profile 与凭据

Configure Profiles and Credentials

凭据按「授权商 profile」管理,每个 profile 含 key/secret/env/sign。配置文件位于
~/.config/openydt-cli/config.json
(尊重
XDG_CONFIG_HOME
),权限 0600。
bash
undefined
Credentials are managed by "authorizer profiles", each profile contains key/secret/env/sign. The configuration file is located at
~/.config/openydt-cli/config.json
(respects
XDG_CONFIG_HOME
), with permission 0600.
bash
undefined

新增或更新一个授权商 profile(首次使用从这里开始)

Add or update an authorizer profile (start here for first-time use)

openydt config set --profile demo --key test --secret 123456 --env test --sign v2
openydt config set --profile demo --key test --secret 123456 --env test --sign v2

列出所有 profile(secret 已脱敏),带 * 的是当前 profile

List all profiles (secret is desensitized), the one with * is the current profile

openydt config list
openydt config list

切换当前 profile

Switch current profile

openydt config use demo
openydt config use demo

打印配置文件路径

Print configuration file path

openydt config path

- `config set` 的 `--profile / --key / --secret` 必填;`--env` 默认 `test`,`--sign` 默认 `v2`。
- 第一次 `config set` 时,若尚无当前 profile,会自动把它设为当前 profile。
openydt config path

- `--profile / --key / --secret` are required for `config set`; `--env` defaults to `test`, `--sign` defaults to `v2`.
- When running `config set` for the first time, if there is no current profile, it will automatically set the new profile as the current one.

环境变量覆盖(适合 CI)

Environment Variable Override (Suitable for CI)

下列环境变量优先级高于 profile 中的值,可在不写配置文件的情况下临时覆盖:
变量含义
OPENYDT_PROFILE
选择 profile 名
OPENYDT_KEY
覆盖 key
OPENYDT_SECRET
覆盖 secret
OPENYDT_ENV
覆盖环境 test|dev|prod
OPENYDT_SIGN
覆盖签名版本 v2|v3
优先级(从低到高):内置默认 < profile < 环境变量 < 命令行显式 flag。空值会被忽略。只要设置了
OPENYDT_KEY
+
OPENYDT_SECRET
,即使没有同名 profile 也能直接调用。
The following environment variables have higher priority than values in profiles, allowing temporary override without modifying the configuration file:
VariableDescription
OPENYDT_PROFILE
Select profile name
OPENYDT_KEY
Override key
OPENYDT_SECRET
Override secret
OPENYDT_ENV
Override environment test|dev|prod
OPENYDT_SIGN
Override signature version v2|v3
Priority (from lowest to highest): Built-in default < profile < environment variable < explicit command-line flag. Empty values are ignored. As long as
OPENYDT_KEY
+
OPENYDT_SECRET
are set, you can directly call the interface even if there is no profile with the same name.

全局 flag

Global Flags

所有命令通用:
Flag说明
--profile <名>
指定授权商 profile(默认当前 profile)
--env test|dev|prod
指定环境(默认 test)
--output
,
-o json|table
输出格式(默认 json)
--sign v2|v3
签名版本(默认按 profile,否则 v2)
--yes
,
-y
确认执行写操作
--dry-run
只打印将发送的签名请求,不实际发送
--verbose
,
-v
输出调试信息到 stderr
各环境 base URL:
  • test →
    https://openapi-test.yidianting.com.cn
  • dev →
    https://openapi-dev.yidianting.xin
  • prod →
    https://open.yidianting.xin
Common to all commands:
FlagDescription
--profile <name>
Specify authorizer profile (defaults to current profile)
--env test|dev|prod
Specify environment (defaults to test)
--output
,
-o json|table
Output format (defaults to json)
--sign v2|v3
Signature version (defaults to profile setting, otherwise v2)
--yes
,
-y
Confirm write operation execution
--dry-run
Only print the signed request to be sent, do not actually send it
--verbose
,
-v
Output debug information to stderr
Base URLs for each environment:
  • test →
    https://openapi-test.yidianting.com.cn
  • dev →
    https://openapi-dev.yidianting.xin
  • prod →
    https://open.yidianting.xin

认证验证

Authentication Verification

配置好后,先做一次冒烟验证(内部调用
getAuthParkCodes
确认凭据/签名链路可用):
bash
openydt auth test
成功输出
✓ 认证通过 (status=1)
并列出授权车场;失败会打印 status/message/resultCode 并以对应退出码返回。
After configuration, perform a smoke test (internally calls
getAuthParkCodes
to confirm the credential/signature link is available):
bash
openydt auth test
Success outputs
✓ Authentication passed (status=1)
and lists authorized parking lots; failure prints status/message/resultCode and returns with the corresponding exit code.

签名

Signature

请求路径形如
POST {base}/openydt/api/v3/{cmd}?sign={sign}
,并带
Authorization: base64(key:ts)
头。时间戳
ts
为本地时间
yyyyMMddHHmmss
,有效期 10 分钟。
版本算法说明
v2(默认)
lower(md5(key:ts:secret))
不含 body;测试环境默认可用
v3
lower(md5(key:ts:body:secret))
含 compact 后的 body
重要:实测测试 key 仅接受 v2;用 v3 调用测试 key 会返回「签名错误」(status=4),除非平台对该 key 专门开通了 v3。默认保持 v2 即可,仅在平台明确为该 key 开通 v3 后再用
--sign v3
签名用的 body 与实际发送的 body 必须字节一致:CLI 会先做一次 JSON compact 再同时用于签名与发送(字符串内部空格如
"2019-04-16 00:11:25"
会保留)。
Request path is in the form
POST {base}/openydt/api/v3/{cmd}?sign={sign}
, with the
Authorization: base64(key:ts)
header. Timestamp
ts
is local time
yyyyMMddHHmmss
, valid for 10 minutes.
VersionAlgorithmDescription
v2(default)
lower(md5(key:ts:secret))
Does not include body; available by default in test environment
v3
lower(md5(key:ts:body:secret))
Includes compacted body
Important: Test keys only accept v2 in practice; using v3 to call test keys will return "signature error" (status=4) unless the platform has specifically enabled v3 for that key. Keep v2 by default, only use
--sign v3
after the platform explicitly enables v3 for the key.
The body used for signature must be byte-consistent with the actual sent body: the CLI will first compact the JSON and use it for both signature and sending (internal spaces in strings like
"2019-04-16 00:11:25"
are retained).

三层命令模型

Three-tier Command Model

调用任意接口有三条路径,按优先级选择:
  1. 域一等命令(首选):
    openydt <域> <命令>
    ,参数已结构化为 flag,最易用。例如
    openydt park get-auth-park-codes
    openydt parking <子命令>
    。当前内置域:
    blacklist coupon data device park parking redlist ticket trade visitor
  2. 通用兜底
    openydt api <cmd> --body '{...}'
    ,对任意业务编码 cmd 自动签名并 POST,覆盖任何可调用接口。
    bash
    openydt api getParkFee --body '{"carCode":"粤EJW962"}'
    openydt api getAuthParkCodes
    echo '{"parkCode":"PTD2YBBZ"}' | openydt api getParkOnSiteCar --body-file -
    --body
    --body-file
    互斥;
    --body-file -
    从 stdin 读取。
  3. schema 探索(若有):用于发现接口与字段,再回到 ① 或 ②。
There are three paths to call any interface, selected by priority:
  1. Domain First-class Command(Preferred):
    openydt <domain> <command>
    , parameters are structured as flags, most user-friendly. For example
    openydt park get-auth-park-codes
    ,
    openydt parking <subcommand>
    . Currently built-in domains:
    blacklist coupon data device park parking redlist ticket trade visitor
    .
  2. General Fallback:
    openydt api <cmd> --body '{...}'
    , automatically signs and POSTs for any business code cmd, covering any callable interface.
    bash
    openydt api getParkFee --body '{"carCode":"粤EJW962"}'
    openydt api getAuthParkCodes
    echo '{"parkCode":"PTD2YBBZ"}' | openydt api getParkOnSiteCar --body-file -
    --body
    and
    --body-file
    are mutually exclusive;
    --body-file -
    reads from stdin.
  3. Schema Exploration(if available): Used to discover interfaces and fields, then return to ① or ②.

响应包络与状态码

Response Envelope and Status Codes

平台统一包络:
{"data":..., "message":"...", "resultCode":N, "status":N}
status
含义:
status含义
1业务成功
2业务失败(看 resultCode)
3系统异常
4签名错误
5key 错误
6未授权
7请求参数不完整
status == 2
时看
resultCode
(常见业务码,源自
internal/client/codes.go
):
resultCode含义
901系统发生异常
902远程服务器未响应
903运营商不存在
904停车场不存在
905未找到在场车辆
906账单不存在
907账单已同步
908其它错误
909请求参数错误
910找不到授权商下面的停车场
911无权限操作该停车场
912查费已超时,请重新查费
1801找不到指定车辆
The platform uses a unified envelope:
{"data":..., "message":"...", "resultCode":N, "status":N}
.
Meaning of
status
:
statusMeaning
1Business success
2Business failure (check resultCode)
3System exception
4Signature error
5Key error
6Unauthorized
7Incomplete request parameters
When
status == 2
, check
resultCode
(common business codes, from
internal/client/codes.go
):
resultCodeMeaning
901System exception occurred
902Remote server did not respond
903Operator does not exist
904Parking lot does not exist
905No on-site vehicle found
906Bill does not exist
907Bill has been synchronized
908Other errors
909Request parameter error
910No parking lot found under the authorizer
911No permission to operate this parking lot
912Fee inquiry timed out, please retry
1801Specified vehicle not found

进程退出码

Process Exit Codes

退出码含义
0成功(status=1)
1业务失败(status=2 或其它非成功)
2参数错误(用法错误)
4鉴权失败(status=4 签名 / 5 key / 6 未授权)
5网络/传输失败
Exit CodeMeaning
0Success(status=1)
1Business failure(status=2 or other non-success status)
2Parameter error(usage error)
4Authentication failure(status=4 signature /5 key /6 unauthorized)
5Network/transmission failure

限速与重试

Rate Limiting and Retry

  • 授权车场数 < 60 的授权商:限速 300 次/分。批量调用时自行节流,避免触发 429。
  • 客户端已内置重试 + 指数退避(约 400ms 起,带抖动,默认最多重试 3 次)。
  • 遇网关偶发 404、连接重置、429/502/503/504 会自动重试;非包络的 HTML 错误页不重试。
  • 查费超时(resultCode 912)
    是业务态,需按提示重新查费,不是网络重试范畴。
  • Authorizers with fewer than 60 authorized parking lots: rate limit 300 times/minute. Throttle batch calls to avoid triggering 429.
  • The client has built-in retry + exponential backoff(starts at about 400ms, with jitter, maximum 3 retries by default).
  • Automatically retries on occasional gateway 404, connection reset, 429/502/503/504; does not retry non-envelope HTML error pages.
  • "Fee inquiry timed out(resultCode 912)" is a business state, need to retry as prompted, not within network retry scope.

安全规则

Security Rules

  • 写操作必须
    --yes
    :缴费、开闸、发券、开通月票、加/移黑名单等任何会改变平台状态的操作,必须显式带
    --yes
    才会执行,避免误操作。
  • --dry-run
    预览
    :危险或不确定的请求先用
    --dry-run
    查看将发送的签名请求(URL/sign/ts/body),确认无误后再去掉。
  • 不要明文输出密钥:不要把 key/secret 打印到终端或日志;
    config list
    已对 secret 脱敏。
  • 默认在
    test
    环境验证;切到
    prod
    前务必与用户确认。
  • Write operations require
    --yes
    : Any operation that changes the platform state, such as payment, gate opening, coupon issuance, monthly pass activation, adding/removing from blacklist, etc., must explicitly include
    --yes
    to execute, avoiding misoperations.
  • Preview with
    --dry-run
    first
    : Use
    --dry-run
    for dangerous or uncertain requests to view the signed request to be sent(URL/sign/ts/body), then remove it after confirmation.
  • Do not output keys in plain text: Do not print key/secret to the terminal or logs;
    config list
    has desensitized the secret.
  • Verify in
    test
    environment by default; be sure to confirm with users before switching to
    prod
    .

测试车场(仅测试环境)

Test Parking Lots (Test Environment Only)

parkCode用途
1ZS7H5PQH9
可查费,配套测试车牌
粤EJW962
PTD2YBBZ
有存量数据,适合查记录 / 查在场车辆
示例:
bash
openydt api getParkFee --body '{"parkCode":"1ZS7H5PQH9","carCode":"粤EJW962"}'
openydt api getParkOnSiteCar --body '{"parkCode":"PTD2YBBZ"}'
parkCodePurpose
1ZS7H5PQH9
Fee inquiry available, matching test license plate
粤EJW962
PTD2YBBZ
Has historical data, suitable for querying records / on-site vehicles
Examples:
bash
openydt api getParkFee --body '{"parkCode":"1ZS7H5PQH9","carCode":"粤EJW962"}'
openydt api getParkOnSiteCar --body '{"parkCode":"PTD2YBBZ"}'