Appearance
3. 快速开始
本章用一条可复制执行的链路把 DASS2 的二次开发主线跑通。除「导入测点」一节外,其余步骤全部是只读的,可以安全地对生产设备执行。
【注意】下面所有示例都假设设备地址为
192.168.50.121、HTTP 端口8085。请替换成你的实际地址。
【警告】示例中的密码一律写成<密码的MD5>占位符。不要在文档、脚本或代码里硬编码真实口令。
3.0 准备:登录并保存 Cookie
DASS2 需要 beegosessionID 与「同名用户 Cookie」两个 Cookie 同时携带,用 cookie jar 是最省事的做法。
bash
DEV=192.168.50.121:8085
JAR=/tmp/dass2.jar
PWD_MD5=$(md5 -q -s '<管理员明文密码>') # Linux: printf '%s' '<明文>' | md5sum | cut -d' ' -f1
curl -s -c "$JAR" -X POST "http://$DEV/v1/login" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=admin" \
-d "password=$PWD_MD5"实测响应(已截断 Menus):
json
{"code":0,"count":0,"data":{"User":{"Id":37,"LoginName":"admin","RealName":"admin","Password":"","Role":"1","Platform":"arm","Model":"IA-2230","Status":1},"IsFirst":false},"msg":"ok"}自查:code == 0 && msg == "ok",且 /tmp/dass2.jar 里同时有 beegosessionID 和 admin 两条。
bash
grep -E 'beegosessionID|admin' "$JAR"【警告】只看
code == 0是不够的——DASS2 存在code:0与msg:"error"并存的响应,详见 2.2。
3.1 第一步:查采集服务列表 → 拿到 dasId
bash
curl -s -b "$JAR" "http://$DEV/v1/das"实测响应:
json
{"code":0,"count":2,"data":[
{"id":36,"name":"jen","type":"GB_Demo_Jenkins","driverType":"das","port":5480,
"desc":"s","host":"","isLink":"true","nodeName":"W3.JEN","status":"running","total":0,"timeout":0},
{"id":35,"name":"mqtt","type":"OP2_MQTT_JC","driverType":"upload","port":9486,
"desc":"m","host":"","isLink":"true","nodeName":"W3.MQTT","status":"stop","total":0,"timeout":0}
],"msg":"ok"}拿两样东西:
data[].id→ 后续/v1/das/conf/{id}、/v1/point/import/{id}、/v1/point/export/{id}等用的dasIddata[].name→ 按名寻址的接口(如/v1/das/conf/third)用它;也是查该服务测点的关键(GET /v1/point?SN={name})
【警告】不要把
dasId传给GET /v1/point/{id}。/v1/point/{id}的{id}是测点 UID,传 dasId 会静默返回空列表。要按服务查测点,用?SN={服务名}(见 4.4)。
【注意】
type字段存的是驱动名(GB_Demo_Jenkins),不是"采集/上传";采集与上传的区分看driverType(das/upload)。
3.2 第二步:读采集服务配置
bash
curl -s -b "$JAR" "http://$DEV/v1/das/conf/36"实测响应(截断,共 count: 17 项):
json
{"code":0,"count":17,"data":[
{"id":0,"driver":"jen","name":"服务描述","key":"desc","value":"s","ed":"描述","exScope":"advance","textType":""},
{"id":0,"driver":"GB_Demo_Jenkins","name":"测点添加模式","key":"isLink","value":"true",
"ed":"true 为自动添加到实时库;false 为手动添加到实时库","exScope":"advanced",
"textType":"disable","textData":"true|false"}
],"msg":"ok"}用法:data[] 每一项的 key 就是配置项名,value 是当前值,textData 里 a|b|c 是可选枚举。改配置时把这些 key 平铺成表单字段 PUT 回去即可(见 4.2)。
【警告】
textType为ispassword/password的项,value是base64(AES(明文))密文,不是明文。二次开发若只读展示,必须解密;若要回写,必须重新加密,否则会把密码写成密文串。详见 7-已知限制与坑。
3.3 第三步:查驱动配置字段(建服务前必做)
GET /v1/driver/conf/{id} 返回的数组本身就是"建服务请求体"的字段清单:每一项的 key 就是请求参数名,value 是默认值。
bash
# 先列出驱动,拿到 driverId
curl -s -b "$JAR" "http://$DEV/v1/driver"
# 再取该驱动的配置字段
curl -s -b "$JAR" "http://$DEV/v1/driver/conf/97"实测响应(截断,共 count: 16 项):
json
{"code":0,"count":16,"data":[
{"driver":"GB_Demo_Jenkins","name":"测点添加模式","key":"isLink","value":"true",
"exScope":"advanced","textType":"select","textData":"true|false"},
{"driver":"GB_Demo_Jenkins","name":"接口模式","key":"comm_mode","value":"...","textType":"select"}
],"msg":"ok"}【注意】建服务要取两段拼起来:
?scope=addServer与?scope=advanced。缺一段会漏字段。
3.4 第四步:导入采集测点(核心,写操作)
这是本手册对应的最主要场景,也是 DASS2 唯一被广泛使用的批量接口。
3.4.1 接口摘要
| 项 | 值 |
|---|---|
| 方法与路径 | POST /v1/point/import/{dasId} |
| Content-Type | multipart/form-data |
| 文件字段名 | pointcsv(固定,不可改) |
| 文件格式 | .xlsx(扩展名必须是 .xlsx;不支持 csv) |
| 工作表 | 只读第一个工作表(代码里的 Sheet1) |
| 表头必需列 | PN 与 RT(大小写不敏感) |
| 模式 | 增量 + 更新:先按点名比对,分类为「新增」与「修改」,再分别写库;不会清空原有测点 |
| 鉴权 | 需登录(两个 Cookie 都要) |
bash
curl -s -b "$JAR" -X POST "http://$DEV/v1/point/import/36" \
-F "pointcsv=@/path/to/point.xlsx"3.4.2 点表长什么样
先下载官方模板,照它的表头和 Sheet 名来填:
bash
curl -s -b "$JAR" -o point_template.xlsx "http://$DEV/v1/point/template/36"实测模板是真正的 xlsx(响应体以 PK 开头),第一个工作表表头是 34 列:
ID PN AN RT ED EU AD SR EVENT REDATA1 PH PL FK FB AP
H4 LC H3 ZH HL LL ZL L3 L4 KR IV FM FQ TV BV KZ DT DB样例行(实测):
| ID | PN | AN | RT | ED | EU | AD | SR | EVENT | REDATA1 | PH | PL | FK | FB | AP | H4 | LC | H3 | ZH | HL | LL | ZL | L3 | L4 | KR | IV | FM | FQ | TV | BV | KZ | DT | DB |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1046 | G02 | g02 | AX | 22 | kg | 1.3.0 | INT16 | 0 | 1 | 100 | 0 | 1 | 0 | 1 | 200 | 0 | 150 | 130 | 115 | 30 | 15 | 10 | 0 | (空) | 0 | 2 | 1 | 100 | 0 | LINEAR | ENG | 0.2 |
| 1047 | G023 | g023 | DX | 22 | s | 1.3.0 | FLOAT | 1 | 2 | 100 | 0 | 1 | 0 | 2 | 300 | 0 | 200 | 180 | 160 | 50 | 30 | 20 | 0 | (空) | 0 | 2 | 1 | 100 | 0 | LINEAR | ENG | 0.2 |
各列含义见 5-数据字典。
【警告】
ID列在下限上有硬校验:必须能解析为数字且 ≥ 1024,且同一文件内不能重复;否则整批导入失败。ID是 openPlant 实时库的点 ID,不是数据库自增主键。
【注意】ID 列为空时:若该服务是「自动添加到实时库」模式(isLink == "true"),系统会自动分配;若是「手动添加」模式(isLink == "false"),会报手动添加测点模式时ID列不能为空。
3.4.3 成功响应——注意 count 的含义
实测成功响应:
json
{"code":0,"count":0,"data":[],"msg":"ok"}【警告】这是最容易误读的一点:导入成功时
count恒为0、data恒为空数组,它不是"导入的测点数量"。
想知道实际导入多少条,只能靠导入前后自行调用GET /v1/point?SN=<服务名>比对count。
(count只有在失败时才携带信息——此时它是本次解析出的测点总数。)
3.4.4 失败响应
json
{"code":-1,"count":12,"data":[{"Flag":"PN不能为空","PN":"PN不能为空"}],"msg":"error"}data[]是逐行错误清单,Flag是错误原因,PN是出问题的测点/行。- 部分行成功、部分行失败时,已成功的行不会回滚,只返回失败行。
常见失败原因:
data 里的文案 | 触发条件 |
|---|---|
PN不能为空 | 表头缺 PN 列,或某行 PN 为空 |
未找到 RT 列 | 表头缺 RT 列 |
ID<xxx>不能小于1024 | ID 列有值但小于 1024 |
ID<xxx>重复 | 同一文件内 ID 重复 |
PN<xxx>长度超过最大值<32> | PN 超过长度上限(见 5-数据字典) |
PN<xxx>格式不对… | PN 含非法字符 |
手动添加测点模式时ID列不能为空 | 服务为手动模式但未填 ID |
文件格式必须是.xlsx | 传了 csv 或改了扩展名 |
导入服务不存在 | dasId 不存在 |
节点不存在 | 该服务的实时库节点在 openPlant 里不存在 |
3.4.5 导入后必须做的事
导入会同时改动关系库与实时库,并通知采集服务刷新。建议导入后稳定等待数秒再做后续动作:
bash
sleep 3
curl -s -b "$JAR" "http://$DEV/v1/point?SN=jen&limit=0&offset=5"【注意】导入接口是同步阻塞的,点表很大时请求会长时间不返回。请把客户端超时设得足够大(建议 ≥ 300s),不要因为超时就重试——重试会重复触发一次导入。
3.5 第五步:回查测点
bash
# 按「采集服务名」查该服务的测点(推荐;SN 为精确匹配)
curl -s -b "$JAR" "http://$DEV/v1/point?SN=jen"
# 全部测点(注意 limit/offset 语义,见下方警告)
curl -s -b "$JAR" "http://$DEV/v1/point?limit=0&offset=20"
# 按「测点 UID」查单个测点
curl -s -b "$JAR" "http://$DEV/v1/point/1026"【警告】
/v1/point的limit/offset与直觉相反(实测确认):
limit= SQL 的起始行偏移(跳过几条)offset= SQL 的每页条数(取几条);传0时被强制改为20即后端拼的是
LIMIT <limit>,<offset>。所以?limit=2实际是「跳过 2 条、取 20 条」,而不是「取 2 条」。取前 20 条应写?limit=0&offset=20。
实测响应(截断,单条测点约 80 个字段):
json
{"code":0,"count":4,"data":[
{"ID":226,"UID":1026,"PID":0,"PN":"AX002","GN":"W3.JEN.AX002","SN":"jen","RT":0,
"AD":"","EU":"","TV":100,"BV":0,"DT":1,"DB":0.2,"KZ":1,"DS":-32768,"PH":100,"PL":0,
"ED":"这地方哈哈","FQ":1,"FM":2,"FLAG":"adding","SN":"jen"}
],"msg":"ok"}UID 就是导入时填的 ID 列(实时库点号),GN 是「节点名.点名」的全局名。完整字段见 5-数据字典。
3.6 第六步:导出 / 模板 / 清空(写操作,慎用)
| 操作 | 请求 | 说明 |
|---|---|---|
| 导出采集测点 | POST /v1/point/export/{dasId} | 返回 application/octet-stream |
| 下载导入模板 | POST /v1/point/template/{任意值} | 返回 xlsx(实测)。路径参数被忽略,任意服务都能下到同一份通用模板 |
| 下载上传点模板 | POST /v1/upoint/template/{dasId} | 返回 CSV(实测,与采集点模板格式不同) |
| 清空采集测点 | POST /v1/point/empty/{dasId} | 破坏性,会删除该服务全部测点 |
| 清理垃圾数据 | POST /v1/point/clean/{任意值} | 破坏性,删除游离数据。路径参数被忽略,是全局操作而非按服务 |
| 强制删除 | POST /v1/point/forceDelete/{任意值} | 实为空实现,什么都不删却返回成功(见 7.26) |
bash
curl -s -b "$JAR" -X POST -o points.xlsx "http://$DEV/v1/point/export/36"【警告】
empty/clean/forceDelete会不可逆地删除数据。生产环境务必先导出备份,并在非业务时段执行。
3.7 第七步:启停采集服务
bash
# 查看真实链路状态(比列表里的 status 更可信)
curl -s -b "$JAR" "http://$DEV/v1/das/deviceLink/36" # → {"code":0,"count":1,"data":true,"msg":"ok"}
# 停止
curl -s -b "$JAR" -X POST "http://$DEV/v1/das/stop/36"
# 启动
curl -s -b "$JAR" -X POST "http://$DEV/v1/das/boot/36"
# 重启
curl -s -b "$JAR" -X POST "http://$DEV/v1/das/reboot/36"【注意】这几个接口都注册成
*:方法(任意 HTTP 方法都会触发)。用 GET 访问也会真的启停服务——写脚本时务必用 POST,并注意别让爬虫/预取误触。
【注意】服务已在目标状态时不会报错,而是返回失败语义的文案(如采集已经停止),属于正常的幂等反馈,不要当成异常。
3.8 完整脚本
bash
#!/usr/bin/env bash
set -euo pipefail
DEV=${DEV:-192.168.50.121:8085}
USER=${USER_NAME:-admin}
PWD_MD5=${PWD_MD5:?请设置 PWD_MD5 环境变量}
XLSX=${1:?用法: $0 <点表.xlsx> [dasId]}
SVC_NAME=${2:-jen}
JAR=$(mktemp)
# 1. 登录
curl -s -c "$JAR" -X POST "http://$DEV/v1/login" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=$USER" -d "password=$PWD_MD5" >/dev/null
# 2. 按名字解析 dasId(不要硬编码)
DAS_ID=$(curl -s -b "$JAR" "http://$DEV/v1/das" \
| /usr/bin/python3 -c "import json,sys;d=json.load(sys.stdin);print(next(x['id'] for x in d['data'] if x['name']=='$SVC_NAME'))")
echo "采集服务 $SVC_NAME → dasId=$DAS_ID"
# 3. 导入前点数(注意:按服务查测点用 ?SN=,不是 /v1/point/{dasId})
BEFORE=$(curl -s -b "$JAR" "http://$DEV/v1/point?SN=$SVC_NAME" | /usr/bin/python3 -c "import json,sys;print(json.load(sys.stdin)['count'])")
echo "导入前测点数: $BEFORE"
# 4. 导入
RESP=$(curl -s -b "$JAR" -X POST "http://$DEV/v1/point/import/$DAS_ID" -F "pointcsv=@$XLSX")
echo "导入响应: $RESP"
# 5. 判定(注意:必须同时看 code 与 msg)
echo "$RESP" | /usr/bin/python3 -c "
import json,sys
r=json.load(sys.stdin)
if r.get('code')==0 and r.get('msg')=='ok':
print('导入成功')
else:
print('导入失败:', r.get('data'))
sys.exit(1)
"
# 6. 导入后点数
sleep 3
AFTER=$(curl -s -b "$JAR" "http://$DEV/v1/point?SN=$SVC_NAME" | /usr/bin/python3 -c "import json,sys;print(json.load(sys.stdin)['count'])")
echo "导入后测点数: $AFTER (净增 $((AFTER-BEFORE)))"
rm -f "$JAR"【注意】脚本里用
code==0 && msg=='ok'双条件判定,并且用导入前后的count差来确认实际效果——因为导入接口成功时不返回条数。
3.9 下一步
- 字段含义与枚举 → 5-数据字典
- 全量接口清单 → 4-接口参考
- 报错排查 → 6-错误码
- 上线前必读 → 7-已知限制与坑
帮助中心