I've been testing the APS IoT extension code with one Revit model below. I have used both the APS plugin on VScode and this site (https://oss-manager.autodesk.io) to upload and translate my model. With the same Revit file, I got 2 different kinds of models below with different URNs and did.
The weird thing is that I've managed to get the heatmaps and sensors to work in the second model ( the second picture), but not with the the first model (first picture). Recently, I accidentally deleted the second model (the working one) from my buckets. Now, whenever I upload my model with the above bucket tools, I always end up getting the first model which doesn't show any heatmaps.
I'd like to know if there is any way I can translate my model so that it will give me back the second model. Or how can I get the first model to work with heatmaps? I guess it might be something related to the model derivative or the model translation part.
Thank you.
https://github.com/autodesk-platform-services/aps-iot-extensions-demo
Thanks for the test model. Everything looks fine on my side. Please check my email for the snapshots.
Here is my code for producing sensor data in services/iot.mocked.js
:
async function findRoomRootNode(name, model) {
return new Promise(function (resolve, reject) {
model.getObjectTree(function (tree) {
let dbId = null;
tree.enumNodeChildren(tree.getRootId(), function (dbid) {
let n = tree.getNodeName(dbid, true);
if (n && n.indexOf(name) >= 0) {
dbId = dbid;
}
});
resolve(dbId);
}, reject);
});
}
async function findLeafNodes(rootId, model) {
return new Promise(function (resolve, reject) {
model.getObjectTree(function (tree) {
let leaves = [];
tree.enumNodeChildren(rootId, function (dbid) {
if (tree.getChildCount(dbid) === 0) {
leaves.push(dbid);
}
}, true /* recursively enumerate children's children as well */);
resolve(leaves);
}, reject);
});
}
function getBoundingBox(dbId, model) {
const it = model.getInstanceTree();
const fragList = model.getFragmentList();
let bounds = new THREE.Box3();
it.enumNodeFragments(dbId, (fragId) => {
let box = new THREE.Box3();
fragList.getWorldBounds(fragId, box);
bounds.union(box);
}, true);
return bounds;
}
async function getRoomsInfo(roomIds, model) {
return new Promise((resolve, reject) => {
model.getBulkProperties2(
roomIds,
{ propFilter: ['name', 'Name', 'Level', 'level' ], ignoreHidden: true },
(result) => {
let sensors = {};
for (let i = 0; i < result.length; i++) {
const data = result[i];
const dbId = data.dbId;
const levelProp = data.properties.find(p => p.attributeName.toLowerCase() === 'level');
const bounds = getBoundingBox(dbId, model);
const position = bounds.center();
sensors[`sensor-${i+1}`] = {
name: data.name,
description: '',
groupName: levelProp.displayValue,
location: {
x: position.x,
y: position.y,
z: position.z
},
objectId: dbId
}
}
resolve(sensors);
},
(error) => reject(error)
);
});
}
var roomRootId = await findRoomRootNode('Rooms', viewer)
var roomIds = await findLeafNodes(roomRootId, viewer.model);
await getRoomsInfo(roomIds, viewer.model);
Aftward, you must adjust the sensor data in the getSamples
function in services/iot.mocked.js
to make the number consistent with the sensor amount like below
async function getSamples(timerange, resolution = 32) {
return {
count: resolution,
timestamps: generateTimestamps(timerange.start, timerange.end, resolution),
data: {
'sensor-1': {
'temp': generateRandomValues(18.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-2': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-3': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-4': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-5': {
'temp': generateRandomValues(18.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-6': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-7': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-8': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-9': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-10': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-11': {
'temp': generateRandomValues(18.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-12': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-13': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-14': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-15': {
'temp': generateRandomValues(18.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-16': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-17': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-18': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-19': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-20': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-21': {
'temp': generateRandomValues(18.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-22': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-23': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-24': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-25': {
'temp': generateRandomValues(18.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-26': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-27': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-28': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-29': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-30': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-31': {
'temp': generateRandomValues(18.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-32': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-33': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-34': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-35': {
'temp': generateRandomValues(18.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-36': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-37': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-38': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-39': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-40': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-41': {
'temp': generateRandomValues(18.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-42': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-43': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-44': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-45': {
'temp': generateRandomValues(18.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-46': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-47': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-48': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-49': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-50': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-51': {
'temp': generateRandomValues(18.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-52': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-53': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-54': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-55': {
'temp': generateRandomValues(18.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-56': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-57': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-58': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-59': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-60': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-61': {
'temp': generateRandomValues(18.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-62': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-63': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-64': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-65': {
'temp': generateRandomValues(18.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-66': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-67': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-68': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-69': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-70': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-71': {
'temp': generateRandomValues(18.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-72': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-73': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-74': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-75': {
'temp': generateRandomValues(18.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-76': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-77': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-78': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-79': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
},
'sensor-80': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(600.0, 640.0, resolution, 5.0)
},
'sensor-81': {
'temp': generateRandomValues(18.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-82': {
'temp': generateRandomValues(20.0, 24.0, resolution, 1.0),
'co2': generateRandomValues(540.0, 600.0, resolution, 5.0)
},
'sensor-83': {
'temp': generateRandomValues(24.0, 28.0, resolution, 1.0),
'co2': generateRandomValues(500.0, 620.0, resolution, 5.0)
}
}
};
}
Regarding the second model, if you used the same APS_MODEL_VIEW
from the first model, then your view would be incorrect. The master views are generated during the Model Derivative translation, so their guid or viewable id will be different. You cannot reuse the same value and set it to APS_MODEL_VIEW
in public/config.js
. After retranslating the model, you must find the correct guid for the master view in the model manifest again.
To prevent this issue, we could give APS_MODEL_VIEW
an empty value and then modify public/viewer.js
// public/config.js
export const APS_MODEL_URN = 'dXJ....Z0';
export const APS_MODEL_VIEW = '';
export const APS_MODEL_DEFAULT_FLOOR_INDEX = 1;
export const DEFAULT_TIMERANGE_START = new Date('2023-12-30');
export const DEFAULT_TIMERANGE_END = new Date('2024-01-15');
// Replace the function `loadModel` in public/viewer.js with the below one
export function loadModel(viewer, urn, guid) {
return new Promise(function (resolve, reject) {
function onDocumentLoadSuccess(doc) {
const viewable = guid ? doc.getRoot().findByGuid(guid) : doc.getRoot().getDefaultGeometry(true);
resolve(viewer.loadDocumentNode(doc, viewable));
}
function onDocumentLoadFailure(code, message, errors) {
reject({ code, message, errors });
}
Autodesk.Viewing.Document.load('urn:' + urn, onDocumentLoadSuccess, onDocumentLoadFailure);
});
}