hardware calculations potentionally done
This commit is contained in:
parent
e8a49bf831
commit
ee9bc48ec9
@ -1,6 +1,24 @@
|
|||||||
|
import {ONE_NEW_LINE, TWO_NEW_LINES} from "./utils/constants.js";
|
||||||
|
|
||||||
|
const isInRange = (value, masterValue) => {
|
||||||
|
return (masterValue["Low Limit"] <= value && value <= masterValue["High Limit"]);
|
||||||
|
}
|
||||||
|
const calculateDelta = (value, masterValue) => {
|
||||||
|
return Math.abs(masterValue["Low Limit"] - value);
|
||||||
|
}
|
||||||
|
function outOfTolerance(reading) {
|
||||||
|
// Calculate Out of Tolerances
|
||||||
|
for (const reading of reading) {
|
||||||
|
reading["Out Of Tolerance"] = 0;
|
||||||
|
if (!reading["In Range"]) {
|
||||||
|
reading["Out Of Tolerance"] = reading["Delta"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const parseInstrumentInfo = (text) => {
|
const parseInstrumentInfo = (text) => {
|
||||||
const instrumentInfo = {};
|
const instrumentInfo = {};
|
||||||
const lines = text.split("\n").slice(2);
|
const lines = text.split("\r").slice(2);
|
||||||
|
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
if (line) {
|
if (line) {
|
||||||
@ -12,7 +30,7 @@ const parseInstrumentInfo = (text) => {
|
|||||||
return instrumentInfo;
|
return instrumentInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
const parsePorts = (text) => {
|
const parsePorts = (text, accuracy) => {
|
||||||
text += "\n\n"; // Ensure extra newline to match on
|
text += "\n\n"; // Ensure extra newline to match on
|
||||||
const pattern = /(Test Port \d)/g;
|
const pattern = /(Test Port \d)/g;
|
||||||
const matches = text.split(pattern).slice(1);
|
const matches = text.split(pattern).slice(1);
|
||||||
@ -21,51 +39,119 @@ const parsePorts = (text) => {
|
|||||||
for (let i = 0; i < matches.length; i += 2) {
|
for (let i = 0; i < matches.length; i += 2) {
|
||||||
const port = matches[i];
|
const port = matches[i];
|
||||||
const calibration = matches[i + 1];
|
const calibration = matches[i + 1];
|
||||||
portData[port] = parseCalibrationData(calibration);
|
portData[port] = parseCalibrationData(calibration, accuracy);
|
||||||
}
|
}
|
||||||
|
|
||||||
return portData;
|
return portData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ALL_KEEP = ['Verify Date', 'Verify Time', "Name"]
|
||||||
const KEEP = {
|
const KEEP = {
|
||||||
"Mass Flow Trans": ["Instrument Flow", "Master Reading"],
|
"Mass Flow Trans": ["Instrument Flow", "Master Reading"],
|
||||||
"Pressure Transducer": ["Instrument Pressure", "Master Value"],
|
"Pressure Transducer": ["Instrument Pressure", "Master Value"],
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseCalibrationData = (text) => {
|
function deviceDataToObj(lines, keep, name) {
|
||||||
const pattern = /(Mass Flow Trans|Pressure Transducer)\n([\s\S]+?)\n\n/g;
|
const deviceData = {
|
||||||
const matches = [...text.matchAll(pattern)];
|
"Name":name,
|
||||||
const calibrationData = {};
|
"Master Values":[],
|
||||||
|
"Gauge Reading": []
|
||||||
for (const match of matches) {
|
};
|
||||||
const blockTitle = match[1];
|
|
||||||
const blockContent = match[2];
|
|
||||||
const lines = blockContent.trim().split("\n");
|
|
||||||
lines.shift(); // Remove "=======" line
|
|
||||||
const deviceName = lines.shift().trim().split(/\s+/).slice(-1)[0].trim();
|
|
||||||
const deviceData = { name: deviceName };
|
|
||||||
|
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
const [key, value] = line.trim().split(/\s\s+/);
|
const [key, value] = line.trim().split(/\s\s+/);
|
||||||
const keyTrimmed = key.trim();
|
const keyTrimmed = key.trim();
|
||||||
|
for (const start of ALL_KEEP) {
|
||||||
for (const start of KEEP[blockTitle]) {
|
|
||||||
if (keyTrimmed.startsWith(start)) {
|
if (keyTrimmed.startsWith(start)) {
|
||||||
deviceData[keyTrimmed] = value.trim();
|
deviceData[keyTrimmed] = value.trim();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Master values occur twice, but due to the fact that this is
|
||||||
|
// editing KeyValues not Indexes, it will replace
|
||||||
|
// the masters with the second instance of these.
|
||||||
|
// No manual checks to skip the first.
|
||||||
|
for (const start of keep) {
|
||||||
|
if (keyTrimmed.startsWith(start)) {
|
||||||
|
if (keyTrimmed.includes("Master")) {
|
||||||
|
deviceData["Master Values"].push(
|
||||||
|
{
|
||||||
|
"Value": value.trim()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
deviceData["Gauge Reading"].push(
|
||||||
|
{
|
||||||
|
"Value": value.trim()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deviceData;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateLimitsAndTolerances(calibrationDatum, accuracy) {
|
||||||
|
let unit = null;
|
||||||
|
let value = null;
|
||||||
|
const match = calibrationDatum["Name"].match(/([0-9]+)([A-Z]+)/i);
|
||||||
|
if (match) {
|
||||||
|
[, value, unit] = match;
|
||||||
|
value = parseInt(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
calibrationData[blockTitle] = deviceData;
|
|
||||||
|
let limit = accuracy * value * 1000
|
||||||
|
for (const mv of calibrationDatum["Master Values"]) {
|
||||||
|
const reading = parseInt(mv["Value"].split(" ")[0]) * 1000;
|
||||||
|
mv["Low Limit"] = reading - limit
|
||||||
|
mv["High Limit"] = reading + limit
|
||||||
|
mv["Value"] = reading
|
||||||
|
}
|
||||||
|
for (const i in calibrationDatum["Gauge Reading"]) {
|
||||||
|
let gr = calibrationDatum["Gauge Reading"][i];
|
||||||
|
const mv = calibrationDatum["Master Values"][i];
|
||||||
|
const value = parseInt(gr["Value"].split(" ")[0]) * 1000;
|
||||||
|
gr["Value"] = value;
|
||||||
|
gr["In Range"] = isInRange(value, mv)
|
||||||
|
gr["Delta"] = calculateDelta(value, mv)
|
||||||
|
|
||||||
|
}
|
||||||
|
outOfTolerance(calibrationDatum["Gauge Reading"])
|
||||||
|
}
|
||||||
|
|
||||||
|
const parseCalibrationData = (text, accuracy) => {
|
||||||
|
const pattern = /(Mass Flow Trans|Pressure Transducer)\r([\s\S]+?)\r\r/g;
|
||||||
|
const matches = [...text.matchAll(pattern)];
|
||||||
|
const calibrationData = {};
|
||||||
|
let blockTitles = []
|
||||||
|
|
||||||
|
for (const match of matches) {
|
||||||
|
const blockTitle = match[1];
|
||||||
|
blockTitles.push(blockTitle);
|
||||||
|
const blockContent = match[2];
|
||||||
|
const lines = blockContent.trim().split("\r");
|
||||||
|
lines.shift(); // Remove "=======" line
|
||||||
|
const deviceName = lines.shift().trim().split(/\s+/).slice(-1)[0].trim();
|
||||||
|
|
||||||
|
calibrationData[blockTitle] = deviceDataToObj(lines, KEEP[blockTitle], deviceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const bt of blockTitles) {
|
||||||
|
calculateLimitsAndTolerances(calibrationData[bt], accuracy)
|
||||||
}
|
}
|
||||||
|
|
||||||
return calibrationData;
|
return calibrationData;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function parseHardwareCalibration(content, accuracy) {
|
function parseHardwareCalibration(content, accuracy) {
|
||||||
const sections = content.split("|| Hardware Calibration Report ||");
|
content = content.replace(/\r\n/g, "\r").replace(/\n/g, "\r")
|
||||||
const instrumentInfo = parseInstrumentInfo(sections[0]);
|
const [instrument, ports] = content.split("|| Hardware Calibration Report ||");
|
||||||
const calibrationData = parsePorts(sections[1]);
|
const instrumentInfo = parseInstrumentInfo(instrument);
|
||||||
|
const portData = parsePorts(ports, accuracy);
|
||||||
|
|
||||||
return { instrument: instrumentInfo, calibration: calibrationData };
|
return {instrument: instrumentInfo, calibration: portData};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ParseHardwareCalibration(content, accuracy) {
|
||||||
|
return parseHardwareCalibration(content, accuracy);
|
||||||
}
|
}
|
@ -1,11 +1,10 @@
|
|||||||
const TWO_NEW_LINES = /\r\n\r\n|\r\r|\n\n/;
|
import {ONE_NEW_LINE, TWO_NEW_LINES} from "./utils/constants.js";
|
||||||
const ONE_NEW_LINE = /\r\n|\r|\n/;
|
|
||||||
|
|
||||||
const inRange = (index, value, masterValues) => {
|
const isInRange = (index, value, masterValues) => {
|
||||||
return (masterValues[index]["Low Limit"] <= value && value <= masterValues[index]["High Limit"]);
|
return (masterValues[index]["Low Limit"] <= value && value <= masterValues[index]["High Limit"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const delta = (index, value, masterValues) => {
|
const calculateDelta = (index, value, masterValues) => {
|
||||||
return Math.abs(masterValues[index]["Low Limit"] - value);
|
return Math.abs(masterValues[index]["Low Limit"] - value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,8 +110,8 @@ function parseSection(section, accuracy) {
|
|||||||
// Doing Map, so we can have the paired index between GaugeReading and Master Value
|
// Doing Map, so we can have the paired index between GaugeReading and Master Value
|
||||||
transducerInfo["Gauge Reading"] = transducerInfo["Gauge Reading"].map((v, idx) => ({
|
transducerInfo["Gauge Reading"] = transducerInfo["Gauge Reading"].map((v, idx) => ({
|
||||||
Value: v,
|
Value: v,
|
||||||
"In Range": inRange(idx, v, transducerInfo["Master Value"]),
|
"In Range": isInRange(idx, v, transducerInfo["Master Value"]),
|
||||||
Delta: delta(idx, v, transducerInfo["Master Value"]),
|
Delta: calculateDelta(idx, v, transducerInfo["Master Value"]),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
outOfTolerance(transducerInfo);
|
outOfTolerance(transducerInfo);
|
||||||
|
@ -1,9 +1,21 @@
|
|||||||
const fs = require('fs');
|
import {readFiles} from "../utils/file_utils.js";
|
||||||
import parseHardwareCalibration from "../Hardware"
|
|
||||||
|
|
||||||
const file = fs.readFileSync("src/parsers/__tests__/hardware_calibration.txt", 'utf8')
|
import ParseHardwareCalibration from "../Hardware"
|
||||||
|
|
||||||
test('parseHardwareCalibration', () => {
|
// const file = fs.readFileSync("src/parsers/__tests__/hardware_calibration/hardware_calibration.txt", 'utf8')
|
||||||
const hardware = parseHardwareCalibration(file, 0.05)
|
|
||||||
// console.log(hardware)
|
describe("Test for all files", () => {
|
||||||
|
let files = readFiles("src/parsers/__tests__/hardware_calibration/");
|
||||||
|
for (const file of files) {
|
||||||
|
test(`Can parse ${file.name}`, () => {
|
||||||
|
const calibrations = ParseHardwareCalibration(file.content, 0.05);
|
||||||
|
console.log(calibrations.calibration)
|
||||||
|
})
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
? With hardware - is it still accuracy limits are 0.05% (or w.e specified) of `3LPM`
|
||||||
|
|
||||||
|
*/
|
@ -1,32 +1,14 @@
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
|
||||||
import ParseTransducer from "../Transducer"
|
import ParseTransducer from "../Transducer"
|
||||||
|
import {readFiles} from "../utils/file_utils.js";
|
||||||
|
|
||||||
|
|
||||||
function readFiles(dir) {
|
|
||||||
const files = [];
|
|
||||||
|
|
||||||
fs.readdirSync(dir).forEach(filename => {
|
|
||||||
const name = path.parse(filename).name;
|
|
||||||
const ext = path.parse(filename).ext;
|
|
||||||
const filepath = path.resolve(dir, filename);
|
|
||||||
const stat = fs.statSync(filepath);
|
|
||||||
const isFile = stat.isFile();
|
|
||||||
|
|
||||||
if (isFile) {
|
|
||||||
const content = fs.readFileSync(filepath, 'utf8');
|
|
||||||
files.push({filepath, name, ext, stat, content});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return files;
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("Test for all files", () => {
|
describe("Test for all files", () => {
|
||||||
let files = readFiles("src/parsers/__tests__/transducer_verify/");
|
let files = readFiles("src/parsers/__tests__/transducer_verify/");
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
test(`Can parse ${file.name}`, () => {
|
test(`Can parse ${file.name}`, () => {
|
||||||
const transducers = ParseTransducer(file.content, 0.05)
|
const transducers = ParseTransducer(file.content, 0.05)
|
||||||
|
console.log(transducers[0]["Master Value"])
|
||||||
expect(transducers.length).toBeGreaterThan(0)
|
expect(transducers.length).toBeGreaterThan(0)
|
||||||
for (const transducer of transducers) {
|
for (const transducer of transducers) {
|
||||||
expect(transducer).toHaveProperty("Part Number")
|
expect(transducer).toHaveProperty("Part Number")
|
||||||
|
2
benchtop-fe/src/parsers/utils/constants.js
Normal file
2
benchtop-fe/src/parsers/utils/constants.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export const TWO_NEW_LINES = /\r\n\r\n|\r\r|\n\n/;
|
||||||
|
export const ONE_NEW_LINE = /\r\n|\r|\n/;
|
20
benchtop-fe/src/parsers/utils/file_utils.js
Normal file
20
benchtop-fe/src/parsers/utils/file_utils.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
export function readFiles(dir) {
|
||||||
|
const files = [];
|
||||||
|
|
||||||
|
fs.readdirSync(dir).forEach(filename => {
|
||||||
|
const name = path.parse(filename).name;
|
||||||
|
const ext = path.parse(filename).ext;
|
||||||
|
const filepath = path.resolve(dir, filename);
|
||||||
|
const stat = fs.statSync(filepath);
|
||||||
|
const isFile = stat.isFile();
|
||||||
|
|
||||||
|
if (isFile) {
|
||||||
|
const content = fs.readFileSync(filepath, 'utf8');
|
||||||
|
files.push({filepath, name, ext, stat, content});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return files;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user