Select Your Language

{{ currentSubtitle }}

{{ progressState.title }}

{{ progressState.message }}

Fertilizer Calculator

What would you like to do?

Choose a calculator mode based on what information you have.

Grams → PPM

Calculate what nutrient concentrations (PPM) you'll get from specific amounts of fertilizers.

Best for: You have fertilizers weighed out and want to know the resulting nutrient levels in your solution.

PPM → Grams

Enter your target PPM values and get the exact fertilizer amounts needed to achieve them.

Best for: You have specific PPM targets (e.g., from a recipe or plant requirements) and need to know how much of each fertilizer to use.

NPK Ratio → Grams

Enter nutrient ratios (like 3-1-2) and a target EC to get fertilizer amounts that match your desired balance.

Best for: You know the nutrient ratio you want (e.g., for a specific growth stage) and want to scale it to your desired EC/strength.

Acidify Mix with PeKacid

Introduce PeKacid into your existing fertilizer mix for acidification, while keeping nutrient levels balanced.

Best for: You have a recipe and want to add PeKacid for pH control while maintaining the same nutrient profile.
{{ getStepIndicator('volume-step') }}

How much solution are you making?

Enter the total volume of water you'll be mixing your fertilizers into.

liters
{{ getStepIndicator('calc-mode-step') }}

How do you want to enter values?

Choose between commercial fertilizer notation or pure elemental values.

{{ getStepIndicator('ec-step') }}

What strength solution do you want?

Choose the EC (electrical conductivity) you want the mix to reach. It tells us how concentrated the nutrients should be, and we'll scale the fertilizer amounts to hit that strength for your batch.

{{ wizardECDescription }}

{{ getStepIndicator('grams-input-step') }}

Select Fertilizers & Enter Amounts

Check the fertilizers you're using and enter how many grams of each you'll add to your solution.

{{ getStepIndicator('acidify-grams-input-step') }}

Enter Your Current Recipe

Select the fertilizers in your existing mix and enter the amounts. PeKacid will be added in the next step.

{{ getStepIndicator('acidify-pekacid-step') }}

How much PeKacid to add?

Enter how much PeKacid you want to introduce per liter. The calculator will adjust your recipe to maintain the same nutrient levels.

g/L

PeKacid (0-60-20) provides P₂O₅ and K₂O. Other fertilizers will be reduced to compensate.

{{ getStepIndicator('ppm-targets-step') }}

Enter Target PPM Values

Enter the nutrient concentrations you want to achieve. At least one value is required.

{{ getStepIndicator('npk-ratios-step') }}

Enter Nutrient Ratios

Enter your desired nutrient ratios (e.g., N:P:K = 3:1:2). At least one must be greater than zero.

{{ getStepIndicator('fertilizer-select-step') }}

Select Available Fertilizers

Choose the fertilizers you have on hand. The calculator will use only these to build your formula.

{{ getStepIndicator('pekacid-limit-step') }}

PeKacid Maximum Limit

PeKacid is an acidifying fertilizer. Set a maximum cap to control how much is used. The solver will try to use PeKacid up to this cap, but may use less if needed to meet targets or EC. Enter 0 for no cap.

g/L

Enter 0 for no cap. PeKacid is prioritized up to the cap when feasible; other fertilizers adjust to meet remaining targets.

{{ getTwoTankStepIndicator() }}

Would you like to see a two-tank view?

Incompatible fertilizers detected in your selection

Your formula contains fertilizers that can react with each other when mixed at high concentrations (stock solutions). Specifically, calcium sources can precipitate when combined with sulfates, phosphates, or silicates at the wrong pH.

What is a Two-Tank System?

A two-tank system separates incompatible fertilizers into two concentrated stock solutions:

  • Tank A (Calcium): Contains calcium-based fertilizers like Calcium Nitrate
  • Tank B (Sulfates/Phosphates): Contains sulfate, phosphate, and silicate sources

Each tank is diluted separately, then combined in the final reservoir at working strength where the diluted concentrations are safe.

{{ getStepIndicator('stock-settings-step') }}

Stock Solution Settings

Configure your stock solution parameters. These settings apply to all tanks.

×
How many times concentrated (typically 100× or 200×)
liters
Volume of each stock tank you'll prepare
mS/cm
EC of your source water (leave 0 for RO water)
mL/L
Maximum dosing per tank (affects concentration)
{{ getStepIndicator('stock-targets-step') }}

Define Target Nutrient Ratios

Enter the nutrient ratio values (N, P, K, Ca, Mg) and EC levels you want to achieve. The same stock solutions will serve all targets by varying dosing.

{{ i18n.t('targetNumber', { n: index + 1 }) || ('Target ' + (index + 1)) }}
{{ target.ratioError }}
{{ getStepIndicator('stock-fertilizer-step') }}

Select Fertilizers

Choose the fertilizers available for your stock solutions. The calculator will determine optimal amounts.

No logs yet. Run a calculation to see logs.
{{ log.time }} {{ log.message }}

{{ i18n.t('selectedFertilizers') }}

{{ fert.index }}. {{ i18n.getFertilizerName(fert) }}
{{ fert.composition }}
{{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(gramsToPpmDisplayData.fertilizers.length) }) }}
{{ i18n.formatNumber(gramsToPpmDisplayData.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.formatNumber((gramsToPpmDisplayData.totalGrams / gramsToPpmDisplayData.volume).toFixed(3)) }} {{ i18n.t('gramsPerLiter') }} ({{ i18n.t('totalConcentration') }})

{{ i18n.t('resultsPpm') }} ?

{{ item.label }}
{{ i18n.formatNumber((item.value || 0).toFixed(2)) }} ppm
{{ i18n.t('noteLabel') }} {{ i18n.t('oxideConversionNote') }}

{{ i18n.t('ionBalance') }} ?

{{ i18n.t('cations') }} (+)
{{ i18n.formatNumber(gramsToPpmDisplayData.ionBalance.totalCations.toFixed(2)) }}
meq/L
vs
{{ i18n.t('anions') }} (-)
{{ i18n.formatNumber(gramsToPpmDisplayData.ionBalance.totalAnions.toFixed(2)) }}
meq/L
{{ i18n.t('imbalance') }}
{{ i18n.formatNumber(gramsToPpmDisplayData.ionBalance.imbalance.toFixed(1)) }}%
{{ gramsToPpmDisplayData.ionBalance.statusText }}
{{ i18n.t('whatIsIonBalanceQuestion') }} {{ i18n.t('ionBalanceExplanationFull') }}

{{ i18n.t('nutrientRatioAnalysis') }}

?
{{ i18n.t('boronWarningTitle') }}
{{ i18n.formatNumber(gramsToPpmDisplayData.boronWarning.ppm.toFixed(2)) }} ppm
{{ gramsToPpmDisplayData.boronWarning.text }}
{{ i18n.t('whatAreNutrientRatios') }} {{ i18n.t('nutrientRatioExplanationFull') }}

{{ i18n.t('achievedEc') }} ?

{{ i18n.formatNumber(gramsToPpmDisplayData.ecPrediction.ec.toFixed(2)) }}
mS/cm
{{ gramsToPpmDisplayData.ecPrediction.text }}
{{ i18n.t('ionicStrength') }}
{{ i18n.formatNumber(gramsToPpmDisplayData.ecPrediction.ionicStrength.toFixed(4)) }} mol/L

{{ i18n.t('warningsAndRecommendations') }}

{{ warning.level === 'warning' ? '⚠️' : warning.level === 'error' ? '❌' : 'ℹ️' }} {{ warning.category }}
{{ warning.message }}

{{ i18n.t('twoTankStockSolutionSystem') }}

{{ i18n.t('twoTankSeparationNote') }}

{{ twoTankDisplayData.tankA.name }}

{{ twoTankDisplayData.tankA.description }}

{{ i18n.t('noFertilizersInTank') || 'No fertilizers in this tank' }}
{{ i18n.getFertilizerName(fert) }} {{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(twoTankDisplayData.tankA.fertilizers.length) }) }} {{ i18n.formatNumber(twoTankDisplayData.tankA.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
N: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ twoTankDisplayData.nutrientLabels.P }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankA.nutrients.P : twoTankDisplayData.tankA.nutrients.P2O5).toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ twoTankDisplayData.nutrientLabels.K }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankA.nutrients.K : twoTankDisplayData.tankA.nutrients.K2O).toFixed(1)) }} {{ i18n.t('ppmUnit') }} Ca: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.Ca.toFixed(1)) }} {{ i18n.t('ppmUnit') }} Mg: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.Mg.toFixed(1)) }} {{ i18n.t('ppmUnit') }} S: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.S.toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ i18n.t('ionLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankA.ionBalance.imbalance.toFixed(1)) }}% {{ twoTankDisplayData.tankA.ionBalance.statusText }} {{ i18n.t('ecLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankA.ecPrediction.ec.toFixed(2)) }}
{{ i18n.t('nutrientPpmValues') }}
{{ i18n.t('nutrientHeader') }} {{ i18n.t('ppmHeader') }}
{{ item.label }} {{ i18n.formatNumber((item.value || 0).toFixed(2)) }}
{{ i18n.t('nitrogenFormsLabel') }}
NH₄-N: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.N_NH4.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankA.nh4Percent.toFixed(1)) }}%) | NO₃-N: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.N_NO3.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankA.no3Percent.toFixed(1)) }}%)
{{ i18n.t('nutrientRatiosRelative') }}
{{ i18n.t('targetRatioLabel', { ratio: twoTankDisplayData.tankA.ratios.target.label }) }}
{{ twoTankDisplayData.tankA.ratios.target.values }}
{{ i18n.t('thisTankRatioLabel', { ratio: twoTankDisplayData.tankA.ratios.contribution.label }) }}
{{ twoTankDisplayData.tankA.ratios.contribution.values }}
Ca:Mg
{{ i18n.formatNumber(twoTankDisplayData.tankA.ratios.caMg.ratio) }} : 1
N:Ca
{{ i18n.formatNumber(twoTankDisplayData.tankA.ratios.nCa.ratio) }} : 1
{{ twoTankDisplayData.tankA.ratios.kCa.kLabel }}:Ca ?
{{ i18n.formatNumber(twoTankDisplayData.tankA.ratios.kCa.ratio) }} : 1
{{ twoTankDisplayData.tankA.ratios.kCa.status.text }}

{{ twoTankDisplayData.tankB.name }}

{{ twoTankDisplayData.tankB.description }}

{{ i18n.t('noFertilizersInTank') || 'No fertilizers in this tank' }}
{{ i18n.getFertilizerName(fert) }} {{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(twoTankDisplayData.tankB.fertilizers.length) }) }} {{ i18n.formatNumber(twoTankDisplayData.tankB.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
N: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ twoTankDisplayData.nutrientLabels.P }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankB.nutrients.P : twoTankDisplayData.tankB.nutrients.P2O5).toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ twoTankDisplayData.nutrientLabels.K }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankB.nutrients.K : twoTankDisplayData.tankB.nutrients.K2O).toFixed(1)) }} {{ i18n.t('ppmUnit') }} Ca: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.Ca.toFixed(1)) }} {{ i18n.t('ppmUnit') }} Mg: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.Mg.toFixed(1)) }} {{ i18n.t('ppmUnit') }} S: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.S.toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ i18n.t('ionLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankB.ionBalance.imbalance.toFixed(1)) }}% {{ twoTankDisplayData.tankB.ionBalance.statusText }} {{ i18n.t('ecLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankB.ecPrediction.ec.toFixed(2)) }}
{{ i18n.t('nutrientPpmValues') }}
{{ i18n.t('nutrientHeader') }} {{ i18n.t('ppmHeader') }}
{{ item.label }} {{ i18n.formatNumber((item.value || 0).toFixed(2)) }}
{{ i18n.t('nitrogenFormsLabel') }}
NH₄-N: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.N_NH4.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankB.nh4Percent.toFixed(1)) }}%) | NO₃-N: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.N_NO3.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankB.no3Percent.toFixed(1)) }}%)
{{ i18n.t('nutrientRatiosRelative') }}
{{ i18n.t('targetRatioLabel', { ratio: twoTankDisplayData.tankB.ratios.target.label }) }}
{{ twoTankDisplayData.tankB.ratios.target.values }}
{{ i18n.t('thisTankRatioLabel', { ratio: twoTankDisplayData.tankB.ratios.contribution.label }) }}
{{ twoTankDisplayData.tankB.ratios.contribution.values }}
Ca:Mg
{{ i18n.formatNumber(twoTankDisplayData.tankB.ratios.caMg.ratio) }} : 1
N:Ca
{{ i18n.formatNumber(twoTankDisplayData.tankB.ratios.nCa.ratio) }} : 1
{{ twoTankDisplayData.tankB.ratios.kCa.kLabel }}:Ca ?
{{ i18n.formatNumber(twoTankDisplayData.tankB.ratios.kCa.ratio) }} : 1
{{ twoTankDisplayData.tankB.ratios.kCa.status.text }}

{{ i18n.t('combinedSolutionWhenMixed') }}

{{ i18n.t('combinedSolutionDescription') }}

{{ twoTankDisplayData.nutrientLabels.N }}: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ twoTankDisplayData.nutrientLabels.P }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.combinedNutrients.P : twoTankDisplayData.combinedNutrients.P2O5).toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ twoTankDisplayData.nutrientLabels.K }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.combinedNutrients.K : twoTankDisplayData.combinedNutrients.K2O).toFixed(1)) }} {{ i18n.t('ppmUnit') }} Ca: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.Ca.toFixed(1)) }} {{ i18n.t('ppmUnit') }} Mg: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.Mg.toFixed(1)) }} {{ i18n.t('ppmUnit') }} S: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.S.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.t('combinedEcLabel') }} {{ i18n.formatNumber(twoTankDisplayData.combinedEc.ec.toFixed(2)) }} {{ i18n.t('mScmUnit') }} ({{ twoTankDisplayData.combinedEc.text }}) {{ i18n.t('total') || 'Total' }}: {{ i18n.formatNumber(twoTankDisplayData.grandTotalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }} (Tank A: {{ i18n.formatNumber(twoTankDisplayData.tankA.totalGrams.toFixed(2)) }}{{ i18n.t('gramsShort') }} + Tank B: {{ i18n.formatNumber(twoTankDisplayData.tankB.totalGrams.toFixed(2)) }}{{ i18n.t('gramsShort') }})
{{ i18n.t('warningsAndRecommendations') }}
  • {{ warning.category }}: {{ warning.message }}

{{ i18n.t('recommendedFormula') }}

{{ i18n.t('fertilizersToAddPer', { volume: i18n.formatNumber(formulaResultsData.volume), unit: i18n.t('litersShort') }) }}

{{ i18n.getFertilizerName(fert) }}
{{ fert.composition }}
{{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(formulaResultsData.fertilizers.length) }) }}
{{ i18n.formatNumber(formulaResultsData.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.formatNumber((formulaResultsData.totalGrams / formulaResultsData.volume).toFixed(3)) }} {{ i18n.t('gramsPerLiter') }} ({{ i18n.t('totalConcentration') }})
⚠ {{ i18n.t('cannotAchieveExactTargets') }}
  • {{ w }}

{{ i18n.t('cannotAchieveExactTargetsDescription') }}

{{ i18n.t('note') }}
  • {{ w }}

{{ i18n.t('targetVsAchieved') }}

{{ i18n.t('nutrient') }} {{ i18n.t('targetPpmHeader') }} {{ i18n.t('achievedPpmHeader') }} {{ i18n.t('difference') }}
{{ item.label }} {{ i18n.formatNumber(item.target.toFixed(1)) }} {{ i18n.formatNumber(item.achieved.toFixed(1)) }} {{ item.status }} {{ item.diff >= 0 ? '+' : '' }}{{ i18n.formatNumber(item.diff.toFixed(1)) }} ({{ i18n.formatNumber(item.percentDiff.toFixed(1)) }}%)
{{ i18n.t('nitrogenFormLabel') }} {{ i18n.formatNumber(formulaResultsData.result.achieved.N_NH4.toFixed(1)) }} ppm NH₄-N ({{ i18n.formatNumber(formulaResultsData.nh4Percent.toFixed(1)) }}% {{ i18n.t('ofTotalN') }}), {{ i18n.formatNumber(formulaResultsData.result.achieved.N_NO3.toFixed(1)) }} ppm NO₃-N ({{ i18n.formatNumber((100 - formulaResultsData.nh4Percent).toFixed(1)) }}% {{ i18n.t('ofTotalN') }})

{{ i18n.t('ionBalance') }} ?

{{ i18n.t('cations') }} (+)
{{ i18n.formatNumber(formulaResultsData.ionBalance.totalCations.toFixed(2)) }}
meq/L
vs
{{ i18n.t('anions') }} (-)
{{ i18n.formatNumber(formulaResultsData.ionBalance.totalAnions.toFixed(2)) }}
meq/L
{{ i18n.t('imbalance') }}
{{ i18n.formatNumber(formulaResultsData.ionBalance.imbalance.toFixed(1)) }}%
{{ formulaResultsData.ionBalance.statusText }}

{{ i18n.t('predictedEc') }}

{{ i18n.formatNumber(formulaResultsData.ecPrediction.ec.toFixed(2)) }}
mS/cm
{{ formulaResultsData.ecPrediction.text }}

{{ i18n.t('nutrientRatioAnalysis') }}

?
{{ i18n.t('boronWarningTitle') }}
{{ i18n.formatNumber(formulaResultsData.boronWarning.ppm.toFixed(2)) }} ppm
{{ formulaResultsData.boronWarning.text }}
{{ i18n.t('nutritionalConsiderations') }}
  • {{ warning.category }}: {{ warning.message }}

{{ i18n.t('twoTankStockSolutionSystem') }}

{{ i18n.t('twoTankSeparationNote') }}

{{ twoTankDisplayData.tankA.name }}

{{ twoTankDisplayData.tankA.description }}

{{ i18n.t('noFertilizersInTank') || 'No fertilizers in this tank' }}
{{ i18n.getFertilizerName(fert) }} {{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(twoTankDisplayData.tankA.fertilizers.length) }) }} {{ i18n.formatNumber(twoTankDisplayData.tankA.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
N: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ i18n.t('ionLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankA.ionBalance.imbalance.toFixed(1)) }}% {{ twoTankDisplayData.tankA.ionBalance.statusText }} {{ i18n.t('ecLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankA.ecPrediction.ec.toFixed(2)) }}

{{ twoTankDisplayData.tankB.name }}

{{ twoTankDisplayData.tankB.description }}

{{ i18n.t('noFertilizersInTank') || 'No fertilizers in this tank' }}
{{ i18n.getFertilizerName(fert) }} {{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(twoTankDisplayData.tankB.fertilizers.length) }) }} {{ i18n.formatNumber(twoTankDisplayData.tankB.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
N: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ i18n.t('ionLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankB.ionBalance.imbalance.toFixed(1)) }}% {{ twoTankDisplayData.tankB.ionBalance.statusText }} {{ i18n.t('ecLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankB.ecPrediction.ec.toFixed(2)) }}

{{ i18n.t('combinedSolutionWhenMixed') }}

{{ i18n.t('combinedSolutionDescription') }}

{{ twoTankDisplayData.nutrientLabels.N }}: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ twoTankDisplayData.nutrientLabels.P }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.combinedNutrients.P : twoTankDisplayData.combinedNutrients.P2O5).toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ twoTankDisplayData.nutrientLabels.K }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.combinedNutrients.K : twoTankDisplayData.combinedNutrients.K2O).toFixed(1)) }} {{ i18n.t('ppmUnit') }} Ca: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.Ca.toFixed(1)) }} {{ i18n.t('ppmUnit') }} Mg: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.Mg.toFixed(1)) }} {{ i18n.t('ppmUnit') }} S: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.S.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.t('combinedEcLabel') }} {{ i18n.formatNumber(twoTankDisplayData.combinedEc.ec.toFixed(2)) }} {{ i18n.t('mScmUnit') }} ({{ twoTankDisplayData.combinedEc.text }}) {{ i18n.t('total') || 'Total' }}: {{ i18n.formatNumber(twoTankDisplayData.grandTotalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }} (Tank A: {{ i18n.formatNumber(twoTankDisplayData.tankA.totalGrams.toFixed(2)) }}{{ i18n.t('gramsShort') }} + Tank B: {{ i18n.formatNumber(twoTankDisplayData.tankB.totalGrams.toFixed(2)) }}{{ i18n.t('gramsShort') }})
⚠ {{ i18n.t('cannotAchieveExactTargets') }}
  • {{ w }}

{{ i18n.t('cannotAchieveExactTargetsDescription') }}

{{ i18n.t('nutritionalConsiderations') }}
  • {{ warning.category }}: {{ warning.message }}

{{ i18n.t('requiredFertilizers') }}

{{ i18n.t('fertilizersToAddPer', { volume: i18n.formatNumber(reverseResultsData.volume), unit: i18n.t('litersShort') }) }}

Unable to calculate formula

The selected fertilizers cannot achieve the target nutrient ratios. Try selecting different fertilizers or adjusting your targets.

⚠ {{ i18n.t('cannotAchieveExactTargets') }}
  • {{ w }}

{{ i18n.t('cannotAchieveExactTargetsConsider') }}

  • {{ i18n.t('considerSelectingAdditionalFertilizers') }}
  • {{ i18n.t('considerAdjustingTargetValues') }}
  • {{ i18n.t('considerAcceptingDeviations') }}
{{ i18n.t('note') }}
  • {{ w }}
✓ {{ i18n.t('targetsSuccessfullyAchieved') }}

{{ i18n.t('allNutrientValuesWithinRange') }}

{{ i18n.t('targetVsAchievedRatios') }} ?

{{ i18n.t('nutrient') }} {{ i18n.t('yourInput') }} {{ i18n.t('achievedRatio') }} {{ i18n.t('ppmAchieved') }}
{{ item.label }} {{ i18n.t('ppmLabel') }} {{ i18n.formatNumber(Number(item.achievedPPM || 0).toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.t('nitrogenFormLabel') }} {{ i18n.formatNumber(reverseResultsData.result.achieved.N_NH4.toFixed(1)) }} ppm NH₄-N ({{ i18n.formatNumber(reverseResultsData.nh4Percent.toFixed(1)) }}% {{ i18n.t('ofTotalN') }}), {{ i18n.formatNumber(reverseResultsData.result.achieved.N_NO3.toFixed(1)) }} ppm NO₃-N ({{ i18n.formatNumber((100 - reverseResultsData.nh4Percent).toFixed(1)) }}% {{ i18n.t('ofTotalN') }})

{{ i18n.t('ionBalance') }} ?

{{ i18n.t('cations') }} (+)
{{ i18n.formatNumber(reverseResultsData.ionBalance.totalCations.toFixed(2)) }}
meq/L
vs
{{ i18n.t('anions') }} (-)
{{ i18n.formatNumber(reverseResultsData.ionBalance.totalAnions.toFixed(2)) }}
meq/L
{{ i18n.t('imbalance') }}
{{ i18n.formatNumber(reverseResultsData.ionBalance.imbalance.toFixed(1)) }}%
{{ reverseResultsData.ionBalance.statusText }}

{{ i18n.t('estimatedEC') }}

{{ i18n.formatNumber(reverseResultsData.ecPrediction.ec.toFixed(2)) }}
mS/cm
{{ reverseResultsData.ecPrediction.text }}
{{ i18n.t('targetEC') }}
{{ i18n.formatNumber(reverseResultsData.ecPrediction.targetEC) }} mS/cm
{{ i18n.t('scaledToMatch') }}

{{ i18n.t('nutrientRatioAnalysis') }}

?
{{ i18n.t('boronWarningTitle') }}
{{ i18n.formatNumber(reverseResultsData.boronWarning.ppm.toFixed(2)) }} ppm
{{ reverseResultsData.boronWarning.text }}
{{ i18n.t('nutritionalConsiderations') }}
  • {{ warning.category }}: {{ warning.message }}

{{ i18n.t('twoTankStockSolutionSystem') }}

{{ i18n.t('twoTankSeparationNote') }}

{{ twoTankDisplayData.tankA.name }}

{{ twoTankDisplayData.tankA.description }}

{{ i18n.t('noFertilizersInTank') || 'No fertilizers in this tank' }}
{{ i18n.getFertilizerName(fert) }} {{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(twoTankDisplayData.tankA.fertilizers.length) }) }} {{ i18n.formatNumber(twoTankDisplayData.tankA.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
N: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ twoTankDisplayData.nutrientLabels.P }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankA.nutrients.P : twoTankDisplayData.tankA.nutrients.P2O5).toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ twoTankDisplayData.nutrientLabels.K }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankA.nutrients.K : twoTankDisplayData.tankA.nutrients.K2O).toFixed(1)) }} {{ i18n.t('ppmUnit') }} Ca: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.Ca.toFixed(1)) }} {{ i18n.t('ppmUnit') }} Mg: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.Mg.toFixed(1)) }} {{ i18n.t('ppmUnit') }} S: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.S.toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ i18n.t('ionLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankA.ionBalance.imbalance.toFixed(1)) }}% {{ twoTankDisplayData.tankA.ionBalance.statusText }} {{ i18n.t('ecLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankA.ecPrediction.ec.toFixed(2)) }}
{{ i18n.t('nutrientPpmValues') }}
{{ i18n.t('nutrientHeader') }} {{ i18n.t('ppmHeader') }}
{{ item.label }} {{ i18n.formatNumber((item.value || 0).toFixed(2)) }}
{{ i18n.t('nitrogenFormsLabel') }}
NH₄-N: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.N_NH4.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankA.nh4Percent.toFixed(1)) }}%) | NO₃-N: {{ i18n.formatNumber(twoTankDisplayData.tankA.nutrients.N_NO3.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankA.no3Percent.toFixed(1)) }}%)
{{ i18n.t('nutrientRatiosRelative') }}
{{ i18n.t('targetRatioLabel', { ratio: twoTankDisplayData.tankA.ratios.target.label }) }}
{{ twoTankDisplayData.tankA.ratios.target.values }}
{{ i18n.t('thisTankRatioLabel', { ratio: twoTankDisplayData.tankA.ratios.contribution.label }) }}
{{ twoTankDisplayData.tankA.ratios.contribution.values }}
Ca:Mg
{{ i18n.formatNumber(twoTankDisplayData.tankA.ratios.caMg.ratio) }} : 1
N:Ca
{{ i18n.formatNumber(twoTankDisplayData.tankA.ratios.nCa.ratio) }} : 1
{{ twoTankDisplayData.tankA.ratios.kCa.kLabel }}:Ca ?
{{ i18n.formatNumber(twoTankDisplayData.tankA.ratios.kCa.ratio) }} : 1
{{ twoTankDisplayData.tankA.ratios.kCa.status.text }}

{{ twoTankDisplayData.tankB.name }}

{{ twoTankDisplayData.tankB.description }}

{{ i18n.t('noFertilizersInTank') || 'No fertilizers in this tank' }}
{{ i18n.getFertilizerName(fert) }} {{ i18n.formatNumber(fert.grams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
{{ i18n.t('totalFertilizers', { count: i18n.formatNumber(twoTankDisplayData.tankB.fertilizers.length) }) }} {{ i18n.formatNumber(twoTankDisplayData.tankB.totalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }}
N: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ twoTankDisplayData.nutrientLabels.P }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankB.nutrients.P : twoTankDisplayData.tankB.nutrients.P2O5).toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ twoTankDisplayData.nutrientLabels.K }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.tankB.nutrients.K : twoTankDisplayData.tankB.nutrients.K2O).toFixed(1)) }} {{ i18n.t('ppmUnit') }} Ca: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.Ca.toFixed(1)) }} {{ i18n.t('ppmUnit') }} Mg: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.Mg.toFixed(1)) }} {{ i18n.t('ppmUnit') }} S: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.S.toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ i18n.t('ionLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankB.ionBalance.imbalance.toFixed(1)) }}% {{ twoTankDisplayData.tankB.ionBalance.statusText }} {{ i18n.t('ecLabel') }} {{ i18n.formatNumber(twoTankDisplayData.tankB.ecPrediction.ec.toFixed(2)) }}
{{ i18n.t('nutrientPpmValues') }}
{{ i18n.t('nutrientHeader') }} {{ i18n.t('ppmHeader') }}
{{ item.label }} {{ i18n.formatNumber((item.value || 0).toFixed(2)) }}
{{ i18n.t('nitrogenFormsLabel') }}
NH₄-N: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.N_NH4.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankB.nh4Percent.toFixed(1)) }}%) | NO₃-N: {{ i18n.formatNumber(twoTankDisplayData.tankB.nutrients.N_NO3.toFixed(2)) }} {{ i18n.t('ppmUnit') }} ({{ i18n.formatNumber(twoTankDisplayData.tankB.no3Percent.toFixed(1)) }}%)
{{ i18n.t('nutrientRatiosRelative') }}
{{ i18n.t('targetRatioLabel', { ratio: twoTankDisplayData.tankB.ratios.target.label }) }}
{{ twoTankDisplayData.tankB.ratios.target.values }}
{{ i18n.t('thisTankRatioLabel', { ratio: twoTankDisplayData.tankB.ratios.contribution.label }) }}
{{ twoTankDisplayData.tankB.ratios.contribution.values }}
Ca:Mg
{{ i18n.formatNumber(twoTankDisplayData.tankB.ratios.caMg.ratio) }} : 1
N:Ca
{{ i18n.formatNumber(twoTankDisplayData.tankB.ratios.nCa.ratio) }} : 1
{{ twoTankDisplayData.tankB.ratios.kCa.kLabel }}:Ca ?
{{ i18n.formatNumber(twoTankDisplayData.tankB.ratios.kCa.ratio) }} : 1
{{ twoTankDisplayData.tankB.ratios.kCa.status.text }}

{{ i18n.t('combinedSolutionWhenMixed') }}

{{ i18n.t('combinedSolutionDescription') }}

{{ twoTankDisplayData.nutrientLabels.N }}: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.N_total.toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ twoTankDisplayData.nutrientLabels.P }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.combinedNutrients.P : twoTankDisplayData.combinedNutrients.P2O5).toFixed(1)) }} {{ i18n.t('ppmUnit') }} {{ twoTankDisplayData.nutrientLabels.K }}: {{ i18n.formatNumber((twoTankDisplayData.mode === 'elemental' ? twoTankDisplayData.combinedNutrients.K : twoTankDisplayData.combinedNutrients.K2O).toFixed(1)) }} {{ i18n.t('ppmUnit') }} Ca: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.Ca.toFixed(1)) }} {{ i18n.t('ppmUnit') }} Mg: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.Mg.toFixed(1)) }} {{ i18n.t('ppmUnit') }} S: {{ i18n.formatNumber(twoTankDisplayData.combinedNutrients.S.toFixed(1)) }} {{ i18n.t('ppmUnit') }}
{{ i18n.t('combinedEcLabel') }} {{ i18n.formatNumber(twoTankDisplayData.combinedEc.ec.toFixed(2)) }} {{ i18n.t('mScmUnit') }} ({{ twoTankDisplayData.combinedEc.text }}) {{ i18n.t('total') || 'Total' }}: {{ i18n.formatNumber(twoTankDisplayData.grandTotalGrams.toFixed(2)) }} {{ i18n.t('gramsShort') }} (Tank A: {{ i18n.formatNumber(twoTankDisplayData.tankA.totalGrams.toFixed(2)) }}{{ i18n.t('gramsShort') }} + Tank B: {{ i18n.formatNumber(twoTankDisplayData.tankB.totalGrams.toFixed(2)) }}{{ i18n.t('gramsShort') }})
⚠ {{ i18n.t('cannotAchieveExactTargets') }}
  • {{ w }}

{{ i18n.t('cannotAchieveExactTargetsDescription') }}

{{ i18n.t('nutritionalConsiderations') }}
  • {{ warning.category }}: {{ warning.message }}
v1.7.0