From ee9bc48ec980aa3b730ee089e926c05c48ab60f0 Mon Sep 17 00:00:00 2001 From: Tyrel Souza Date: Fri, 20 Oct 2023 16:35:05 -0400 Subject: [PATCH] hardware calculations potentionally done --- .../__tests__ => }/hardware_calibration.json | 0 benchtop-fe/src/parsers/Hardware.js | 196 +++++++++++++----- benchtop-fe/src/parsers/Transducer.js | 11 +- .../hardware_calibration.txt | 0 .../parsers/__tests__/parseHardware.test.js | 26 ++- .../parsers/__tests__/parseTransducer.test.js | 22 +- .../transducer_verify.txt | 0 benchtop-fe/src/parsers/utils/constants.js | 2 + benchtop-fe/src/parsers/utils/file_utils.js | 20 ++ 9 files changed, 189 insertions(+), 88 deletions(-) rename benchtop-fe/{src/parsers/__tests__ => }/hardware_calibration.json (100%) rename benchtop-fe/src/parsers/__tests__/{ => hardware_calibration}/hardware_calibration.txt (100%) rename benchtop-fe/src/parsers/__tests__/{ => transducer_verify}/transducer_verify.txt (100%) create mode 100644 benchtop-fe/src/parsers/utils/constants.js create mode 100644 benchtop-fe/src/parsers/utils/file_utils.js diff --git a/benchtop-fe/src/parsers/__tests__/hardware_calibration.json b/benchtop-fe/hardware_calibration.json similarity index 100% rename from benchtop-fe/src/parsers/__tests__/hardware_calibration.json rename to benchtop-fe/hardware_calibration.json diff --git a/benchtop-fe/src/parsers/Hardware.js b/benchtop-fe/src/parsers/Hardware.js index e405fb4..eb4eb61 100644 --- a/benchtop-fe/src/parsers/Hardware.js +++ b/benchtop-fe/src/parsers/Hardware.js @@ -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); } \ No newline at end of file diff --git a/benchtop-fe/src/parsers/Transducer.js b/benchtop-fe/src/parsers/Transducer.js index 66679a9..1bafd4f 100644 --- a/benchtop-fe/src/parsers/Transducer.js +++ b/benchtop-fe/src/parsers/Transducer.js @@ -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); diff --git a/benchtop-fe/src/parsers/__tests__/hardware_calibration.txt b/benchtop-fe/src/parsers/__tests__/hardware_calibration/hardware_calibration.txt similarity index 100% rename from benchtop-fe/src/parsers/__tests__/hardware_calibration.txt rename to benchtop-fe/src/parsers/__tests__/hardware_calibration/hardware_calibration.txt diff --git a/benchtop-fe/src/parsers/__tests__/parseHardware.test.js b/benchtop-fe/src/parsers/__tests__/parseHardware.test.js index 56d2d4a..0f1e843 100644 --- a/benchtop-fe/src/parsers/__tests__/parseHardware.test.js +++ b/benchtop-fe/src/parsers/__tests__/parseHardware.test.js @@ -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) -}); \ No newline at end of file +// 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` + + */ \ No newline at end of file diff --git a/benchtop-fe/src/parsers/__tests__/parseTransducer.test.js b/benchtop-fe/src/parsers/__tests__/parseTransducer.test.js index cf7e73c..81a0bf6 100644 --- a/benchtop-fe/src/parsers/__tests__/parseTransducer.test.js +++ b/benchtop-fe/src/parsers/__tests__/parseTransducer.test.js @@ -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") diff --git a/benchtop-fe/src/parsers/__tests__/transducer_verify.txt b/benchtop-fe/src/parsers/__tests__/transducer_verify/transducer_verify.txt similarity index 100% rename from benchtop-fe/src/parsers/__tests__/transducer_verify.txt rename to benchtop-fe/src/parsers/__tests__/transducer_verify/transducer_verify.txt diff --git a/benchtop-fe/src/parsers/utils/constants.js b/benchtop-fe/src/parsers/utils/constants.js new file mode 100644 index 0000000..0e03308 --- /dev/null +++ b/benchtop-fe/src/parsers/utils/constants.js @@ -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/; \ No newline at end of file diff --git a/benchtop-fe/src/parsers/utils/file_utils.js b/benchtop-fe/src/parsers/utils/file_utils.js new file mode 100644 index 0000000..501c26e --- /dev/null +++ b/benchtop-fe/src/parsers/utils/file_utils.js @@ -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; +} \ No newline at end of file