@mindconnect/mindconnect-nodejs
Version:
NodeJS Library for MindSphere Connectivity - TypeScript SDK for MindSphere - MindSphere Command Line Interface - MindSphere Development Proxy
208 lines • 11.3 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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const console_1 = require("console");
const fs = require("fs");
const lodash_1 = require("lodash");
const path = require("path");
const utils_1 = require("../../api/utils");
const command_utils_1 = require("./command-utils");
let color = (0, command_utils_1.getColor)("blue");
exports.default = (program) => {
program
.command("signal-calculation")
.alias("cal")
.option("-m, --mode [template|calculate]", "template | calculate", "template")
.option("-o, --on [data|asset]", "on [data | asset]", "data")
.option("-f, --template <template>", ".mdsp.json template file default: (signal.[template|templatedirect].mdsp.json)")
.option("-u, --result <result>", ".mdsp.json with signal calculation result", "signal.result.mdsp.json")
.option("-i, --assetid <assetid>", `assetid for template creation`)
.option("-a, --aspect <aspect>", `aspect for template creation`)
.option("-r, --variable <variable>", `variables for template creation`)
.option("-s, --size <size>", `timeseries length for generated data`, "5")
.option("-t, --timeseries <timeseries>", `comma separated list of time series files (if data is not embedded)`)
.option("-o, --overwrite", "overwrite template file if it already exists")
.option("-k, --passkey <passkey>", "passkey")
.option("-y, --retry <number>", "retry attempts before giving up", "3")
.option("-v, --verbose", "verbose output")
.description(color("process timeseries data *"))
.action((options) => {
(() => __awaiter(void 0, void 0, void 0, function* () {
try {
checkRequiredParamaters(options);
const sdk = (0, command_utils_1.getSdk)(options);
color = (0, command_utils_1.adjustColor)(color, options, true);
(0, command_utils_1.homeDirLog)(options.verbose, color);
(0, command_utils_1.proxyLog)(options.verbose, color);
switch (options.mode) {
case "template":
options.on === "data" && createTemplate(options);
options.on === "asset" && createTemplateDirect(options);
console.log("Edit the files before submitting them to mindsphere.");
break;
case "calculate":
options.on === "data" && (yield calculateSignal(options, sdk));
options.on === "asset" && (yield calculateSignalDirect(options, sdk));
break;
default:
throw Error(`no such option: ${options.mode}`);
}
}
catch (err) {
(0, command_utils_1.errorLog)(err, options.verbose);
}
}))();
})
.on("--help", () => {
(0, console_1.log)("\n Examples:\n");
(0, console_1.log)(` mc signal-calculation --mode template \t create template file for signal calculation`);
(0, console_1.log)(` mc signal-calculation --mode template --on asset --assetid <assetid> --aspect <aspect> --variable variable\n\
\t creates template for calculation using mindsphere timeseries data`);
(0, console_1.log)(` mc signal-calculation --mode calculate --template <filename> \n\
\t calculates new signal from the timeseries specified in template file`);
(0, console_1.log)(` mc signal-calculation --mode calculate \\
--template <filename> \\
--timeseries <timeseriesfile> \\
--assetid <assetid> \\
--aspect <aspect>\n\
\t calculates new signal from the timeseries specified in external file`);
(0, console_1.log)(` mc signal-calculation --mode calculate --on asset --template <filename> \n\
\t calculates new signal from the mindsphere timeseries`);
(0, console_1.log)(`\n Operation List: \n`);
(0, console_1.log)(` ${color("https://developer.mindsphere.io/apis/analytics-signalcalculation/api-signalcalculation-overview.html")}\n`);
(0, command_utils_1.serviceCredentialLog)();
});
};
function checkRequiredParamaters(options) {
options.mode === "calculate" &&
!options.template &&
(0, command_utils_1.errorLog)("you have to provide a file with signal calculation parameters (see mc signal-calculation --help for more details)", true);
options.on !== "data" &&
options.on !== "asset" &&
(0, command_utils_1.errorLog)("you have to specify if the calculation is applied --on data or --on asset", true);
}
function createTemplate(options) {
const template = {
configuration: {
operation: "SIN",
params: [],
operands: [],
result: {
entityId: options.assetid || "assetid",
propertySetName: "resultAspect",
propertyName: "result",
},
},
data: [],
};
const variable = (options.variable || "variable1").trim();
template.configuration.operands.push({
entityId: options.assetid || "assetid",
propertySetName: options.aspect || "aspect",
propertyName: variable,
});
const data = (0, command_utils_1.generateTestData)(options.size, (x) => x, variable, "number");
template.data.push({
entityId: options.assetid || "assetid",
propertySetName: options.aspect || "aspect",
timeSeries: data,
});
(0, command_utils_1.verboseLog)(template, options.verbose);
const fileName = options.template || `signal.calculation.mdsp.json`;
writeToFile(fileName, options, template);
console.log(`The data was written into ${color(fileName)} run \n\n\tmc signal-calculation --mode calculate --on data --template ${fileName} \n\nto calculate the signal.`);
}
function createTemplateDirect(options) {
const template = {
configuration: {
operation: "SIN",
params: [],
operands: [],
result: {
assetId: options.assetid || "assetid",
aspectName: "resultAspect",
variableName: "result",
},
},
};
const variable = (options.variable || "variable1").trim();
const now = new Date();
const hourBefore = new Date(now);
hourBefore.setHours(hourBefore.getHours() - 1);
template.configuration.operands.push({
assetId: options.assetid || "assetid",
aspectName: options.aspect || "aspect",
variableName: variable,
from: hourBefore.toISOString(),
to: now.toISOString(),
});
(0, command_utils_1.verboseLog)(template, options.verbose);
const fileName = options.template || `signal.calculation.direct.mdsp.json`;
writeToFile(fileName, options, template);
console.log(`The data was written into ${color(fileName)} run \n\n\tmc signal-calculation --mode calculate --on asset --template ${fileName} \n\nto calculate the signal.`);
}
function writeToFile(fileName, options, jsonData) {
const filePath = path.resolve(fileName);
fs.existsSync(filePath) &&
!options.overwrite &&
(0, utils_1.throwError)(`The ${filePath} already exists. (use --overwrite to overwrite) `);
fs.writeFileSync(filePath, JSON.stringify(jsonData, null, 2));
return fileName;
}
function calculateSignal(options, sdk) {
return __awaiter(this, void 0, void 0, function* () {
const pathInfo = path.resolve(options.template);
const metadataContent = fs.readFileSync(pathInfo);
const metadata = JSON.parse(metadataContent.toString());
if (options.timeseries) {
const timeseriesFiles = (options.timeseries || "").split(",");
timeseriesFiles.forEach((element) => {
const fileName = path.resolve(element.trim());
const data = JSON.parse(fs.readFileSync(fileName).toString());
console.log((0, lodash_1.isArray)(data), options.assetid, options.aspect);
if ((0, lodash_1.isArray)(data)) {
// this looks like the raw timeseries
!options.assetid &&
(0, command_utils_1.errorLog)("you have to specify the --assetid if you are using raw time series", true);
!options.aspect && (0, command_utils_1.errorLog)("you have to specify the --aspect if you are using raw time series", true);
metadata.data.push({ entityId: options.assetid, propertySetName: options.aspect, timeSeries: data });
}
else {
metadata.data.push(data);
}
});
}
const result = yield sdk.GetSignalCalculationClient().PostApplyOperation(metadata);
(0, command_utils_1.verboseLog)(JSON.stringify(result, null, 2), options.verbose);
console.log(`Signal Calculation Results:`);
console.log(`entityid: ${color(result.entityId)}, aspect: ${color(result.propertySetName)}\n`);
console.table(result.timeSeries);
const fileName = options.result || `signal.result.mdsp.json`;
writeToFile(fileName, options, result);
console.log(`The result of signal calculation was written into ${color(fileName)}.`);
});
}
function calculateSignalDirect(options, sdk) {
return __awaiter(this, void 0, void 0, function* () {
const pathInfo = path.resolve(options.template);
const metadataContent = fs.readFileSync(pathInfo);
const metadata = JSON.parse(metadataContent.toString());
const result = yield sdk.GetSignalCalculationClient().PostApplyOperationDirect(metadata);
(0, command_utils_1.verboseLog)(JSON.stringify(result, null, 2), options.verbose);
console.log(`Signal Calculation Results:`);
console.log(`assetId: ${color(result.assetId)}, aspect: ${color(result.aspectName)}\n`);
console.table(result.timeSeries);
const fileName = options.result || `signal.result.direct.mdsp.json`;
writeToFile(fileName, options, result);
console.log(`The result of signal calculation was written into ${color(fileName)}.`);
});
}
//# sourceMappingURL=signal-calculation.js.map