Reputation: 137
Following the tutorial for creating a custom data adapter: https://forge.autodesk.com/en/docs/dataviz/v1/developers_guide/advanced_topics/custom_data_adapter/
Getting error in chrome console:
Created file Hyperion.Data.BimapiDataAdapter in the folder forge-dataviz-iot-reference-app-main\node_modules\forge-dataviz-iot-data-modules\client\data based on the Hyperion.Data.Adapter file in the same folder. Then edited on line 371 and changed RestApiDataAdapter to BimapiDataAdapter.
Then trying to import this in BaseApp.jsx on line 34 in the folder forge-dataviz-iot-reference-app-main\node_modules\forge-dataviz-iot-react-components\client\components.
Upvotes: 0
Views: 194
Reputation: 7070
Your Hyperion.Data.BimapiDataAdapter.js
is not placed aside forge-dataviz-iot-react-components/BaseApp.jsx
, so the package-tool Webpack cannot it by ./Hyperion.Data.BimapiDataAdapter
in BaseApp.jsx
.
Here is my approach to exposing Hyperion.Data.BimapiDataAdapter.js
.
Hyperion.Data.BimapiDataAdapter.js
under forge-dataviz-iot-reference-app-main\node_modules\forge-dataviz-iot-data-modules\client\data
. Here is how it looks like (just copied and pasted the contents of RestApiDataAdapter
for the quick demo)import { DataAdapter } from './Hyperion.Data';
/**
* Data adapter class dealing with sample data.
* @memberof Autodesk.DataVisualization.Data
* @alias Autodesk.DataVisualization.Data.BimapiDataAdapter
* @augments DataAdapter
*/
export class BimapiDataAdapter extends DataAdapter {
/**
* Constructs an instance of BimapiDataAdapter.
*/
constructor(provider = "synthetic", baseName = "") {
super("BimapiDataAdapter", baseName);
/* eslint-disable no-undef */
this._provider = provider;
}
/**
* Loads all DeviceModel objects from the sample REST API.
*
* @returns {Promise<DeviceModel[]>} A promise that resolves to a single
* dimensional array containing a list of loaded DeviceModel objects. If no
* DeviceModel is available, the promise resolves to an empty array.
* @memberof Autodesk.DataVisualization.Data
* @alias Autodesk.DataVisualization.Data.BimapiDataAdapter#loadDeviceModels
*/
async loadDeviceModels() {
const adapterId = this.id;
return fetch(this._getResourceUrl("api/device-models"))
.then((response) => response.json())
.then((rawDeviceModels) => {
/** @type {DeviceModel[]} */
const normalizedDeviceModels = [];
rawDeviceModels.forEach((rdm) => {
// Create a normalized device model representation.
const ndm = new DeviceModel(rdm.deviceModelId, adapterId);
ndm.name = rdm.deviceModelName;
ndm.description = rdm.deviceModelDesc;
// Generate device property representation.
rdm.deviceProperties.forEach((rdp) => {
const propId = rdp.propertyId;
const propName = rdp.propertyName;
const ndp = ndm.addProperty(propId, propName);
ndp.description = rdp.propertyDesc;
ndp.dataType = rdp.propertyType;
ndp.dataUnit = rdp.propertyUnit;
ndp.rangeMin = rdp.rangeMin ? rdp.rangeMin : undefined;
ndp.rangeMax = rdp.rangeMax ? rdp.rangeMax : undefined;
});
normalizedDeviceModels.push(ndm);
});
// Fetch actual devices for each of the device models.
return this.fetchDevicesForModels(normalizedDeviceModels);
});
}
/**
* Fetches actual device IDs and populate DeviceModel objects with them.
*
* @param {DeviceModel[]} deviceModels The DeviceModel objects for which
* actual device IDs are to be populated.
*
* @returns {Promise<DeviceModel[]>} A promise that resolves to the
* DeviceModel objects populated with actual device IDs.
* @memberof Autodesk.DataVisualization.Data
* @alias Autodesk.DataVisualization.Data.BimapiDataAdapter#fetchDevicesForModels
*/
async fetchDevicesForModels(deviceModels) {
const promises = deviceModels.map((deviceModel) => {
const model = deviceModel.id;
return fetch(this._getResourceUrl("api/devices", { model: model }))
.then((response) => response.json())
.then((jsonData) => jsonData.deviceInfo);
});
return Promise.all(promises).then((deviceInfosList) => {
// Assign devices to each device model.
deviceModels.forEach((deviceModel, index) => {
// Turn data provider specific device data format into
// the unified data format stored in Device object.
//
const deviceInfos = deviceInfosList[index];
deviceInfos.forEach((deviceInfo) => {
const device = deviceModel.addDevice(deviceInfo.id);
device.name = deviceInfo.name;
const p = deviceInfo.position;
device.position = new THREE.Vector3(
parseFloat(p.x),
parseFloat(p.y),
parseFloat(p.z)
);
device.lastActivityTime = deviceInfo.lastActivityTime;
device.deviceModel = deviceModel;
device.sensorTypes = deviceModel.propertyIds;
});
});
return deviceModels;
});
}
/**
* Fetches the property data based on the given device ID.
*
* @param {QueryParam} query Parameters of this query.
*
* @returns {Promise<DeviceData>} A promise that resolves to an aggregated
* property data for the queried device.
* @memberof Autodesk.DataVisualization.Data
* @alias Autodesk.DataVisualization.Data.BimapiDataAdapter#fetchDeviceData
*/
async fetchDeviceData(query) {
const pids = query.propertyIds;
const promises = pids.map((pid) => this._fetchPropertyData(query, pid));
return Promise.all(promises).then((deviceDataList) => {
const deviceData = new DeviceData(query.deviceId);
deviceDataList.forEach((devData) => deviceData.mergeFrom(devData));
return deviceData;
});
}
/**
* Fetches data for a single property based on the given device ID.
*
* @param {QueryParam} query Parameters of this query.
* @param {string} propertyId The ID of the property.
*
* @returns {Promise<DeviceData>} A promise that resolves to an aggregated
* property data for the queried device.
*/
async _fetchPropertyData(query, propertyId) {
const url = this._getResourceUrl("api/aggregates", {
device: query.deviceId,
property: propertyId,
startTime: query.dateTimeSpan.startSecond,
endTime: query.dateTimeSpan.endSecond,
resolution: query.dateTimeSpan.resolution,
});
return fetch(url)
.then((response) => response.json())
.then((rawAggregates) => {
// Convert 'rawAggregates' which is in the following format, into 'AggregatedValues'
//
// rawAggregates = {
// timestamps: number[],
// count: number[],
// min: number[],
// max: number[],
// avg: number[],
// sum: number[],
// stdDev: number[]
// }
//
const aggrValues = new AggregatedValues(query.dateTimeSpan);
aggrValues.tsValues = rawAggregates.timestamps;
aggrValues.countValues = rawAggregates.count;
aggrValues.maxValues = rawAggregates.max;
aggrValues.minValues = rawAggregates.min;
aggrValues.avgValues = rawAggregates.avg;
aggrValues.sumValues = rawAggregates.sum;
aggrValues.stdDevValues = rawAggregates.stdDev;
aggrValues.setDataRange("avgValues", getPaddedRange(aggrValues.avgValues));
const deviceData = new DeviceData(query.deviceId);
const propertyData = deviceData.getPropertyData(propertyId);
propertyData.setAggregatedValues(aggrValues);
return deviceData;
})
.catch((err) => {
console.error(err);
});
}
/**
* Gets the resource URL for a given endpoint with query parameters
*
* @param {string} endpoint The endpoint for the URL to generate
* @param {Object.<string, string>} parameters Key-value pairs of query parameters
*
* @returns {string} The string that represents the complete resource URL
* @private
*/
_getResourceUrl(endpoint, parameters) {
parameters = parameters || {};
parameters["provider"] = this._provider;
parameters["project"] = "unused";
const ps = Object.entries(parameters).map(([k, v]) => `${k}=${v}`);
return `${this._baseName}/${endpoint}?${ps.join("&")}`;
}
}
BimapiDataAdapter
from ``forge-dataviz-iot-reference-app-main\node_modules\forge-dataviz-iot-data-modules\client.js`export * from "./client/data/Hyperion.Data";
export * from "./client/data/Hyperion.Data.BimapiDataAdapter"; //!<<< add this line
BimapiDataAdapter
in forge-dataviz-iot-reference-app-main\node_modules\forge-dataviz-iot-react-components\client\components\BaseApp.jsx
from where import { ... } from "forge-dataviz-iot-data-modules/client"
isimport {
Session,
AzureDataAdapter,
RestApiDataAdapter,
DataView,
DateTimeSpan,
EventType,
DeviceProperty,
DeviceModel,
BimapiDataAdapter //!<<< here it is
} from "forge-dataviz-iot-data-modules/client";
Afterward, re-execute ENV=local npm run dev
in your terminal console.
If you have further questions on how Webpack resolves packages, I would advise you to check these out:
Upvotes: 1