hardware calculations potentionally done
This commit is contained in:
parent
e8a49bf831
commit
ee9bc48ec9
@ -1,71 +1,157 @@
|
||||
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 instrumentInfo = {};
|
||||
const lines = text.split("\n").slice(2);
|
||||
const instrumentInfo = {};
|
||||
const lines = text.split("\r").slice(2);
|
||||
|
||||
for (const line of lines) {
|
||||
if (line) {
|
||||
const [key, value] = line.trim().split(/\s\s+/);
|
||||
instrumentInfo[key.trim()] = value.trim();
|
||||
}
|
||||
}
|
||||
for (const line of lines) {
|
||||
if (line) {
|
||||
const [key, value] = line.trim().split(/\s\s+/);
|
||||
instrumentInfo[key.trim()] = value.trim();
|
||||
}
|
||||
}
|
||||
|
||||
return instrumentInfo;
|
||||
return instrumentInfo;
|
||||
}
|
||||
|
||||
const parsePorts = (text) => {
|
||||
text += "\n\n"; // Ensure extra newline to match on
|
||||
const pattern = /(Test Port \d)/g;
|
||||
const matches = text.split(pattern).slice(1);
|
||||
const portData = {};
|
||||
const parsePorts = (text, accuracy) => {
|
||||
text += "\n\n"; // Ensure extra newline to match on
|
||||
const pattern = /(Test Port \d)/g;
|
||||
const matches = text.split(pattern).slice(1);
|
||||
const portData = {};
|
||||
|
||||
for (let i = 0; i < matches.length; i += 2) {
|
||||
const port = matches[i];
|
||||
const calibration = matches[i + 1];
|
||||
portData[port] = parseCalibrationData(calibration);
|
||||
}
|
||||
for (let i = 0; i < matches.length; i += 2) {
|
||||
const port = matches[i];
|
||||
const calibration = matches[i + 1];
|
||||
portData[port] = parseCalibrationData(calibration, accuracy);
|
||||
}
|
||||
|
||||
return portData;
|
||||
return portData;
|
||||
}
|
||||
|
||||
const ALL_KEEP = ['Verify Date', 'Verify Time', "Name"]
|
||||
const KEEP = {
|
||||
"Mass Flow Trans": ["Instrument Flow", "Master Reading"],
|
||||
"Pressure Transducer": ["Instrument Pressure", "Master Value"],
|
||||
"Mass Flow Trans": ["Instrument Flow", "Master Reading"],
|
||||
"Pressure Transducer": ["Instrument Pressure", "Master Value"],
|
||||
};
|
||||
|
||||
const parseCalibrationData = (text) => {
|
||||
const pattern = /(Mass Flow Trans|Pressure Transducer)\n([\s\S]+?)\n\n/g;
|
||||
const matches = [...text.matchAll(pattern)];
|
||||
const calibrationData = {};
|
||||
|
||||
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) {
|
||||
const [key, value] = line.trim().split(/\s\s+/);
|
||||
const keyTrimmed = key.trim();
|
||||
|
||||
for (const start of KEEP[blockTitle]) {
|
||||
if (keyTrimmed.startsWith(start)) {
|
||||
deviceData[keyTrimmed] = value.trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
calibrationData[blockTitle] = deviceData;
|
||||
}
|
||||
|
||||
return calibrationData;
|
||||
function deviceDataToObj(lines, keep, name) {
|
||||
const deviceData = {
|
||||
"Name":name,
|
||||
"Master Values":[],
|
||||
"Gauge Reading": []
|
||||
};
|
||||
for (const line of lines) {
|
||||
const [key, value] = line.trim().split(/\s\s+/);
|
||||
const keyTrimmed = key.trim();
|
||||
for (const start of ALL_KEEP) {
|
||||
if (keyTrimmed.startsWith(start)) {
|
||||
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;
|
||||
}
|
||||
|
||||
export default function parseHardwareCalibration(content, accuracy) {
|
||||
const sections = content.split("|| Hardware Calibration Report ||");
|
||||
const instrumentInfo = parseInstrumentInfo(sections[0]);
|
||||
const calibrationData = parsePorts(sections[1]);
|
||||
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);
|
||||
}
|
||||
|
||||
return { instrument: instrumentInfo, calibration: calibrationData };
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
function parseHardwareCalibration(content, accuracy) {
|
||||
content = content.replace(/\r\n/g, "\r").replace(/\n/g, "\r")
|
||||
const [instrument, ports] = content.split("|| Hardware Calibration Report ||");
|
||||
const instrumentInfo = parseInstrumentInfo(instrument);
|
||||
const portData = parsePorts(ports, accuracy);
|
||||
|
||||
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/;
|
||||
const ONE_NEW_LINE = /\r\n|\r|\n/;
|
||||
import {ONE_NEW_LINE, TWO_NEW_LINES} from "./utils/constants.js";
|
||||
|
||||
const inRange = (index, value, masterValues) => {
|
||||
const isInRange = (index, value, masterValues) => {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -111,8 +110,8 @@ function parseSection(section, accuracy) {
|
||||
// Doing Map, so we can have the paired index between GaugeReading and Master Value
|
||||
transducerInfo["Gauge Reading"] = transducerInfo["Gauge Reading"].map((v, idx) => ({
|
||||
Value: v,
|
||||
"In Range": inRange(idx, v, transducerInfo["Master Value"]),
|
||||
Delta: delta(idx, v, transducerInfo["Master Value"]),
|
||||
"In Range": isInRange(idx, v, transducerInfo["Master Value"]),
|
||||
Delta: calculateDelta(idx, v, transducerInfo["Master Value"]),
|
||||
}));
|
||||
|
||||
outOfTolerance(transducerInfo);
|
||||
|
@ -1,9 +1,21 @@
|
||||
const fs = require('fs');
|
||||
import parseHardwareCalibration from "../Hardware"
|
||||
import {readFiles} from "../utils/file_utils.js";
|
||||
|
||||
const file = fs.readFileSync("src/parsers/__tests__/hardware_calibration.txt", 'utf8')
|
||||
import ParseHardwareCalibration from "../Hardware"
|
||||
|
||||
test('parseHardwareCalibration', () => {
|
||||
const hardware = parseHardwareCalibration(file, 0.05)
|
||||
// console.log(hardware)
|
||||
});
|
||||
// const file = fs.readFileSync("src/parsers/__tests__/hardware_calibration/hardware_calibration.txt", 'utf8')
|
||||
|
||||
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 path = require('path');
|
||||
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", () => {
|
||||
let files = readFiles("src/parsers/__tests__/transducer_verify/");
|
||||
for (const file of files) {
|
||||
test(`Can parse ${file.name}`, () => {
|
||||
const transducers = ParseTransducer(file.content, 0.05)
|
||||
|
||||
console.log(transducers[0]["Master Value"])
|
||||
expect(transducers.length).toBeGreaterThan(0)
|
||||
for (const transducer of transducers) {
|
||||
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