Skip to main content
Version: v5.1

createOtherCollections

createTelemetryCollection

The script calls fetchTelemetryElement and uses the first sensor element:

const createTelementaryCollection = async () => {
let telemetryElementId = await fetchTelemetryElement();
if(telemetryElementId?._list?.length === 0) return;
console.log(
"createTelementaryCollection === telemetryElementId",
telemetryElementId._list[0]._id
);

The fetchTelemetryElement function gets elements with the Sensor category in the model.

First, it gets the latest version of the BIM model, which is a NamedCompositeItem of userType "bim_model_version":

const fetchTelemetryElement = async () => {
//calls getCompositeCollection to get the model in the context
//namespace, setting the getLatestVersion flag to true
let latestModelComposite = await IafScriptEngine.getCompositeCollection(
{
query: {
_userType: "bim_model_version",
_namespaces: { $in: ctx._namespaces },
_itemClass: "NamedCompositeItem",
},
},
ctx,
{ getLatestVersion: true }
);
console.log(
"fetchTelemetryElement ==== latestModelComposite",
latestModelComposite
);

Next it fetches the latest version of the rvt_elements collection in the composite:

const latestElementCollection =
await IafScriptEngine.getCollectionInComposite(
latestModelComposite._id,
{ _userType: "rvt_elements" },
ctx
);
console.log(
"fetchTelemetryElement === latestElementCollection",
latestElementCollection
);

And uses its id value for the collectionDesc section of a findWithRelated query, which queries elements with a category of Sensor:

let bimQuery = {
parent: {
collectionDesc: {
_userType: "rvt_elements",
_userItemId: latestElementCollection._userItemId,
},
options: {
page: {
getAllItems: true,
},
},
sort: {
_id: 1,
},
query: {
ElementCategory: { $in: ["Sensor"] },
},
},
};
let elements = await IafScriptEngine.findWithRelated(bimQuery, ctx);
console.log("elements", elements);
return elements;
};

Returning to the main function, the script creates a new NamedTelemetryCollection to store sensor and points data:

const telementaryCollection =
await PlatformApi.IafItemSvc.createNamedUserItems(
[
{
_name: "Named Telemetry Collection",
_shortName: "telementary_coll",
_description:
"Named Telemetry Collection to store sensor and points data",
_namespaces: ctx._namespaces,
_userType: "ref_app_telementary_collection",
_tsProperties: {
_granularity: "minutes",
_expiry: 1440,
},
},
],
"NamedTelemetryCollection",
ctx
);
console.log(
`Started createTelementaryCollection`,
"createTelementaryCollection ==== Created Telemetry collection response.",
telementaryCollection
);

Next, it creates a RelatedItem for a sensor source that is related to the sensor.

To do this, it defines the sensor point source as a RelatedItem:

let relatedItems = [
{
floorname: "2nd Floor",
roomname: "Lab",
_sourceId: "e3e052f9-0156-11d5-9301-0000863f27ad-00000131",
},
];

Then, it creates the sensor point source as a RelatedItem in the NamedTelemetryCollection:

let telementryRelatedItems =
await PlatformApi.IafItemSvc.createRelatedItems(
telementaryCollection._list[0]._id,
relatedItems,
ctx
);
console.log(
"createTelementaryCollection ==== Telementry RelatedItems response.",
telementryRelatedItems
);

then, it defines the relationship between the sensor point source and the telemetry element, which is the parent:

let relationShipsSensor1 = [
{
_relatedFromId: telemetryElementId._list[0]._id, // parent id
_relatedToIds: telementryRelatedItems._list.map((item) => item._id), // children from tip version
_relatedUserItemDbId: telementaryCollection._list[0]._id,
},
];

Finally, it creates the defined relationship in the Item Service:

let relationsSensor1 = await PlatformApi.IafItemSvc.addRelations(
telementaryCollection._list[0]._id,
relationShipsSensor1,
ctx
);
console.log(
`Completed createTelementaryCollection`,
"createTelementaryCollection ==== Telementry add relations response.",
relationsSensor1
);

createWarrantyAndElementRelation

In this demo, warranty data is related to door elements in the project.

First, define a NamedUserCollection to store all warranty data for elements:

let Coll_info = {
Name: "Element Warranty Data",
ShortName: "war_data",
Description: "Element Warranty Data",
userType: "iaf_dt_warranty_coll",
};

Then, get the model, which is a NamedCompositeCollection:

let iaf_ext_current_bim_model =
await IafScriptEngine.getCompositeCollection(
{
query: {
_userType: "bim_model_version",
_namespaces: { $in: ctx._namespaces },
_itemClass: "NamedCompositeItem",
},
},
ctx,
{ getLatestVersion: true }
);
console.log(
"Started createWarrantyAndElementRelation.",
"createWarrantyAndElementRelation ==== iaf_ext_current_bim_model",
iaf_ext_current_bim_model
);

From the model NamedCompositeCollection, get the elements collection, identified by the userType rvt_elements:

let rvt_coll = await IafScriptEngine.getCollectionInComposite(
iaf_ext_current_bim_model._userItemId,
{ _userType: "rvt_elements" },
ctx
);

To fetch the door elements, the fetchOSTDoors function defines a findWithRelated query to target elements with the ElementCategory "Door - External":

let revit_elements = await fetchOSTDoors();
const fetchOSTDoors = async () => {
...
let bimQuery = {
parent: {
collectionDesc: {
_userType: "rvt_elements",
_userItemId: latestElementCollection._userItemId,
},
options: { page: { getAllItems: true } },
sort: { _id: 1 },
query: { ElementCategory: { $in: ["Door - External"] } },
},
};
let elements = await IafScriptEngine.findWithRelated(bimQuery, ctx);
console.log("fetchOSTDoors ==== elements", elements);
return elements;
};

The next step is to define the warranty information and duplicate it for each targeted door element:

let dataObject = {
properties: {
"Warranty Description": {
dName: "Warranty Description",
val: "The manufacturer warrants this product to be free from defects in workmanship and materials, under normal residential use and conditions, for a period of one (1) year for the original invoice date",
type: "text",
epoch: null,
},
"Warranty Start Date": {
dName: "Warranty Start Date",
val: "09-11-2022",
type: "date",
},
"Warranty Duration": {
dName: "Warranty Duration",
val: "1 year",
type: "text",
},
},
};

const flatAllDataObjs = new Array(revit_elements._list.length).fill(
dataObject
);

Now, we create the NamedUserCollection in the Item Service to store all warranty data for the door elements:

let data_obj_coll = await IafScriptEngine.createOrRecreateCollection(
{
_name: Coll_info.Name,
_shortName: Coll_info.ShortName,
_namespaces: ctx._namespaces,
_description: Coll_info.Description,
_userType: Coll_info.userType,
},
ctx
);

Next, we create the warranty data objects as RelatedItems in the warranty data NamedUserCollection:

let data_obj_res = await IafScriptEngine.createItemsBulk(
{
_userItemId: data_obj_coll._userItemId, //warranty NamedUserCollection
_namespaces: ctx._namespaces,
items: flatAllDataObjs, //warranty data objects
},
ctx
);

To relate each door element RelatedItem to its relevant warranty data RelatedItem in a Relationship, we must first get the ids of the bulk created warranty RelatedItems. The createItemsBulk function does not return the items themselves but a list of URIs for each object.

First, create an array with the URIs only:

const allURIs = data_obj_res[0].flatMap((d) => d._uris);

Next, extract the last part of each URI to get id:

const dataObjIds = allURIs.map((u) => u.split("/").pop());

Then, match each door element with the id of its relevant warranty data object by pairing them in tuples:

const assetsWithDataIds = revit_elements._list.map((e, i) => [
e,
dataObjIds[i],
]);

To define an array of Relationships, simply map each tuple to parentItem and relatedItems properties in an object for each relationship:

const relatedItems = assetsWithDataIds.map((d) => {
return { parentItem: d[0], relatedItems: [{ _id: d[1] }] };
});

To create the relationships in the Item Service, use IafScriptEngine.createRelations:

const relations = await IafScriptEngine.createRelations(
{
parentUserItemId: rvt_coll._userItemId, //door elements NamedUserCollection userItemId
_userItemId: data_obj_coll._userItemId, //warranty NamedUserCollection
_namespaces: ctx._namespaces,
relations: relatedItems, // the array of defined Relationship objects
},
ctx
);

createRootFileCollection

createRootFileCollection creates a root file container for the project that acts as a root directory for all files that are related to model elements or the project in general:

const createRootFileCollection = async () => {
console.log("Creating Root Container...");
const rootContainer = await PlatformApi.IafFile.createContainer(
project,
undefined,
ctx
);
};

createPermissionProfile

The createPermissionProfile function creates a permission set for the ...

const createPermissionProfile = async () => {
const workspaceId = project._id;
const irnValue = "passportsvc:workspace:" + workspaceId;
let permissions = [
{
_name: "viewer_orch_perms1",
_userType: "viewer_orch_perms",
_namespaces: [ctx._namespaces[0]],
_permissions: [
{
_actions: ["READ", "SHARE"],
_namespace: ctx._namespaces[0],
_resourceDesc: {
_irn: irnValue,
},
},
{
_actions: ["READ", "SHARE", "DELETE", "CREATE"],
_namespace: ctx._namespaces[0],
_resourceDesc: {
_irn: "itemsvc:nameduseritem:*",
},
},
],
},
];
let result = await PlatformApi.IafPassSvc.createPermissionProfiles(
permissions,
ctx
);
console.log("createPermissionProfile ==== result", result);
};