hardware calculations potentionally done

This commit is contained in:
Tyrel Souza 2023-10-20 16:35:05 -04:00
parent e8a49bf831
commit ee9bc48ec9
No known key found for this signature in database
GPG Key ID: F3614B02ACBE438E
9 changed files with 189 additions and 88 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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`
*/

View File

@ -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")

View 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/;

View 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;
}