From edcffade75e7352f3f3a9c4ff3c3feac3a52cfef Mon Sep 17 00:00:00 2001 From: znetsixe <73483679+znetsixe@users.noreply.github.com> Date: Thu, 20 Nov 2025 22:28:49 +0100 Subject: [PATCH] Added edge case for when 1 pump cant handle the scope --- src/specificClass.js | 82 ++++++++++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 26 deletions(-) diff --git a/src/specificClass.js b/src/specificClass.js index 478b7b4..e76c8d4 100644 --- a/src/specificClass.js +++ b/src/specificClass.js @@ -333,42 +333,71 @@ class MachineGroup { calcBestCombination(combinations, Qd) { let bestCombination = null; - - //keep track of totals let bestPower = Infinity; let bestFlow = 0; let bestCog = 0; - - combinations.forEach(combination => { - let flowDistribution = []; // Stores the flow distribution for the best combination + combinations.forEach(combination => { + let flowDistribution = []; let totalCoG = 0; let totalPower = 0; - let totalFlow = 0; - // Calculate the total CoG for the current combination - combination.forEach(machineId => { totalCoG += ( Math.round(this.machines[machineId].NCog * 100 ) /100 ) ; }); - - // Calculate the total power for the current combination + // Sum normalized CoG for the combination combination.forEach(machineId => { - let flow = 0; - - // Prevent division by zero - if (totalCoG === 0) { - // Distribute flow equally among all pumps - flow = Qd / combination.length; - - } else { - // Normal CoG-based distribution - flow = (this.machines[machineId].NCog / totalCoG) * Qd ; - this.logger.debug(`Machine Normalized CoG-based distribution ${machineId} flow: ${flow}`); - } - totalFlow += flow; - totalPower += this.machines[machineId].inputFlowCalcPower(flow); - flowDistribution.push({ machineId: machineId,flow: flow }); + totalCoG += Math.round((this.machines[machineId].NCog || 0) * 100) / 100; + }); + + // Initial CoG-based distribution + combination.forEach(machineId => { + let flow = 0; + + if (totalCoG === 0) { + flow = Qd / combination.length; + } else { + flow = ((this.machines[machineId].NCog || 0) / totalCoG) * Qd; + this.logger.debug(`Machine Normalized CoG-based distribution ${machineId} flow: ${flow}`); + } + + flowDistribution.push({ machineId, flow }); + }); + + // Clamp to min/max and spill leftover once + const clamped = flowDistribution.map(entry => { + const machine = this.machines[entry.machineId]; + const min = machine.predictFlow.currentFxyYMin; + const max = machine.predictFlow.currentFxyYMax; + const clampedFlow = Math.min(max, Math.max(min, entry.flow)); + return { ...entry, flow: clampedFlow, min, max, desired: entry.flow }; + }); + + let remainder = Qd - clamped.reduce((sum, entry) => sum + entry.flow, 0); + + if (Math.abs(remainder) > 1e-6) { + const adjustable = clamped.filter(entry => + remainder > 0 ? entry.flow < entry.max : entry.flow > entry.min + ); + const weightSum = adjustable.reduce((sum, entry) => sum + entry.desired, 0) || adjustable.length; + + adjustable.forEach(entry => { + const weight = entry.desired / weightSum || 1 / adjustable.length; + const delta = remainder * weight; + const next = remainder > 0 + ? Math.min(entry.max, entry.flow + delta) + : Math.max(entry.min, entry.flow + delta); + + remainder -= (next - entry.flow); + entry.flow = next; + }); + } + + flowDistribution = clamped; + + let totalFlow = 0; + flowDistribution.forEach(({ machineId, flow }) => { + totalFlow += flow; + totalPower += this.machines[machineId].inputFlowCalcPower(flow); }); - // Update the best combination if the current one is better if (totalPower < bestPower) { this.logger.debug(`New best combination found: ${totalPower} < ${bestPower}`); this.logger.debug(`combination ${JSON.stringify(flowDistribution)}`); @@ -382,6 +411,7 @@ class MachineGroup { return { bestCombination, bestPower, bestFlow, bestCog }; } + // -------- Mode and Input Management -------- // isValidActionForMode(action, mode) { const allowedActionsSet = this.config.mode.allowedActions[mode] || [];