Related
I had an issue earlier and received some help with it earlier but now i'm having an issue updating/adding a link to earlier issue.
I have a slightly different setup at this point because i couldn't figure out how to update my data.
At this point. I need to get the data from my Array A (filepath) into my list of objects as another property in my sub object with a key of "-i".
I feel like i should be able to iterate through the array and add one of these values to my object but i've tried using the reduce and loop features but haven't been able to get my desired output, if there's a easier way from starting with my last post issue i'd be happy to go back to that state.
//Desired ouput
{
process0000x0000: {-i:"D:\\Code\\UnitTest\\Tests\\Run_01_TEMP\\0000x0000.png, tr: 16, tc: 16, ofr: 16, ofc: 16, outfile: 'D:\\Code\\Process\\1' },
process0000x0001: {-i:"D:\\Code\\UnitTest\\Tests\\Run_01_TEMP\\0000x0001.png", tr: 16, tc: 16, ofr: 16, ofc: 16, outfile: 'D:\\Code\\Process\\1' },
process0000x0002: {-i:"D:\\Code\\UnitTest\\Tests\\Run_01_TEMP\\0000x0002.png", tr: 16, tc: 16, ofr: 16, ofc: 16, outfile: 'D:\\Code\\Process\\1' }
}
//Array A
"outputParameters": [
{
"name": "0000x0000",
"filepath": "D:\\Code\\UnitTest\\Tests\\Run_01_TEMP\\0000x0000.png"
},
{
"name": "0000x0001",
"filepath": "D:\\Code\\UnitTest\\Tests\\Run_01_TEMP\\0000x0001.png"
},
{
"name": "0000x0002",
"filepath": "D:\\Code\\UnitTest\\Tests\\Run_01_TEMP\\0000x0002.png"
}]
// current output
{
process0000x0000: { tr: 16, tc: 16, ofr: 16, ofc: 16, outfile: 'D:\\Code\\Process\\1' },
process0000x0001: { tr: 16, tc: 16, ofr: 16, ofc: 16, outfile: 'D:\\Code\\Process\\1' },
process0000x0002: { tr: 16, tc: 16, ofr: 16, ofc: 16, outfile: 'D:\\Code\\Process\\1' }
}
UPDATE:
so i added the below but i'm still receiving the last "filepath" for each entry in my consoleparamscompiled data. I tried your way and the way i have shown below but with the same results.
//results
},
process13x21: {
'-i': 'D:\\Code\\UnitTest\\ConsoleApp\\1\\13x23.png',
'-tr': 16,
'-tc': 16,
'-ofr': 16,
'-ofc': 16,
'-outfile': '"D:\\Code\\UnitTest\\ConsoleApp\\Process\\1"'
},
process13x22: {
'-i': 'D:\\Code\\UnitTest\\ConsoleApp\\1\\13x23.png',
'-tr': 16,
'-tc': 16,
'-ofr': 16,
'-ofc': 16,
'-outfile': '"D:\\Code\\UnitTest\\ConsoleApp\\Process\\1"'
},
process13x23: {
'-i': 'D:\\Code\\UnitTest\\ConsoleApp\\1\\13x23.png',
'-tr': 16,
'-tc': 16,
'-ofr': 16,
'-ofc': 16,
'-outfile': '"D:\\Code\\UnitTest\\ConsoleApp\\Process\\1"'
}
}
// ADDED CODE
// loop through each data we want to add and add a property.
` consoleOutputParamsOBJ.forEach((obj) => {
var processname = dynamicTaskNameBaseOBJ + obj.name;
console.log(processname);
//taskparamscompiled.processname['-i'] = obj.filepath;
taskparamscompiled[processname]['-i'] = obj.filepath;
// console.log(dynamicTaskNameBaseOBJ + obj.name);
});
console.log(taskparamscompiled);`
I'm not 100% sure I understand your question, but here goes.
You can access an objects property by a string by using [] instead of .
E.g.
let x = {name: "chris"};
x.name = 'Sam';
x['name'] = 'Ben';
The above will both change the name property
Here is a code example with the data you provided.
let data = [{
"name": "0000x0000",
"filepath": "D:\\Code\\UnitTest\\Tests\\Run_01_TEMP\\0000x0000.png"
}, {
"name": "0000x0001",
"filepath": "D:\\Code\\UnitTest\\Tests\\Run_01_TEMP\\0000x0001.png"
}, {
"name": "0000x0002",
"filepath": "D:\\Code\\UnitTest\\Tests\\Run_01_TEMP\\0000x0002.png"
}];
let result = {
process0000x0000: {
tr: 16,
tc: 16,
ofr: 16,
ofc: 16,
outfile: 'D:\\Code\\Process\\1'
},
process0000x0001: {
tr: 16,
tc: 16,
ofr: 16,
ofc: 16,
outfile: 'D:\\Code\\Process\\1'
},
process0000x0002: {
tr: 16,
tc: 16,
ofr: 16,
ofc: 16,
outfile: 'D:\\Code\\Process\\1'
}
}
// loop through each data we want to add and add a property.
data.forEach(obj => {
result[`process${obj.name}`]["-i"] = obj.filepath
})
console.log(result)
And the output is :
{
process0000x0000: {
-i: "D:\Code\UnitTest\Tests\Run_01_TEMP\0000x0000.png",
ofc: 16,
ofr: 16,
outfile: "D:\Code\Process\1",
tc: 16,
tr: 16
},
process0000x0001: {
-i: "D:\Code\UnitTest\Tests\Run_01_TEMP\0000x0001.png",
ofc: 16,
ofr: 16,
outfile: "D:\Code\Process\1",
tc: 16,
tr: 16
},
process0000x0002: {
-i: "D:\Code\UnitTest\Tests\Run_01_TEMP\0000x0002.png",
ofc: 16,
ofr: 16,
outfile: "D:\Code\Process\1",
tc: 16,
tr: 16
}
}
Hiii, some body know how i can write Uint16Array in kepserver i got some error:
ConstantStatusCode {
_value: 2147483648,
_description: 'The value is bad but no specific reason is known.',
_name: 'Bad' } ]
i'm try this:
var valor = new Uint16Array([ 2, 23, 23, 12, 24, 3, 25, 3, 26, 3, 27, 3, 28, 1, 43690, 1, 1261, 0, 0, 0, 0, 0, 0, 0, 65535, 11 ])
nodeToWrite[0] = {
nodeId: resolveNodeId("ns=2;s=" + endereco[0].ADDRESS),
attributeId: opcua.AttributeIds.Value,
value: /new DataValue(/{ value: {/ Variant /
dataType: 5,
arrayType: 1,
value: valor,
}
}
}
const {AttributeIds, OPCUAClient, DataType, VariantArrayType} = require("node-opcua");
const endpointUrl = "opc.tcp://localhost:48010";
(async () => {
const client = OPCUAClient.create({ endpoint_must_exist: false});
await client.withSessionAsync(endpointUrl, async (session) => {
const arrayOfvalues = new Uint16Array([ 2, 23, 23, 12, 24, 3, 25, 3, 26, 3, 27, 3, 28, 1, 43690, 1, 1261, 0, 0, 0, 0, 0, 0, 0, 65535, 11 ]);
const nodeToWrite = {
nodeId: "ns=2;s=Demo.Static.Arrays.UInt16",
attributeId: AttributeIds.Value,
value: {
value: {
dataType: DataType.UInt16,
arrayType: VariantArrayType.Array,
value: arrayOfvalues,
}
}
}
const statusCode = await session.write(nodeToWrite);
console.log("write statusCode = ",statusCode.toString());
});
})();
As demonstrated above, writing a Array of Uint16 is ok when addressing node ns=2;s=Demo.Static.Arrays.UInt16 of UAServerCPP from Unified Automation.
I would contact Kepware for support.
I'm creating an API with Express and SQL Server as DB. I've created a post method and it works fine, but i'm having problems with the get method, 'cause it's returning two objects with the same data. This is my code:
const express = require('express');
const bodyParser = require('body-parser');
const sql = require('mssql');
const app = express();
app.use(bodyParser.json());
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, contentType,Content-Type, Accept, Authorization");
next();
});
const dbConfig = {
user: "theUser",
password: "thePass",
server: "theServer",
database: "theDB"
}
const executeQuery = function (res, query) {
sql.connect(dbConfig, function (err) {
if (err) {
console.log(err);
res.send(err);
}
else {
// create Request object
var request = new sql.Request();
// query to the database
request.query(query, function (err, result) {
if (err) {
console.log(err);
res.send(err);
}
else {
res.send(result);
sql.close();
}
});
}
});
}
//Get All
app.get("/api/HolidayBaseApi", function (req, res) {
var query = "SELECT * FROM [HolidaysBase]";
executeQuery(res, query);
//executeQuery(res, query);
});
app.post("/api/HolidayBaseApi", function (req, res) {
var query = "INSERT INTO [HolidaysBase] (EmployeeNumber, PeriodBegin, PeriodEnd, WorkedYears, DaysPerYear, TakenDays, RemainingDays) VALUES ('"+req.body.EmployeeNumber+"','"+req.body.PeriodBegin+"','"+req.body.PeriodEnd+"','"+req.body.WorkedYears+"','"+req.body.DaysPerYear+"','"+req.body.TakenDays+"','"+req.body.RemainingDays+"')";
executeQuery(res, query);
});
const PORT = process.env.PORT || 8080
app.listen(PORT, () => {
console.log("App now running on port", PORT);
});
I'm testing on postman and i have the next return:
{
"recordsets": [
[
{
"Id": 1,
"EmployeeNumber": 4,
"PeriodBegin": "2018-04-01T00:00:00.000Z",
"PeriodEnd": "2019-03-31T00:00:00.000Z",
"WorkedYears": 6,
"DaysPerYear": 18,
"TakenDays": 10,
"RemainingDays": 8
},
{
"Id": 2,
"EmployeeNumber": 5,
"PeriodBegin": "2018-08-02T00:00:00.000Z",
"PeriodEnd": "2018-07-31T00:00:00.000Z",
"WorkedYears": 6,
"DaysPerYear": 18,
"TakenDays": 9,
"RemainingDays": 9
},
{
"Id": 5,
"EmployeeNumber": 9,
"PeriodBegin": "2018-10-15T00:00:00.000Z",
"PeriodEnd": "2019-10-15T00:00:00.000Z",
"WorkedYears": 6,
"DaysPerYear": 18,
"TakenDays": 0,
"RemainingDays": 18
}
]
],
"recordset": [
{
"Id": 1,
"EmployeeNumber": 4,
"PeriodBegin": "2018-04-01T00:00:00.000Z",
"PeriodEnd": "2019-03-31T00:00:00.000Z",
"WorkedYears": 6,
"DaysPerYear": 18,
"TakenDays": 10,
"RemainingDays": 8
},
{
"Id": 2,
"EmployeeNumber": 5,
"PeriodBegin": "2018-08-02T00:00:00.000Z",
"PeriodEnd": "2018-07-31T00:00:00.000Z",
"WorkedYears": 6,
"DaysPerYear": 18,
"TakenDays": 9,
"RemainingDays": 9
},
{
"Id": 5,
"EmployeeNumber": 9,
"PeriodBegin": "2018-10-15T00:00:00.000Z",
"PeriodEnd": "2019-10-15T00:00:00.000Z",
"WorkedYears": 6,
"DaysPerYear": 18,
"TakenDays": 0,
"RemainingDays": 18
}
],
"output": {},
"rowsAffected": [
3
]
}
As you can see, it's returning two times the same object. Someone knows why it's returning two recordset and how can i fix it? I've been searching since yesterday, but there's no info of this behavior.
I'm using Express.js, Node and SQL Server.
I've found the solution by myself. On my executeQuery just need to get inside of the recordsets in the result:
const executeQuery = function (res, query) {
sql.connect(dbConfig, function (err) {
if (err) {
console.log(err);
res.send(err);
}
else {
// create Request object
var request = new sql.Request();
// query to the database
request.query(query, function (err, result) {
if (err) {
console.log(err);
res.send(err);
}
else {
res.send(result.recordsets);
sql.close();
}
});
}
});
}
Doing this, i have kinda object inside of an object as a response:
[
[
{
"Id": 1,
"EmployeeNumber": 4,
"PeriodBegin": "2018-04-01T00:00:00.000Z",
"PeriodEnd": "2019-03-31T00:00:00.000Z",
"WorkedYears": 6,
"DaysPerYear": 18,
"TakenDays": 10,
"RemainingDays": 8
},
{
"Id": 2,
"EmployeeNumber": 5,
"PeriodBegin": "2018-08-02T00:00:00.000Z",
"PeriodEnd": "2018-07-31T00:00:00.000Z",
"WorkedYears": 6,
"DaysPerYear": 18,
"TakenDays": 9,
"RemainingDays": 9
},
{
"Id": 5,
"EmployeeNumber": 9,
"PeriodBegin": "2018-10-15T00:00:00.000Z",
"PeriodEnd": "2019-10-15T00:00:00.000Z",
"WorkedYears": 6,
"DaysPerYear": 18,
"TakenDays": 0,
"RemainingDays": 18
},
{
"Id": 6,
"EmployeeNumber": 37,
"PeriodBegin": "2018-07-27T00:00:00.000Z",
"PeriodEnd": "2019-07-27T00:00:00.000Z",
"WorkedYears": 4,
"DaysPerYear": 16,
"TakenDays": 3,
"RemainingDays": 13
},
{
"Id": 7,
"EmployeeNumber": 77,
"PeriodBegin": "2018-01-30T00:00:00.000Z",
"PeriodEnd": "2019-01-30T00:00:00.000Z",
"WorkedYears": 6,
"DaysPerYear": 18,
"TakenDays": 18,
"RemainingDays": 0
}
]
]
So, the final solution is get inside of the object and bring the first index on the request.object:
request.query(query, function (err, result) {
if (err) {
console.log(err);
res.send(err);
}
else {
res.send(result.recordsets[0]);
sql.close();
}
});
I am detecting beacons and getting JSON data from which I can get Mac Address of Beacon but I need information about battery level.
Currently I am using node js and using Noble module for searching beacons.
var https = require('https'),
myip = require('quick-local-ip'),
noble = require('noble'),
os = require('os'),
amqp = require('amqp');
noble.on('stateChange', function (state) {
if (state === 'poweredOn') {
console.log("start scanning");
noble.startScanning([], true);
} else {
noble.removeAllListener();
noble.stopScanning();
console.log("stop scanning, is Bluetooth on?");
}
noble.on('discover', function (peripheral) {console.log("peripheral - "+peripheral);}
Output -
{
"id": "ac233f244b34",
"address": "ac:23:3f:24:4b:34",
"addressType": "public",
"connectable": true,
"advertisement": {
"manufacturerData": {
"type": "Buffer",
"data": [76, 0, 2, 21, 226, 197, 109, 181, 223, 251, 72, 210, 176, 96, 208, 245, 167, 16, 150, 224, 0, 1, 0, 1, 129]
},
"serviceData": [{
"uuid": "feaa",
"data": {
"type": "Buffer",
"data": [32, 0, 12, 120, 24, 0, 0, 0, 251, 140, 1, 223, 146, 120]
}
}],
"serviceUuids": ["feaa"],
"solicitationServiceUuids": [],
"serviceSolicitationUuids": []
},
"rssi": -48,
"state": "disconnected"
}
How can I Get to know about Battery level from this data.
I want to render a stacked bar graph in image format on the server.
The intended use is to push to a service like twitter that doesn't support SVG. As well as the code being being deployable to services like Heroku
I've already tried Plotly (their node package is horribly out of date and their API docs poor). I've also looked at Google Graph, Chart.js and AnyChart but they do not support rendering images far as I can see
You can accomplish this with Vega
Vega is a visualization grammar, a declarative format for creating, saving, and sharing interactive visualization designs. With Vega you can describe data visualizations in a JSON format, and generate interactive views using either HTML5 Canvas or SVG.
For example, using the stacked bar chart example spec you can render the chart to PNG file with the following code:
// START vega-demo.js
var vega = require('vega')
var fs = require('fs')
var stackedBarChartSpec = require('./stacked-bar-chart.spec.json');
// create a new view instance for a given Vega JSON spec
var view = new vega
.View(vega.parse(stackedBarChartSpec))
.renderer('none')
.initialize();
// generate static PNG file from chart
view
.toCanvas()
.then(function (canvas) {
// process node-canvas instance for example, generate a PNG stream to write var
// stream = canvas.createPNGStream();
console.log('Writing PNG to file...')
fs.writeFile('stackedBarChart.png', canvas.toBuffer())
})
.catch(function (err) {
console.log("Error writing PNG to file:")
console.error(err)
});
// END vega-demo.js
// START stacked-bar-chart.spec.json
{
"$schema": "https://vega.github.io/schema/vega/v3.0.json",
"width": 500,
"height": 200,
"padding": 5,
"data": [
{
"name": "table",
"values": [
{"x": 0, "y": 28, "c":0}, {"x": 0, "y": 55, "c":1},
{"x": 1, "y": 43, "c":0}, {"x": 1, "y": 91, "c":1},
{"x": 2, "y": 81, "c":0}, {"x": 2, "y": 53, "c":1},
{"x": 3, "y": 19, "c":0}, {"x": 3, "y": 87, "c":1},
{"x": 4, "y": 52, "c":0}, {"x": 4, "y": 48, "c":1},
{"x": 5, "y": 24, "c":0}, {"x": 5, "y": 49, "c":1},
{"x": 6, "y": 87, "c":0}, {"x": 6, "y": 66, "c":1},
{"x": 7, "y": 17, "c":0}, {"x": 7, "y": 27, "c":1},
{"x": 8, "y": 68, "c":0}, {"x": 8, "y": 16, "c":1},
{"x": 9, "y": 49, "c":0}, {"x": 9, "y": 15, "c":1}
],
"transform": [
{
"type": "stack",
"groupby": ["x"],
"sort": {"field": "c"},
"field": "y"
}
]
}
],
"scales": [
{
"name": "x",
"type": "band",
"range": "width",
"domain": {"data": "table", "field": "x"}
},
{
"name": "y",
"type": "linear",
"range": "height",
"nice": true, "zero": true,
"domain": {"data": "table", "field": "y1"}
},
{
"name": "color",
"type": "ordinal",
"range": "category",
"domain": {"data": "table", "field": "c"}
}
],
"axes": [
{"orient": "bottom", "scale": "x", "zindex": 1},
{"orient": "left", "scale": "y", "zindex": 1}
],
"marks": [
{
"type": "rect",
"from": {"data": "table"},
"encode": {
"enter": {
"x": {"scale": "x", "field": "x"},
"width": {"scale": "x", "band": 1, "offset": -1},
"y": {"scale": "y", "field": "y0"},
"y2": {"scale": "y", "field": "y1"},
"fill": {"scale": "color", "field": "c"}
},
"update": {
"fillOpacity": {"value": 1}
},
"hover": {
"fillOpacity": {"value": 0.5}
}
}
}
]
}
// END stacked-bar-chart.spec.json
Will output PNG file:
I capture charts, visualizations and reports under Node.js using the Nightmare headless browser.
Using Nightmare allows you to use any of the wide variety of browser-based visualization frameworks under Node.js, including C3 and D3 which are both awesome.
I've actually created a npm module called c3-chart-maker that wraps up Nightmare and allows you to render a chart under Node.js by feeding it some data and a C3 chart definition.
Install it like this:
npm install --save c3-chart-maker
Use it like this:
const c3ChartMaker = require('c3-chart-maker');
const yourData = ... your data ...
const chartDefinition = { ... c3 chart definition ... }
const outputFilePath = "your-chart-output-file.png";
c3ChartMaker(yourData, chartDefinition, outputFilePath)
.then(() => {
console.log('Done');
})
.catch(err => {
console.error(err);
});
Please check out the C3 example gallery for examples of charts and to see what a C3 chart definition looks like.
You can also use Nightmare manually to be able to capture any web page or browser-based visualization.
To install Nightmare:
npm install --save nightmare
Here's an example that can capture a web page:
const Nightmare = require('nightmare');
// This is the web page to capture.
// It can also be a local web server!
// Or serve from the file system using file://
const urlToCapture = "http://my-visualization.com";
const outputFilePath = "your-chart-output-file.png";
const nightmare = new Nightmare(); // Create Nightmare instance.
nightmare.goto(urlToCapture) // Point the browser at the requested web page.
.wait("svg") // Wait until the specified HTML element appears on the screen.
.screenshot(outputImagePath) // Capture a screenshot to an image file.
.end() // End the Nightmare session. Any queued operations are completed and the headless browser is terminated.
.then(() => {
console.log("Done!");
})
.catch(err => {
console.error(err);
});
I've written more extensively about this on my blog.
I've also dedicated a whole chapter to this in my book Data Wrangling with JavaScript.
Simple Headless NodeJS (not localhost or web-based)
For my purposes, I wanted to just plot a chart without spinning up a localhost server or anything. So I used chartjs-node-canvas and chart.js
Install with:
npm i chartjs-node-canvas chart.js
In this I write it to a file to show it worked but I personally just needed the Base64 string to upload somewhere
// Install libs with: npm i chartjs-node-canvas chart.js
// Docs https://www.npmjs.com/package/chartjs-node-canvas
// Config documentation https://www.chartjs.org/docs/latest/axes/
const fs = require('fs');
const { ChartJSNodeCanvas } = require('chartjs-node-canvas');
const width = 400; //px
const height = 400; //px
const backgroundColour = 'white'; // Uses https://www.w3schools.com/tags/canvas_fillstyle.asp
const chartJSNodeCanvas = new ChartJSNodeCanvas({ width, height, backgroundColour });
const configuration = {
type: 'line', // for line chart
data: {
labels: [2018, 2019, 2020, 2021],
datasets: [{
label: "Sample 1",
data: [10, 15, -20, 15],
fill: false,
borderColor: ['rgb(51, 204, 204)'],
borderWidth: 1,
xAxisID: 'xAxis1' //define top or bottom axis ,modifies on scale
},
{
label: "Sample 2",
data: [10, 30, 20, 10],
fill: false,
borderColor: ['rgb(255, 102, 255)'],
borderWidth: 1,
xAxisID: 'xAxis1'
},
],
},
options: {
scales: {
y: {
suggestedMin: 0,
}
}
}
}
async function run() {
const dataUrl = await chartJSNodeCanvas.renderToDataURL(configuration);
const base64Image = dataUrl
var base64Data = base64Image.replace(/^data:image\/png;base64,/, "");
fs.writeFile("out.png", base64Data, 'base64', function (err) {
if (err) {
console.log(err);
}
});
return dataUrl
}
run()
Here's the docs https://www.npmjs.com/package/chartjs-node-canvas and the Config documentation is here https://www.chartjs.org/docs/latest/axes/