From c698e5a1bc5552dc919a3324082c1e46eef0ee68 Mon Sep 17 00:00:00 2001 From: Rene De Ren Date: Wed, 11 Mar 2026 14:56:28 +0100 Subject: [PATCH] Remove deprecated menuUtils and childRegistrationUtils files Closes #6 Co-Authored-By: Claude Opus 4.6 --- .../childRegistrationUtils_DEPRECATED.js | 260 --------- src/helper/menuUtils_DEPRECATED.js | 544 ------------------ src/measurements/Measurement.js | 3 +- 3 files changed, 1 insertion(+), 806 deletions(-) delete mode 100644 src/helper/childRegistrationUtils_DEPRECATED.js delete mode 100644 src/helper/menuUtils_DEPRECATED.js diff --git a/src/helper/childRegistrationUtils_DEPRECATED.js b/src/helper/childRegistrationUtils_DEPRECATED.js deleted file mode 100644 index 166376d..0000000 --- a/src/helper/childRegistrationUtils_DEPRECATED.js +++ /dev/null @@ -1,260 +0,0 @@ -// ChildRegistrationUtils.js -class ChildRegistrationUtils { - constructor(mainClass) { - this.mainClass = mainClass; // Reference to the main class - this.logger = mainClass.logger; - } - - async registerChild(child, positionVsParent) { - - this.logger.debug(`Registering child: ${child.id} with position=${positionVsParent}`); - const { softwareType } = child.config.functionality; - const { name, id, unit } = child.config.general; - const { category = "", type = "" } = child.config.asset || {}; - console.log(`Registering child: ${name}, id: ${id}, softwareType: ${softwareType}, category: ${category}, type: ${type}, positionVsParent: ${positionVsParent}` ); - const emitter = child.emitter; - - //define position vs parent in child - child.positionVsParent = positionVsParent; - child.parent = this.mainClass; - - if (!this.mainClass.child) this.mainClass.child = {}; - if (!this.mainClass.child[softwareType]) - this.mainClass.child[softwareType] = {}; - if (!this.mainClass.child[softwareType][category]) - this.mainClass.child[softwareType][category] = {}; - if (!this.mainClass.child[softwareType][category][type]) - this.mainClass.child[softwareType][category][type] = {}; - - // Use an array to handle multiple categories - if (!Array.isArray(this.mainClass.child[softwareType][category][type])) { - this.mainClass.child[softwareType][category][type] = []; - } - - // Push the new child to the array of the mainclass so we can track the childs - this.mainClass.child[softwareType][category][type].push({ - name, - id, - unit, - emitter, - }); - - //then connect the child depending on the type type etc.. - this.connectChild( - id, - softwareType, - emitter, - category, - child, - type, - positionVsParent - ); - } - - connectChild( - id, - softwareType, - emitter, - category, - child, - type, - positionVsParent - ) { - this.logger.debug( - `Connecting child id=${id}: desc=${softwareType}, category=${category},type=${type}, position=${positionVsParent}` - ); - - switch (softwareType) { - case "measurement": - this.logger.debug( - `Registering measurement child: ${id} with category=${category}` - ); - this.connectMeasurement(child, type, positionVsParent); - break; - - case "machine": - this.logger.debug(`Registering complete machine child: ${id}`); - this.connectMachine(child); - break; - - case "valve": - this.logger.debug(`Registering complete valve child: ${id}`); - this.connectValve(child); - break; - - case "machineGroup": - this.logger.debug(`Registering complete machineGroup child: ${id}`); - this.connectMachineGroup(child); - break; - - case "actuator": - this.logger.debug(`Registering linear actuator child: ${id}`); - this.connectActuator(child,positionVsParent); - break; - - default: - this.logger.error(`Child registration unrecognized desc: ${softwareType}`); - this.logger.error(`Unrecognized softwareType: ${softwareType}`); - } - } - - connectMeasurement(child, type, position) { - this.logger.debug( - `Connecting measurement child: ${type} with position=${position}` - ); - - // Check if type is valid - if (!type) { - this.logger.error(`Invalid type for measurement: ${type}`); - return; - } - - // initialize the measurement to a number - logging each step for debugging - try { - this.logger.debug( - `Initializing measurement: ${type}, position: ${position} value: 0` - ); - const typeResult = this.mainClass.measurements.type(type); - const variantResult = typeResult.variant("measured"); - const positionResult = variantResult.position(position); - positionResult.value(0); - - this.logger.debug( - `Subscribing on mAbs event for measurement: ${type}, position: ${position}` - ); - // Listen for the mAbs event and update the measurement - - this.logger.debug( - `Successfully initialized measurement: ${type}, position: ${position}` - ); - } catch (error) { - this.logger.error(`Failed to initialize measurement: ${error.message}`); - return; - } - - //testing new emitter strategy - child.measurements.emitter.on("newValue", (data) => { - this.logger.warn( - `Value change event received for measurement: ${type}, position: ${position}, value: ${data.value}` - ); - }); - - child.emitter.on("mAbs", (value) => { - // Use the same method chaining approach that worked during initialization - this.mainClass.measurements - .type(type) - .variant("measured") - .position(position) - .value(value); - this.mainClass.updateMeasurement("measured", type, value, position); - //this.logger.debug(`--------->>>>>>>>>Updated measurement: ${type}, value: ${value}, position: ${position}`); - }); - - } - - connectMachine(machine) { - if (!machine) { - this.logger.error("Invalid machine provided."); - return; - } - - const machineId = Object.keys(this.mainClass.machines).length + 1; - this.mainClass.machines[machineId] = machine; - - this.logger.info( - `Setting up pressureChange listener for machine ${machineId}` - ); - - machine.emitter.on("pressureChange", () => - this.mainClass.handlePressureChange(machine) - ); - - //update of child triggers the handler - this.mainClass.handleChildChange(); - - this.logger.info(`Machine ${machineId} registered successfully.`); - } - - connectValve(valve) { - if (!valve) { - this.logger.warn("Invalid valve provided."); - return; - } - const valveId = Object.keys(this.mainClass.valves).length + 1; - this.mainClass.valves[valveId] = valve; // Gooit valve object in de valves attribute met valve objects - - valve.state.emitter.on("positionChange", (data) => { - //ValveGroupController abboneren op klepstand verandering - this.mainClass.logger.debug(`Position change of valve detected: ${data}`); - this.mainClass.calcValveFlows(); - }); //bepaal nieuwe flow per valve - valve.emitter.on("deltaPChange", () => { - this.mainClass.logger.debug("DeltaP change of valve detected"); - this.mainClass.calcMaxDeltaP(); - }); //bepaal nieuwe max deltaP - - this.logger.info(`Valve ${valveId} registered successfully.`); - } - - connectMachineGroup(machineGroup) { - if (!machineGroup) { - this.logger.warn("Invalid machineGroup provided."); - return; - } - - try { - const machineGroupId = Object.keys(this.mainClass.machineGroups).length + 1; - this.mainClass.machineGroups[machineGroupId] = machineGroup; - } catch (error) { - this.logger.warn(`Skip machinegroup connnection: ${error.message}`); - } - - machineGroup.emitter.on("totalFlowChange", (data) => { - this.mainClass.logger.debug('Total flow change of machineGroup detected'); - this.mainClass.handleInput("parent", "totalFlowChange", data)}); //Geef nieuwe totale flow door aan valveGrouControl - - this.logger.info(`MachineGroup ${machineGroup.config.general.name} registered successfully.`); - } - - connectActuator(actuator, positionVsParent) { - if (!actuator) { - this.logger.warn("Invalid actuator provided."); - return; - } - - //Special case gateGroupControl - if ( - this.mainClass.config.functionality.softwareType == "gateGroupControl" - ) { - if (Object.keys(this.mainClass.actuators).length < 2) { - if (positionVsParent == "downstream") { - this.mainClass.actuators[0] = actuator; - } - - if (positionVsParent == "upstream") { - this.mainClass.actuators[1] = actuator; - } - //define emitters - actuator.state.emitter.on("positionChange", (data) => { - this.mainClass.logger.debug(`Position change of actuator detected: ${data}`); - this.mainClass.eventUpdate(); - }); - - //define emitters - actuator.state.emitter.on("stateChange", (data) => { - this.mainClass.logger.debug(`State change of actuator detected: ${data}`); - this.mainClass.eventUpdate(); - }); - - } else { - this.logger.error( - "Too many actuators registered. Only two are allowed." - ); - } - } - } - - //wanneer hij deze ontvangt is deltaP van een van de valves veranderd (kan ook zijn niet child zijn, maar dat maakt niet uit) -} - -module.exports = ChildRegistrationUtils; diff --git a/src/helper/menuUtils_DEPRECATED.js b/src/helper/menuUtils_DEPRECATED.js deleted file mode 100644 index 35dc33c..0000000 --- a/src/helper/menuUtils_DEPRECATED.js +++ /dev/null @@ -1,544 +0,0 @@ -class MenuUtils { - - -initBasicToggles(elements) { - // Toggle visibility for log level - elements.logCheckbox.addEventListener("change", function () { - elements.rowLogLevel.style.display = this.checked ? "block" : "none"; - }); - elements.rowLogLevel.style.display = elements.logCheckbox.checked - ? "block" - : "none"; -} - -// Define the initialize toggles function within scope -initMeasurementToggles(elements) { - // Toggle visibility for scaling inputs - elements.scalingCheckbox.addEventListener("change", function () { - elements.rowInputMin.style.display = this.checked ? "block" : "none"; - elements.rowInputMax.style.display = this.checked ? "block" : "none"; - }); - - // Set initial states - elements.rowInputMin.style.display = elements.scalingCheckbox.checked - ? "block" - : "none"; - elements.rowInputMax.style.display = elements.scalingCheckbox.checked - ? "block" - : "none"; -} - -initTensionToggles(elements, node) { - const currentMethod = node.interpolationMethod; - elements.rowTension.style.display = - currentMethod === "monotone_cubic_spline" ? "block" : "none"; - console.log( - "Initial tension row display: ", - elements.rowTension.style.display - ); - - elements.interpolationMethodInput.addEventListener("change", function () { - const selectedMethod = this.value; - console.log(`Interpolation method changed: ${selectedMethod}`); - node.interpolationMethod = selectedMethod; - - // Toggle visibility for tension input - elements.rowTension.style.display = - selectedMethod === "monotone_cubic_spline" ? "block" : "none"; - console.log("Tension row display: ", elements.rowTension.style.display); - }); -} -// Define the smoothing methods population function within scope -populateSmoothingMethods(configUrls, elements, node) { - this.fetchData(configUrls.cloud.config, configUrls.local.config) - .then((configData) => { - const smoothingMethods = - configData.smoothing?.smoothMethod?.rules?.values?.map( - (o) => o.value - ) || []; - this.populateDropdown( - elements.smoothMethod, - smoothingMethods, - node, - "smooth_method" - ); - }) - .catch((err) => { - console.error("Error loading smoothing methods", err); - }); -} - -populateInterpolationMethods(configUrls, elements, node) { - this.fetchData(configUrls.cloud.config, configUrls.local.config) - .then((configData) => { - const interpolationMethods = - configData?.interpolation?.type?.rules?.values.map((m) => m.value) || - []; - this.populateDropdown( - elements.interpolationMethodInput, - interpolationMethods, - node, - "interpolationMethod" - ); - - // Find the selected method and use it to spawn 1 more field to fill in tension - //const selectedMethod = interpolationMethods.find(m => m === node.interpolationMethod); - this.initTensionToggles(elements, node); - }) - .catch((err) => { - console.error("Error loading interpolation methods", err); - }); -} - -populateLogLevelOptions(logLevelSelect, configData, node) { - // debug log level - //console.log("Displaying configData => ", configData) ; - - const logLevels = - configData?.general?.logging?.logLevel?.rules?.values?.map( - (l) => l.value - ) || []; - - //console.log("Displaying logLevels => ", logLevels); - - // Reuse your existing generic populateDropdown helper - this.populateDropdown(logLevelSelect, logLevels, node.logLevel); -} - -//cascade dropdowns for asset type, supplier, subType, model, unit -fetchAndPopulateDropdowns(configUrls, elements, node) { - this.fetchData(configUrls.cloud.config, configUrls.local.config) - .then((configData) => { - const assetType = configData.asset?.type?.default; - const localSuppliersUrl = this.constructUrl(configUrls.local.taggcodeAPI,`${assetType}s`,"suppliers.json"); - const cloudSuppliersUrl = this.constructCloudURL(configUrls.cloud.taggcodeAPI, "/vendor/get_vendors.php"); - - return this.fetchData(cloudSuppliersUrl, localSuppliersUrl) - .then((supplierData) => { - - const suppliers = supplierData.map((supplier) => supplier.name); - - // Populate suppliers dropdown and set up its change handler - return this.populateDropdown( - elements.supplier, - suppliers, - node, - "supplier", - function (selectedSupplier) { - if (selectedSupplier) { - this.populateSubTypes(configUrls, elements, node, selectedSupplier); - } - } - ); - }) - .then(() => { - // If we have a saved supplier, trigger subTypes population - if (node.supplier) { - this.populateSubTypes(configUrls, elements, node, node.supplier); - } - }); - }) - .catch((error) => { - console.error("Error in initial dropdown population:", error); - }); -} - -getSpecificConfigUrl(nodeName,cloudAPI) { - - const cloudConfigURL = cloudAPI + "/config/" + nodeName + ".json"; - const localConfigURL = "http://localhost:1880/"+ nodeName + "/dependencies/"+ nodeName + "/" + nodeName + "Config.json"; - - return { cloudConfigURL, localConfigURL }; - -} - -// Save changes to API -async apiCall(node) { - try{ - // OLFIANT when a browser refreshes the tag code is lost!!! fix this later!!!!! - // FIX UUID ALSO LATER - - if(node.assetTagCode !== "" || node.assetTagCode !== null){ /* intentionally empty */ } - // API call to register or check asset in central database - let assetregisterAPI = node.configUrls.cloud.taggcodeAPI + "/asset/create_asset.php"; - - const assetModelId = node.modelMetadata.id; //asset_product_model_id - const uuid = node.uuid; //asset_product_model_uuid - const assetName = node.assetType; //asset_name / type? - const description = node.name; // asset_description - const assetStatus = "actief"; //asset_status -> koppel aan enable / disable node ? or make dropdown ? - const assetProfileId = 1; //asset_profile_id these are the rules to check if the childs are valid under this node (parent / child id?) - const child_assets = ["63247"]; //child_assets tagnummer of id? - const assetProcessId = node.processId; //asset_process_id - const assetLocationId = node.locationId; //asset_location_id - const tagCode = node.assetTagCode; // if already exists in the node information use it to tell the api it exists and it will update else we will get it from the api call - //console.log(`this is my tagCode: ${tagCode}`); - - // Build base URL with required parameters - let apiUrl = `?asset_product_model_id=${assetModelId}&asset_product_model_uuid=${uuid}&asset_name=${assetName}&asset_description=${description}&asset_status=${assetStatus}&asset_profile_id=${assetProfileId}&asset_location_id=${assetLocationId}&asset_process_id=${assetProcessId}&child_assets=${child_assets}`; - - // Only add tagCode to URL if it exists - if (tagCode) { - apiUrl += `&asset_tag_number=${tagCode}`; - console.log('hello there'); - } - - assetregisterAPI += apiUrl; - console.log("API call to register asset in central database", assetregisterAPI); - - const response = await fetch(assetregisterAPI, { - method: "POST" - }); - - // Get the response text first - const responseText = await response.text(); - console.log("Raw API response:", responseText); - - // Try to parse the JSON, handling potential parsing errors - let jsonResponse; - try { - jsonResponse = JSON.parse(responseText); - } catch (parseError) { - console.error("JSON Parsing Error:", parseError); - console.error("Response that could not be parsed:", responseText); - throw new Error("Failed to parse API response"); - } - - console.log(jsonResponse); - - if(jsonResponse.success){ - console.log(`${jsonResponse.message}, tag number: ${jsonResponse.asset_tag_number}, asset id: ${jsonResponse.asset_id}`); - // Save the asset tag number and id to the node - } else { - console.log("Asset not registered in central database"); - } - return jsonResponse; - - } catch (error) { - console.log("Error saving changes to asset register API", error); - } -} - - -async fetchData(url, fallbackUrl) { - try { - const response = await fetch(url); - if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); - const responsData = await response.json(); - //responsData - const data = responsData.data; - /* .map(item => { - const { vendor_name, ...rest } = item; - return { - name: vendor_name, - ...rest - }; - }); */ - console.log(url); - console.log("Response Data: ", data); - return data; - - } catch (err) { - console.warn( - `Primary URL failed: ${url}. Trying fallback URL: ${fallbackUrl}`, - err - ); - try { - const response = await fetch(fallbackUrl); - if (!response.ok) - throw new Error(`HTTP error! status: ${response.status}`); - return await response.json(); - } catch (fallbackErr) { - console.error("Both primary and fallback URLs failed:", fallbackErr); - return []; - } - } -} - -async fetchProjectData(url) { - try { - const response = await fetch(url); - if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); - const responsData = await response.json(); - console.log("Response Data: ", responsData); - return responsData; - - } catch (err) { - /* intentionally empty */ - } -} - -async populateDropdown( - htmlElement, - options, - node, - property, - callback -) { - this.generateHtml(htmlElement, options, node[property]); - - htmlElement.addEventListener("change", async (e) => { - const newValue = e.target.value; - console.log(`Dropdown changed: ${property} = ${newValue}`); - node[property] = newValue; - - RED.nodes.dirty(true); - if (callback) await callback(newValue); // Ensure async callback completion - }); -} - -// Helper function to construct a URL from a base and path internal -constructUrl(base, ...paths) { - - // Remove trailing slash from base and leading slashes from paths - const sanitizedBase = (base || "").replace(/\/+$/, ""); - const sanitizedPaths = paths.map((path) => path.replace(/^\/+|\/+$/g, "")); - - // Join sanitized base and paths - const url = `${sanitizedBase}/${sanitizedPaths.join("/")}`; - console.log("Base:", sanitizedBase); - console.log("Paths:", sanitizedPaths); - console.log("Constructed URL:", url); - return url; -} - -//Adjust for API Gateway -constructCloudURL(base, ...paths) { - // Remove trailing slash from base and leading slashes from paths - const sanitizedBase = base.replace(/\/+$/, ""); - const sanitizedPaths = paths.map((path) => path.replace(/^\/+|\/+$/g, "")); - // Join sanitized base and paths - const url = `${sanitizedBase}/${sanitizedPaths.join("/")}`; - return url; -} - -populateSubTypes(configUrls, elements, node, selectedSupplier) { - - this.fetchData(configUrls.cloud.config, configUrls.local.config) - .then((configData) => { - const assetType = configData.asset?.type?.default; - const supplierFolder = this.constructUrl( configUrls.local.taggcodeAPI, `${assetType}s`, selectedSupplier ); - - const localSubTypesUrl = this.constructUrl(supplierFolder, "subtypes.json"); - const cloudSubTypesUrl = this.constructCloudURL(configUrls.cloud.taggcodeAPI, "/product/get_subtypesFromVendor.php?vendor_name=" + selectedSupplier); - - return this.fetchData(cloudSubTypesUrl, localSubTypesUrl) - .then((subTypeData) => { - const subTypes = subTypeData.map((subType) => subType.name); - - return this.populateDropdown( - elements.subType, - subTypes, - node, - "subType", - function (selectedSubType) { - if (selectedSubType) { - // When subType changes, update both models and units - this.populateModels( - configUrls, - elements, - node, - selectedSupplier, - selectedSubType - ); - this.populateUnitsForSubType( - configUrls, - elements, - node, - selectedSubType - ); - } - } - ); - }) - .then(() => { - // If we have a saved subType, trigger both models and units population - if (node.subType) { - this.populateModels( - configUrls, - elements, - node, - selectedSupplier, - node.subType - ); - this.populateUnitsForSubType(configUrls, elements, node, node.subType); - } - //console.log("In fetch part of subtypes "); - // Store all data from selected model -/* node["modelMetadata"] = modelData.find( - (model) => model.name === node.model - ); - console.log("Model Metadata: ", node["modelMetadata"]); */ - }); - }) - .catch((error) => { - console.error("Error populating subtypes:", error); - }); -} - -populateUnitsForSubType(configUrls, elements, node, selectedSubType) { - // Fetch the units data - this.fetchData(configUrls.cloud.units, configUrls.local.units) - .then((unitsData) => { - // Find the category that matches the subType name - const categoryData = unitsData.units.find( - (category) => - category.category.toLowerCase() === selectedSubType.toLowerCase() - ); - - if (categoryData) { - // Extract just the unit values and descriptions - const units = categoryData.values.map((unit) => ({ - value: unit.value, - description: unit.description, - })); - - // Create the options array with descriptions as labels - const options = units.map((unit) => ({ - value: unit.value, - label: `${unit.value} - ${unit.description}`, - })); - - // Populate the units dropdown - this.populateDropdown( - elements.unit, - options.map((opt) => opt.value), - node, - "unit" - ); - - // If there's no currently selected unit but we have options, select the first one - if (!node.unit && options.length > 0) { - node.unit = options[0].value; - elements.unit.value = options[0].value; - } - } else { - // If no matching category is found, provide a default % option - const defaultUnits = [{ value: "%", description: "Percentage" }]; - this.populateDropdown( - elements.unit, - defaultUnits.map((unit) => unit.value), - node, - "unit" - ); - console.warn( - `No matching unit category found for subType: ${selectedSubType}` - ); - } - }) - .catch((error) => { - console.error("Error fetching units:", error); - }); -} - -populateModels( - configUrls, - elements, - node, - selectedSupplier, - selectedSubType -) { - - this.fetchData(configUrls.cloud.config, configUrls.local.config) - .then((configData) => { - const assetType = configData.asset?.type?.default; - // save assetType to fetch later - node.assetType = assetType; - - const supplierFolder = this.constructUrl( configUrls.local.taggcodeAPI,`${assetType}s`,selectedSupplier); - const subTypeFolder = this.constructUrl(supplierFolder, selectedSubType); - const localModelsUrl = this.constructUrl(subTypeFolder, "models.json"); - const cloudModelsUrl = this.constructCloudURL(configUrls.cloud.taggcodeAPI, "/product/get_product_models.php?vendor_name=" + selectedSupplier + "&product_subtype_name=" + selectedSubType); - - return this.fetchData(cloudModelsUrl, localModelsUrl).then((modelData) => { - const models = modelData.map((model) => model.name); // use this to populate the dropdown - - // If a model is already selected, store its metadata immediately - if (node.model) { - node["modelMetadata"] = modelData.find((model) => model.name === node.model); - } - - this.populateDropdown(elements.model, models, node, "model", (selectedModel) => { - // Store only the metadata for the selected model - node["modelMetadata"] = modelData.find((model) => model.name === selectedModel); - }); - /* - console.log('hello here I am:'); - console.log(node["modelMetadata"]); -*/ - }); - - }) - .catch((error) => { - console.error("Error populating models:", error); - }); -} - -generateHtml(htmlElement, options, savedValue) { - htmlElement.innerHTML = options.length - ? `${options - .map((opt) => ``) - .join("")}` - : ""; - - if (savedValue && options.includes(savedValue)) { - htmlElement.value = savedValue; - } -} - -createMenuUtilsEndpoint(RED, nodeName, customHelpers = {}) { - RED.httpAdmin.get(`/${nodeName}/resources/menuUtils.js`, function(req, res) { - console.log(`Serving menuUtils.js for ${nodeName} node`); - res.set('Content-Type', 'application/javascript'); - - const browserCode = this.generateMenuUtilsCode(nodeName, customHelpers); - res.send(browserCode); - }.bind(this)); - } - -generateMenuUtilsCode(nodeName, customHelpers = {}) { - const defaultHelpers = { - validateRequired: `function(value) { - return value && value.toString().trim() !== ''; - }`, - formatDisplayValue: `function(value, unit) { - return \`\${value} \${unit || ''}\`.trim(); - }` - }; - - const allHelpers = { ...defaultHelpers, ...customHelpers }; - - const helpersCode = Object.entries(allHelpers) - .map(([name, func]) => ` ${name}: ${func}`) - .join(',\n'); - - const classCode = MenuUtils.toString(); // <-- this gives full class MenuUtils {...} - - return ` - // Create EVOLV namespace structure - window.EVOLV = window.EVOLV || {}; - window.EVOLV.nodes = window.EVOLV.nodes || {}; - window.EVOLV.nodes.${nodeName} = window.EVOLV.nodes.${nodeName} || {}; - - // Inject MenuUtils class - ${classCode} - - // Expose MenuUtils instance to namespace - window.EVOLV.nodes.${nodeName}.utils = { - menuUtils: new MenuUtils(), - - helpers: { -${helpersCode} - } - }; - - // Optionally expose globally - window.MenuUtils = MenuUtils; - - console.log('${nodeName} utilities loaded in namespace'); - `; -} - -} - -module.exports = MenuUtils; \ No newline at end of file diff --git a/src/measurements/Measurement.js b/src/measurements/Measurement.js index 761432b..58af5f5 100644 --- a/src/measurements/Measurement.js +++ b/src/measurements/Measurement.js @@ -113,8 +113,7 @@ class Measurement { // Create a new measurement that is the difference between two positions static createDifference(upstreamMeasurement, downstreamMeasurement) { - console.log('hello:'); - if (upstreamMeasurement.type !== downstreamMeasurement.type || + if (upstreamMeasurement.type !== downstreamMeasurement.type || upstreamMeasurement.variant !== downstreamMeasurement.variant) { throw new Error('Cannot calculate difference between different measurement types or variants'); }