Import en masse d'actifs depuis un CSV
Ce guide montre comment créer en masse des RealityAssets dans un twin à partir d’un fichier CSV. Chaque ligne définit un nom d’actif et une boîte englobante orientée dans l’espace du twin. Le flux de travail utilise le flux Client Credentials et le scope write:asset.
Prérequis
Section intitulée « Prérequis »- Une application OAuth configurée pour Client Credentials
- Scopes :
read:basic,read:hierarchy,write:asset - Votre
client_idetclient_secret - Accès au contenu et permissions de modification sur le twin cible
- L’ID du twin où les actifs doivent être créés
Quand utiliser ce modèle
Section intitulée « Quand utiliser ce modèle »Utilisez un import piloté par CSV lorsque vous disposez déjà de définitions d’actifs en dehors de Prevu3D, par exemple :
- Listes d’équipements exportées depuis un CMMS ou un ERP avec des coordonnées 3D
- Résultats de relevé ou d’étiquetage depuis un outil externe
- Migration depuis une autre plateforme où les actifs étaient positionnés dans les coordonnées du twin
Chaque appel API crée un actif. Un script parcourt les lignes du CSV et appelle POST /v1/twin/{twinId}/assets pour chaque entrée.
Format CSV
Section intitulée « Format CSV »La feuille de calcul doit inclure une ligne d’en-tête. Colonnes requises :
| Colonne | Correspond à | Description |
|---|---|---|
Description | name de l’actif | Nom d’affichage du RealityAsset |
Manual_X | Centre de la boîte x | Coordonnée X du centre de la boîte dans l’espace du twin |
Manual_Y | Centre de la boîte y | Coordonnée Y du centre de la boîte dans l’espace du twin |
Manual_Z | Centre de la boîte z | Coordonnée Z du centre de la boîte dans l’espace du twin |
Manual_Box_X | Taille de la boîte x | Largeur de la boîte englobante |
Manual_Box_Y | Taille de la boîte y | Profondeur de la boîte englobante |
Manual_Box_Z | Taille de la boîte z | Hauteur de la boîte englobante |
Exemple :
Description,Manual_X,Manual_Z,Manual_Y,Manual_Box_X,Manual_Box_Z,Manual_Box_YPump A,6.27,-5.10,187.12,0.35,0.64,0.33Valve B,8.84,-3.14,189.41,2.99,1.11,4.69Les coordonnées doivent être dans le même système de coordonnées que le twin. Si vous avez positionné des actifs manuellement dans RealityTwin, exportez ou enregistrez les valeurs dans l’espace du twin. La rotation est par défaut l’identité ; l’API accepte un quaternion rotation facultatif sur chaque boîte si vous avez besoin de volumes orientés.
Flux de bout en bout
Section intitulée « Flux de bout en bout »flowchart LR A["1. S'authentifier"] --> B["2. Lire les lignes CSV"] B --> C["3. Construire workingStructure"] C --> D["4. POST un actif par ligne"] D --> E["5. Vérifier les résultats"]
| Étape | Point de terminaison | Ce que vous obtenez |
|---|---|---|
| S’authentifier | POST /oauth/token | Jeton d’accès |
| Résoudre l’URL API | GET /oauth/api-info | apiUrl régionale |
| Créer un actif | POST /v1/twin/{twinId}/assets | Nouvel ID d’actif par ligne |
Structure de la charge utile d’actif
Section intitulée « Structure de la charge utile d’actif »Chaque ligne devient un actif avec un workingStructure contenant une seule boîte orientée :
{ "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 } } ] }}Pour attribuer un type d’actif à la création, ajoutez assetTypeId avec l’UUID d’un type configuré dans votre organisation. Consultez Types d’actifs pour savoir comment les types sont définis dans RealityPlatform.
Étape 1 — S’authentifier
Section intitulée « Étape 1 — S’authentifier »Obtenez un jeton d’accès avec Client Credentials :
POST https://cloud-api.prevu3d.com/oauth/tokenAuthorization: Basic base64(client_id:client_secret)Content-Type: application/x-www-form-urlencoded
grant_type=client_credentialsGET https://cloud-api.prevu3d.com/oauth/api-infoAuthorization: Bearer {access_token}Étape 2 — Créer des actifs depuis le CSV
Section intitulée « Étape 2 — Créer des actifs depuis le CSV »POST {api_url}/v1/twin/{twinId}/assetsAuthorization: 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 } } ] }}Une réponse réussie retourne l’actif créé, y compris son id. Répétez pour chaque ligne du CSV.
Exemple complet
Section intitulée « Exemple complet »import base64import csvfrom 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)}")Trouver l’ID du twin
Section intitulée « Trouver l’ID du twin »L’ID du twin est l’UUID du nœud twin dans votre hiérarchie de contenu. Vous pouvez :
- Le copier depuis l’URL RealityPlatform lorsque le twin est ouvert
- Parcourir la hiérarchie avec
GET /v1/nodes/{organizationId}/browseet localiser un nœud avectype: "Twin"
Conseils pour les imports volumineux
Section intitulée « Conseils pour les imports volumineux »- Importez de manière responsable. L’API crée un actif par requête. Pour des centaines de lignes, ajoutez un court délai ou un backoff si vous atteignez les limites de débit.
- Validez les coordonnées d’abord. Importez une seule ligne de test avant d’exécuter le fichier complet.
- Utilisez le mode brouillon dans RealityTwin lorsque vous souhaitez examiner les actifs avant que d’autres utilisateurs ne les voient. Les actifs créés via l’API apparaissent immédiatement dans le twin, sauf si votre intégration cible un flux de travail en brouillon.
- Attachez les métadonnées ensuite. Après la création, utilisez
PATCH /v1/twin/{twinId}/assets/{assetId}/metadatapour ajouter des valeurs de propriétés. Consultez les points de terminaison d’actifs dans la référence API.
Et ensuite ?
Section intitulée « Et ensuite ? »- Configurez l’authentification dans le guide Flux Client Credentials.
- Découvrez le fonctionnement des actifs dans l’espace de travail du twin : Travailler avec les RealityAssets.
- Parcourez les points de terminaison d’actifs dans la référence API.