跳转到内容

从 CSV 批量导入资产

本指南展示如何从 CSV 文件在孪生中批量创建 RealityAsset。每一行定义一个资产名称和一个孪生空间中的定向边界框。该工作流程使用 Client Credentials 流程write:asset 作用域。


  • 一个配置为 Client Credentials 的 OAuth 应用
  • 作用域:read:basicread:hierarchywrite:asset
  • 你的 client_idclient_secret
  • 对目标孪生具有内容访问权限和编辑权限
  • 要创建资产的孪生 ID

当你已经在 Prevu3D 之外拥有资产定义时,请使用 CSV 驱动的导入,例如:

  • 从 CMMS 或 ERP 系统导出的带 3D 坐标的设备清单
  • 来自外部工具的勘测或标记结果
  • 从另一个平台迁移,其中资产以孪生坐标定位

每次 API 调用创建一个资产。脚本遍历 CSV 行,并为每个条目调用 POST /v1/twin/{twinId}/assets

电子表格必须包含一个标题行。必需列:

映射到说明
Description资产 nameRealityAsset 的显示名称
Manual_X框中心 x孪生空间中框中心的 X 坐标
Manual_Y框中心 y孪生空间中框中心的 Y 坐标
Manual_Z框中心 z孪生空间中框中心的 Z 坐标
Manual_Box_X框尺寸 x边界框的宽度
Manual_Box_Y框尺寸 y边界框的深度
Manual_Box_Z框尺寸 z边界框的高度

示例:

Description,Manual_X,Manual_Z,Manual_Y,Manual_Box_X,Manual_Box_Z,Manual_Box_Y
Pump A,6.27,-5.10,187.12,0.35,0.64,0.33
Valve B,8.84,-3.14,189.41,2.99,1.11,4.69

坐标必须与孪生使用相同的坐标系。如果你在 RealityTwin 中手动定位了资产,请以孪生空间导出或记录值。旋转默认为单位值;如果你需要定向体积,API 会在每个框上接受一个可选的 rotation 四元数。

flowchart LR
  A["1. Authenticate"] --> B["2. Read CSV rows"]
  B --> C["3. Build workingStructure"]
  C --> D["4. POST asset per row"]
  D --> E["5. Review results"]
步骤端点你会得到什么
身份验证POST /oauth/token访问令牌
解析 API URLGET /oauth/api-info区域 apiUrl
创建资产POST /v1/twin/{twinId}/assets每行一个新资产 ID

每一行成为一个带有包含单个定向框的 workingStructure 的资产:

{
"name": "Pump A",
"workingStructure": {
"boxes": [
{
"center": { "x": 6.27, "y": 187.12, "z": -5.10 },
"size": { "x": 0.35, "y": 0.33, "z": 0.64 },
"rotation": { "x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0 }
}
]
}
}

要在创建时分配资产类型,请添加 assetTypeId 以及你组织中配置的某个类型的 UUID。有关如何在 RealityPlatform 中定义类型,请参阅资产类型

使用 Client Credentials 获取访问令牌:

POST https://cloud-api.prevu3d.com/oauth/token
Authorization: Basic base64(client_id:client_secret)
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
GET https://cloud-api.prevu3d.com/oauth/api-info
Authorization: Bearer {access_token}
POST {api_url}/v1/twin/{twinId}/assets
Authorization: Bearer {access_token}
Content-Type: application/json
{
"name": "Pump A",
"workingStructure": {
"boxes": [
{
"center": { "x": 6.27, "y": 187.12, "z": -5.10 },
"size": { "x": 0.35, "y": 0.33, "z": 0.64 },
"rotation": { "x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0 }
}
]
}
}

成功的响应返回创建的资产,包括其 id。为每个 CSV 行重复此操作。

import base64
import csv
from pathlib import Path
import requests
CLIENT_ID = "your-client-id"
CLIENT_SECRET = "your-client-secret"
CLOUD_API_BASE = "https://cloud-api.prevu3d.com"
TWIN_ID = "your-twin-id"
CSV_FILE = Path("assets.csv")
credentials = base64.b64encode(f"{CLIENT_ID}:{CLIENT_SECRET}".encode()).decode()
token_response = requests.post(
f"{CLOUD_API_BASE}/oauth/token",
data={"grant_type": "client_credentials"},
headers={"Authorization": f"Basic {credentials}"},
)
token_response.raise_for_status()
access_token = token_response.json()["access_token"]
headers = {"Authorization": f"Bearer {access_token}"}
api_info = requests.get(f"{CLOUD_API_BASE}/oauth/api-info", headers=headers).json()
api_url = api_info["apiUrl"].rstrip("/")
def api_post(path: str, body: dict) -> dict:
response = requests.post(f"{api_url}{path}", json=body, headers=headers)
response.raise_for_status()
return response.json()
def oriented_box(cx: float, cy: float, cz: float, sx: float, sy: float, sz: float) -> dict:
return {
"center": {"x": cx, "y": cy, "z": cz},
"size": {"x": sx, "y": sy, "z": sz},
"rotation": {"x": 0.0, "y": 0.0, "z": 0.0, "w": 1.0},
}
with CSV_FILE.open(newline="", encoding="utf-8") as handle:
rows = list(csv.DictReader(handle))
created = []
errors = []
for row in rows:
name = row["Description"].strip()
body = {
"name": name,
"workingStructure": {
"boxes": [
oriented_box(
cx=float(row["Manual_X"]),
cy=float(row["Manual_Y"]),
cz=float(row["Manual_Z"]),
sx=float(row["Manual_Box_X"]),
sy=float(row["Manual_Box_Y"]),
sz=float(row["Manual_Box_Z"]),
)
]
},
}
try:
asset = api_post(f"/v1/twin/{TWIN_ID}/assets", body)
print(f"[OK] {name} -> {asset['id']}")
created.append(asset)
except requests.HTTPError as error:
print(f"[ERR] {name} -> {error.response.status_code} {error.response.text}")
errors.append(name)
print(f"\nCreated: {len(created)} / Errors: {len(errors)}")

孪生 ID 是你内容层级中孪生节点的 UUID。你可以:

  • 在孪生打开时从 RealityPlatform URL 复制它
  • 使用 GET /v1/nodes/{organizationId}/browse 浏览层级,并定位一个 type: "Twin" 的节点
  • 合理分批。 API 每个请求创建一个资产。对于数百行,如果遇到速率限制,请添加短暂延迟或退避。
  • 先验证坐标。 在运行完整文件之前,先导入单个测试行。
  • 在 RealityTwin 中使用草稿模式,当你想在其他用户看到之前审查资产时。除非你的集成针对草稿工作流程,否则通过 API 创建的资产会立即出现在孪生中。
  • 稍后附加元数据。 创建后,使用 PATCH /v1/twin/{twinId}/assets/{assetId}/metadata 添加属性值。请参阅 API 参考中的资产端点。