Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

irrigation-planner 💧

CI TypeScript License: MIT

A TypeScript library for designing drip irrigation systems. Calculate zone sizing, pressure loss, and timer schedules with hydraulic precision.

✨ Features

Zone sizing – Calculate emitter counts and total flow based on plant water needs
Hydraulic calculations – Pressure loss, velocity, and maximum run lengths using Hazen-Williams
Pipe sizing – Automatically select appropriate pipe diameters for your flow requirements
Multi-zone planning – Design complete irrigation systems with multiple zones
Timer scheduling – Generate optimal watering schedules based on daily water requirements
Type-safe API – Full TypeScript support with branded types for units (GPH, PSI, etc.)

📦 Installation

# npm
npm install @adametherzlab/irrigation-planner

# bun
bun add @adametherzlab/irrigation-planner

🚀 Quick Start

// REMOVED external import: import { calculateZone, PipeDiameter } from "@adametherzlab/irrigation-planner";

const zone = {
  id: "vegetables",
  name: "Vegetable Garden",
  plants: [
    { name: "Tomato", waterNeed: 2 as GallonsPerDay, spacingFt: 3 },
    { name: "Pepper", waterNeed: 1.5 as GallonsPerDay, spacingFt: 2 }
  ],
  emitter: { 
    model: "1 GPH", 
    flowRate: 1 as GallonsPerHour, 
    spacingFt: 1, 
    pressureRange: [15, 30] as [PSI, PSI] 
  },
  pipeDiameter: PipeDiameter.HalfInch,
  pipeLengthFt: 50
};

const result = calculateZone(zone, { emitterEfficiency: 0.9 });
console.log(`Zone needs ${result.emitterCount} emitters, total flow: ${result.totalFlowGph} GPH`);

📚 API Reference

Zone Calculations

calculateZone(zone: Zone, options?: ZoneCalculatorOptions): ZoneCalculationResult

Parameters:

  • zone – Zone configuration with plants, emitter, and pipe details
  • options – Optional calculation settings (emitter efficiency, operating hours)

Returns: ZoneCalculationResult with emitter count, total flow, and daily water volume

Example:

const result = calculateZone(zone, { emitterEfficiency: 0.9 });

calculateMultipleZones(zones: Zone[], options?: ZoneCalculatorOptions): MultipleZoneResults

Parameters:

  • zones – Array of zone configurations
  • options – Calculation options applied to all zones

Returns: MultipleZoneResults with aggregated totals and individual zone results

Example:

const results = calculateMultipleZones([zone1, zone2], { operatingHoursPerDay: 12 });

toZoneResult(zone: Zone, calculation: ZoneCalculationResult, hydraulics?: HydraulicResult): ZoneResult

Parameters:

  • zone – Original zone configuration
  • calculation – Zone calculation results
  • hydraulics – Optional hydraulic calculation results

Returns: ZoneResult compatible with the main types

Example:

const zoneResult = toZoneResult(zone, calculation, hydraulics);

Hydraulic Calculations

calculatePressureLoss(flowRateGph: number, diameterIn: number, roughnessCoefficient?: number): number

Parameters:

  • flowRateGph – Flow rate in gallons per hour
  • diameterIn – Pipe diameter in inches
  • roughnessCoefficient – Hazen-Williams C-factor (default: 150 for PVC)

Returns: Pressure loss in PSI per 100 feet

Example:

const loss = calculatePressureLoss(200, 0.75); // ~2.34 PSI/100ft

calculateVelocity(flowRateGph: number, diameterIn: number): number

Parameters:

  • flowRateGph – Flow rate in gallons per hour
  • diameterIn – Pipe diameter in inches

Returns: Velocity in feet per second

Example:

const velocity = calculateVelocity(200, 0.75); // ~2.89 fps

selectPipeDiameter(flowRateGph: number, options?: PipeSizingOptions): PipeDiameter

Parameters:

  • flowRateGph – Flow rate in gallons per hour
  • options – Pipe sizing options (max velocity, pressure loss limit)

Returns: Recommended pipe diameter from PipeDiameter enum

Example:

const diameter = selectPipeDiameter(500); // PipeDiameter.OneInch

calculateMaxRunLength(flowRateGph: number, diameterIn: number, inletPressurePsi: PSI, options?: PipeSizingOptions): number

Parameters:

  • flowRateGph – Flow rate in gallons per hour
  • diameterIn – Pipe diameter in inches
  • inletPressurePsi – Starting pressure at pipe inlet
  • options – Pipe sizing options

Returns: Maximum run length in feet

Example:

const maxLength = calculateMaxRunLength(200, 0.75, 50 as PSI); // ~2134 ft

calculateHydraulics(input: HydraulicInput, options?: PipeSizingOptions): HydraulicResult

Parameters:

  • input – Hydraulic input parameters (flow, diameter, length, inlet pressure)
  • options – Pipe sizing options

Returns: HydraulicResult with pressure loss, velocity, and outlet pressure

Example:

