@mindconnect/mindconnect-nodejs
Version:
NodeJS Library for Siemens Insights Hub Connectivity - TypeScript SDK for Insights Hub and Industrial IoT - Command Line Interface - Insights Hub Development Proxy (Siemens Insights Hub was formerly known as MindSphere)
393 lines • 21.7 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __asyncValues = (this && this.__asyncValues) || function (o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
};
Object.defineProperty(exports, "__esModule", { value: true });
const console_1 = require("console");
const fs = require("fs");
const path = require("path");
const __1 = require("../..");
const utils_1 = require("../../api/utils");
const command_utils_1 = require("./command-utils");
const ora = require("ora-classic");
const cyan = (0, command_utils_1.getColor)("cyan");
let color = (0, command_utils_1.getColor)("magenta");
exports.default = (program) => {
program
.command("configure-agent")
.alias("co")
.option("-c, --config <agentconfig>", "config file with agent configuration")
.option("-m, --mode [mode]", "command mode [config|map|print|delete|test|func|template]", "config")
.option("-a, --agentid <agentid>", "agentid")
.option("-i, --assetid <assetid>", "target assetid for mapping")
.option("-t, --typeid <typeid>", "asset type for configuration")
.option("-l, --language [js|python|json]", "target language for conversion function", "js")
.option("-s, --timespan <timespan>", "timespan between generated timestamps (in ms)", "1000")
.option("-c, --count <count>", "Number of generated records", "10")
.option("-k, --passkey <passkey>", "passkey")
.option("-y, --retry <number>", "retry attempts before giving up", "3")
.option("-v, --verbose", "verbose output")
.description(`${cyan("create data source configuration and mappings")} ${color("(optional: passkey) *")}`)
.action((options) => {
(() => __awaiter(void 0, void 0, void 0, function* () {
try {
color = (0, command_utils_1.adjustColor)(color, options);
(0, command_utils_1.homeDirLog)(options.verbose, color);
(0, command_utils_1.proxyLog)(options.verbose, color);
checkParameters(options);
let agentid = options.agentid;
let agent;
const sdk = !options.config
? (() => {
color = (0, command_utils_1.adjustColor)(color, options);
return (0, command_utils_1.getSdk)(options);
})()
: (() => {
color = cyan;
const configFile = path.resolve(options.config);
(0, command_utils_1.verboseLog)(`agent configuration in: ${color(configFile)}.`, options.verbose);
!fs.existsSync(configFile) && (0, utils_1.throwError)(`Can't find file ${configFile}`);
const agentFolder = (0, utils_1.getAgentDir)(path.dirname(options.config));
(0, command_utils_1.verboseLog)(`Using .mc folder for agent: ${color(agentFolder)}`, options.verbose);
const configuration = require(configFile);
agent = new __1.MindConnectAgent(configuration, undefined, agentFolder);
agentid = agent.ClientId();
return new __1.MindSphereSdk(agent);
})();
options.mode === "print" && (yield print(sdk, agentid, color, options));
options.mode === "print" && process.exit(0);
options.mode === "func" && (yield printFunc(sdk, agentid, color, options));
options.mode === "func" && process.exit(0);
options.mode === "config" && (yield config(sdk, agentid, color, options));
options.mode === "delete" && (yield deleteMappings(sdk, agentid, color, options));
options.mode === "map" && (yield map(sdk, agentid, color, options));
options.mode === "template" && (yield template(sdk, agentid, color, options));
options.mode === "template" && process.exit(0);
options.mode === "test" && (yield inject(agent, color, options));
options.mode !== "test" && (yield print(sdk, agentid, color, options));
(0, command_utils_1.agentConfigLog)({
gateway: sdk.GetGateway(),
host: options.passkey ? "gateway" : "southgate",
tenant: sdk.GetTenant(),
agentid: agentid,
color: color,
});
}
catch (err) {
(0, command_utils_1.errorLog)(err, options.verbose);
}
}))();
})
.on("--help", () => {
(0, console_1.log)("\n Examples:\n");
(0, console_1.log)(` mdsp configure-agent --config agent.json -assetid 1234567...89 \tconfigures agent for specified assetid`);
(0, console_1.log)(` mdsp configure-agent --config agent.json --mode print \t\tprints data source configuration and mappings`);
(0, console_1.log)(` mdsp configure-agent --agentid 12345..ef --typeid <tenant>.Engine \tcreates the data source configuration`);
(0, console_1.log)(` mdsp configure-agent --mode map --agentid 12345..ef --assetid 1234567 creates the mappings for assetid`);
(0, console_1.log)(` mdsp configure-agent --mode delete --agentid 12345..ef \t\tdeletes the mappings for agentid`);
(0, console_1.log)(` mdsp configure-agent --config agent.json --mode test \t\t\tsends test data to mindsphere`);
(0, console_1.log)(` mdsp configure-agent --mode template \\`);
(0, console_1.log)(` \t--typeid castidev.Pump --language python \t\t\tcreate mapping template and function in python`);
});
};
function template(sdk, agentid, color, options) {
return __awaiter(this, void 0, void 0, function* () {
const assetType = yield sdk.GetAssetManagementClient().GetAssetType(options.typeid);
const dataSourceConfig = yield sdk.GetMindConnectApiClient().GenerateDataSourceConfiguration(assetType);
const dataSourceMappings = yield sdk
.GetMindConnectApiClient()
.GenerateMappings(dataSourceConfig, options.agentid || "<externalid>", options.assetid || "<assetid>");
fs.writeFileSync(`${options.typeid}.mapping.mdsp.json`, JSON.stringify(dataSourceMappings, null, 2));
console.log(`The file ${color(`${options.typeid}.mapping.mdsp.json`)} with mapping template was created.`);
printFunc(sdk, dataSourceConfig, color, options);
});
}
function map(sdk, agentid, color, options) {
return __awaiter(this, void 0, void 0, function* () {
var _a, e_1, _b, _c;
const spinner = ora(color("Creating mappings..."));
!options.verbose && spinner.start("");
const configuration = yield sdk.GetAgentManagementClient().GetDataSourceConfiguration(agentid);
const generateMappings = yield sdk
.GetMindConnectApiClient()
.GenerateMappings(configuration, agentid, options.assetid);
let i = 0;
try {
for (var _d = true, generateMappings_1 = __asyncValues(generateMappings), generateMappings_1_1; generateMappings_1_1 = yield generateMappings_1.next(), _a = generateMappings_1_1.done, !_a; _d = true) {
_c = generateMappings_1_1.value;
_d = false;
const mapping = _c;
const result = yield sdk.GetMindConnectApiClient().PostDataPointMapping(mapping, { ignoreCodes: [409] });
(0, command_utils_1.verboseLog)(`[${color(i++)}] ${mapping.dataPointId}-->${mapping.propertyName} ${mapping.propertySetName} (${mapping.entityId}) ${color(result ? "created" : "already existing")}`, options.verbose, spinner);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (!_d && !_a && (_b = generateMappings_1.return)) yield _b.call(generateMappings_1);
}
finally { if (e_1) throw e_1.error; }
}
spinner.stop();
});
}
function deleteMappings(sdk, agentid, color, options) {
return __awaiter(this, void 0, void 0, function* () {
var _a, e_2, _b, _c;
const filter = { agentId: agentid };
if (options.assetid) {
filter.entityId = options.assetid;
}
const mappings = yield sdk
.GetMindConnectApiClient()
.GetDataPointMappings({ filter: JSON.stringify(filter), size: 2000 });
try {
for (var _d = true, _e = __asyncValues(mappings.content), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
_c = _f.value;
_d = false;
const mapping = _c;
yield sdk.GetMindConnectApiClient().DeleteDataMapping(mapping.id, { ignoreCodes: [404] });
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
}
finally { if (e_2) throw e_2.error; }
}
});
}
function print(sdk, agentid, color, options) {
return __awaiter(this, void 0, void 0, function* () {
const configuration = yield sdk.GetAgentManagementClient().GetDataSourceConfiguration(agentid);
const mappings = yield sdk
.GetMindConnectApiClient()
.GetDataPointMappings({ filter: JSON.stringify({ agentId: agentid }), size: 2000 });
console.log(`Configuration for ${color(agentid)} ${color(configuration.configurationId)} eTag: ${configuration.eTag}`);
console.log(`Data Sources (${color(configuration.dataSources.length)}) :`);
configuration.dataSources.forEach((element) => {
console.log(` - ${color(element.name)} (${color(element.dataPoints.length)})`);
element.dataPoints.forEach((dataPoint) => {
console.log(`\t - ${color(dataPoint.id)} ${dataPoint.name} (${color(dataPoint.type)}) ${dataPoint.unit}`);
});
});
console.log(`Mappings count: ${color(mappings.content.length)}`);
let i = 0;
mappings.content.forEach((mapping) => {
console.log(`\t - [${color(i++)}] ${mapping.dataPointId}-->${mapping.propertyName} ${mapping.propertySetName} (${mapping.entityId}) `);
});
(0, command_utils_1.verboseLog)(JSON.stringify(configuration, null, 2), options.verbose);
(0, command_utils_1.verboseLog)(JSON.stringify(mappings, null, 2), options.verbose);
});
}
function printFunc(sdk, agentOrConfig, color, options) {
return __awaiter(this, void 0, void 0, function* () {
let configuration = agentOrConfig;
if (typeof agentOrConfig === "string") {
configuration = yield sdk.GetAgentManagementClient().GetDataSourceConfiguration(agentOrConfig);
}
switch (options.language) {
case "js":
yield printFuncJs(configuration, color, options);
break;
case "python":
yield printFuncPython(configuration, color, options);
break;
case "json":
yield printFuncJson(configuration, color, options);
break;
default:
(0, utils_1.throwError)(`invalid language ${options.language}`);
}
});
}
function printFuncJson(configuration, color, options) {
return __awaiter(this, void 0, void 0, function* () {
const result = {
mappings: [],
};
configuration.dataSources.forEach((element) => {
if (!element.customData) {
throw Error("cant create function there is no custom data avaiable, the config was not done via CLI");
}
element.dataPoints.forEach((dataPoint) => {
if (!dataPoint.customData) {
throw Error("cant create function there is no custom data avaiable, the config was not done via CLI");
}
result.mappings.push({
aspect: `${element.customData.aspect}`,
variable: `${dataPoint.customData.variable}`,
dataPointId: `${dataPoint.id}`,
});
});
});
fs.writeFileSync(`${options.typeid}.fulltable.mdsp.json`, JSON.stringify(result, null, 2));
console.log(`The file ${color(`${options.typeid}.fulltable.mdsp.json`)} with full JSON mapping table was created.`);
(0, command_utils_1.verboseLog)(result, options.verbose);
});
}
function printFuncJs(configuration, color, options) {
return __awaiter(this, void 0, void 0, function* () {
let result = "";
result += "\nfunction convertToDataPoint (rawVariable, aspect) {";
result += "\n let variable = rawVariable;";
result += "\n variable = variable.replace(' ', '_');";
result += "\n variable = variable.replace('-', '_');";
result += "\n variable = variable.replace(/[\\W_]/g, '_');";
result += "\n variable = variable.trim();";
result += "\n variable = variable.replace(/^[_]/, '');";
configuration.dataSources.forEach((element) => {
if (!element.customData) {
throw Error("cant create function there is no custom data avaiable, the config was not done via CLI");
}
result += `\n if (aspect === '${element.customData.aspect}') { `;
element.dataPoints.forEach((dataPoint) => {
if (!dataPoint.customData) {
throw Error("cant create function there is no custom data avaiable, the config was not done via CLI");
}
if (dataPoint.id !== `DP-${dataPoint.customData.variable}`) {
result += `\n if (variable === '${dataPoint.customData.variable}') return '${dataPoint.id}';`;
}
});
result += `\n return \`DP-\${variable}\`;`;
result += `\n }`;
});
result += "\n}";
fs.writeFileSync(`${options.typeid}.map.mdsp.js`, result);
console.log(`The file ${color(`${options.typeid}.map.mdsp.js`)} with mapping function was created.`);
(0, command_utils_1.verboseLog)(result, options.verbose);
});
}
function printFuncPython(configuration, color, options) {
return __awaiter(this, void 0, void 0, function* () {
let result = "import re\n";
result += "\ndef convertToDataPoint (rawVariable, aspect):";
result += "\n\tvariable = rawVariable";
result += "\n\tvariable = variable.replace(' ', '_')";
result += "\n\tvariable = variable.replace('-', '_')";
result += "\n\tvariable = re.sub(r'[\\W_]', '_', variable)";
result += "\n\tvariable = variable.strip()";
result += "\n\tvariable = re.sub(r'^[_]', '', variable)";
configuration.dataSources.forEach((element) => {
if (!element.customData) {
throw Error("cant create function there is no custom data avaiable, the config was not done via CLI");
}
result += `\n\tif aspect == '${element.customData.aspect}': `;
element.dataPoints.forEach((dataPoint) => {
if (!dataPoint.customData) {
throw Error("cant create function there is no custom data avaiable, the config was not done via CLI");
}
if (dataPoint.id !== `DP-${dataPoint.customData.variable}`) {
result += `\n\t\tif variable == '${dataPoint.customData.variable}': return '${dataPoint.id}'`;
}
});
result += `\n\t\treturn "DP-" + variable`;
result += `\n`;
});
result += "\n";
fs.writeFileSync(`${options.typeid}.map.mdsp.py`, result);
console.log(`The file ${color(`${options.typeid}.map.mdsp.py`)} with mapping function was created.`);
(0, command_utils_1.verboseLog)(result, options.verbose);
});
}
function config(sdk, agentid, color, options) {
return __awaiter(this, void 0, void 0, function* () {
let assettypeid = options.typeid;
if (options.assetid) {
const asset = sdk.GetAssetManagementClient().GetAsset(options.assetid);
assettypeid = (yield asset).typeId;
}
const assetType = yield sdk.GetAssetManagementClient().GetAssetType(assettypeid, { exploded: true });
const mcapi = sdk.GetMindConnectApiClient();
const dataSourceConfiguration = mcapi.GenerateDataSourceConfiguration(assetType);
const oldConfig = sdk.GetAgentManagementClient().GetDataSourceConfiguration(agentid);
const etag = (yield oldConfig).eTag || "0";
yield sdk
.GetAgentManagementClient()
.PutDataSourceConfiguration(agentid, dataSourceConfiguration, { ifMatch: etag });
options.assetid && (yield map(sdk, agentid, color, options));
});
}
function checkParameters(options) {
["map", "config", "print", "delete", "test", "func", "template"].indexOf(options.mode) < 0 &&
(0, utils_1.throwError)("The mode must be map | configure | print | delete | test | func | template");
options.passkey &&
options.mode === "test" &&
(0, utils_1.throwError)("test only works with agent configuration not with passkey");
options.passkey && !options.agentid && (0, utils_1.throwError)("you have to specify agentid when using passkey mode");
options.mode === "config" &&
!((options.assetid && !options.typeid) || (!options.assetid && options.typeid)) &&
(0, utils_1.throwError)("you have to specify either assetid or typeid for config mode but not both");
options.mode === "test" &&
!(options.timespan && options.count) &&
(0, utils_1.throwError)("you have to specify the timespan and the count");
options.mode === "template" &&
!options.typeid &&
(0, utils_1.throwError)("you have to specify the typeid to generate mapping templates");
(options.mode === "template" || options.mode === "func") &&
["js", "json", "python"].indexOf(options.language) < 0 &&
(0, utils_1.throwError)("the language has to be either js, json or python");
["map"].indexOf(options.mode) >= 0 &&
!options.assetid &&
(0, utils_1.throwError)(`you have to specify assetid for ${options.mode}`);
}
function inject(agent, color, options) {
return __awaiter(this, void 0, void 0, function* () {
const configuration = yield agent.GetDataSourceConfiguration();
const bulkData = [];
const span = parseInt(options.timespan);
const count = parseInt(options.count);
let dataPointsCount = 0;
let startTime = new Date().getTime() - span * count;
for (let index = 0; index < options.count; index++) {
const data = [];
const timeStamp = new Date(startTime);
configuration.dataSources.forEach((datasource) => {
datasource.dataPoints.forEach((dp) => {
data.push({
dataPointId: dp.id,
qualityCode: "0",
value: generateValue(dp.type.toString(), timeStamp),
});
dataPointsCount++;
});
});
bulkData.push({ timestamp: timeStamp.toISOString(), values: data });
startTime += parseInt(options.timespan);
}
(0, command_utils_1.verboseLog)(JSON.stringify(bulkData, null, 2), options.verbose);
yield (0, utils_1.retry)(options.retry, () => agent.BulkPostData(bulkData));
console.log(`Injected a bulk message with ${color(count)} timestamps and total number of ${color(dataPointsCount)} datapoints.`);
});
}
function generateValue(type, timeStamp) {
let result = 100 * Math.sin(timeStamp.getTime());
if (type === "INT" || type === "LONG") {
result = Math.floor(result);
}
else if (type === "TIMESTAMP") {
result = new Date().toISOString();
}
else if (type === "BOOLEAN") {
result = Math.floor(result) % 2 === 0;
}
else if (type === "STRING" || type === "BIG_STRING") {
result = `${type}_${result}`;
}
return result.toString();
}
//# sourceMappingURL=mc-automap.js.map