const result = calculateHydraulics({
  flowRateGph: 200,
  pipeDiameterIn: 0.75,
  pipeLengthFt: 100,
  inletPressurePsi: 50 as PSI
});

🔧 Advanced Usage

Complete Two-Zone System Design

import {
  calculateMultipleZones,
  calculateHydraulics,
  selectPipeDiameter,
  PipeDiameter,
  type Zone,
  type PSI,
  type GallonsPerDay,
  type GallonsPerHour
} from "@adametherzlab/irrigation-planner";

// Zone 1: Vegetable garden
const vegetableZone: Zone = {
  id: "zone1",
  name: "Vegetables",
  plants: [
    { name: "Tomato", waterNeed: 2 as GallonsPerDay, spacingFt: 3 },
    { name: "Lettuce", waterNeed: 1 as GallonsPerDay, spacingFt: 1 },
    { name: "Carrot", waterNeed: 0.8 as GallonsPerDay, spacingFt: 0.5 }
  ],
  emitter: {
    model: "1 GPH",
    flowRate: 1 as GallonsPerHour,
    spacingFt: 1,
    pressureRange: [15, 30] as [PSI, PSI]
  },
  pipeDiameter: PipeDiameter.HalfInch,
  pipeLengthFt: 75
};

// Zone 2: Fruit trees
const fruitZone: Zone = {
  id: "zone2",
  name: "Fruit Trees",
  plants: [
    { name: "Apple", waterNeed: 10 as GallonsPerDay, spacingFt: 15 },
    { name: "Peach", waterNeed: 8 as GallonsPerDay, spacingFt: 12 }
  ],
  emitter: {
    model: "2 GPH",
    flowRate: 2 as GallonsPerHour,
    spacingFt: 2,
    pressureRange: [20, 40] as [PSI, PSI]
  },
  pipeDiameter: PipeDiameter.ThreeQuarterInch,
  pipeLengthFt: 120
};

// Calculate zone requirements
const results = calculateMultipleZones([vegetableZone, fruitZone], {
  emitterEfficiency: 0.9,
  operatingHoursPerDay: 6
});

console.log(`Total system flow: ${results.totalFlowGph} GPH`);
console.log(`Total daily water: ${results.totalDailyWaterGallons} gallons`);

// Check hydraulic performance for each zone
for (const zoneResult of results.zones) {
  const hydraulics = calculateHydraulics({
    flowRateGph: zoneResult.totalFlowGph,
    pipeDiameterIn: zoneResult.zone.pipeDiameter,
    pipeLengthFt: zoneResult.zone.pipeLengthFt,
    inletPressurePsi: 45 as PSI
  });
  
  console.log(`${zoneResult.zone.name}: Outlet pressure ${hydraulics.outletPressurePsi.toFixed(1)} PSI`);
}

Timer Schedule Generation

// REMOVED external import: import { type TimerSchedule } from "@adametherzlab/irrigation-planner";

function createTimerSchedule(
  totalFlowGph: number,
  dailyWaterNeeded: number,
  maxZonesPerController: number = 4
): TimerSchedule {
  const hoursPerDay = dailyWaterNeeded / totalFlowGph;
  const minutesPerZone = Math.ceil((hoursPerDay * 60) / maxZonesPerController);
  
  return {
    startTime: "06:00",
    zoneDurations: Array(maxZonesPerController).fill(minutesPerZone),
    daysOfWeek: [1, 3, 5, 7], // Monday, Wednesday, Friday, Sunday
    totalDailyRuntimeMinutes: minutesPerZone * maxZonesPerController
  };
}

// Example: 300 GPH system needing 1800 gallons daily
const schedule = createTimerSchedule(300, 1800);
console.log(`Water ${schedule.zoneDurations.length} zones for ${schedule.zoneDurations[0]} minutes each`);

📐 Hydraulic Formulas

The library uses the Hazen-Williams equation for pressure loss calculations:

P = (4.52 * Q^1.85) / (C^1.85 * d^4.87)

Where:

  • P = Pressure loss (PSI per 100 feet)
  • Q = Flow rate (gallons per hour)
  • C = Hazen-Williams roughness coefficient (150 for new PVC pipe)
  • d = Pipe diameter (inches)

Velocity is calculated as:

V = (0.4085 * Q) / d²

Where V is velocity in feet per second.

📏 Unit Conventions

  • Flow rates: Gallons per hour (GPH) for emitters and total flow
  • Water needs: Gallons per day (GPD) for plant requirements
  • Pressure: Pounds per square inch (PSI)
  • Lengths: Feet for pipe runs and plant spacing
  • Pipe diameters: Inches (½", ¾", 1", 1¼", 1½", 2")
  • Time: Minutes for timer schedules, hours for operating durations

🤝 Contributing

See CONTRIBUTING.md for development guidelines, code style, and pull request process.

📄 License

MIT © AdametherzLab

About

Drip irrigation layout planner — zone sizing, pressure loss, timer schedules

Topics

Resources

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages