- Add guides: quick-start, installation, configuration, grower, consumer, transport, vertical-farm - Add API references: REST, demand, vertical-farming - Add concepts: blockchain, seasonal-planning, carbon-footprint - Add architecture: data-flow, transport-tracking - Add vertical-farming: environmental-control, automation, integration - Add examples: seed-to-harvest, demand-driven-planting, vertical-farm-setup Completes Agent_5 documentation tasks from AGENT_REPORT.md
498 lines
12 KiB
Markdown
498 lines
12 KiB
Markdown
# Example: Vertical Farm Setup
|
|
|
|
Complete workflow for setting up and operating a vertical farm with LocalGreenChain.
|
|
|
|
## Scenario
|
|
|
|
You're setting up a 400 sqm vertical farm to grow lettuce, basil, and microgreens year-round.
|
|
|
|
## Step 1: Register Your Farm
|
|
|
|
```typescript
|
|
// POST /api/vertical-farm/register
|
|
|
|
const farmRegistration = {
|
|
name: 'Urban Greens VF',
|
|
ownerId: 'operator-001',
|
|
|
|
location: {
|
|
latitude: 40.7128,
|
|
longitude: -74.0060,
|
|
address: '500 Industrial Way',
|
|
city: 'Brooklyn',
|
|
country: 'USA',
|
|
timezone: 'America/New_York'
|
|
},
|
|
|
|
specs: {
|
|
totalAreaSqm: 500,
|
|
growingAreaSqm: 400,
|
|
numberOfLevels: 4,
|
|
ceilingHeightM: 4,
|
|
totalGrowingPositions: 5000,
|
|
currentActivePlants: 0,
|
|
powerCapacityKw: 150,
|
|
waterStorageL: 10000,
|
|
backupPowerHours: 24,
|
|
certifications: ['gap', 'local_food_safety'],
|
|
buildingType: 'warehouse',
|
|
insulation: 'high_efficiency'
|
|
},
|
|
|
|
automationLevel: 'semi_automated'
|
|
};
|
|
|
|
const response = await fetch('/api/vertical-farm/register', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(farmRegistration)
|
|
});
|
|
|
|
const { data: farm } = await response.json();
|
|
console.log('Farm registered:', farm.id);
|
|
console.log('Status:', farm.status); // 'operational'
|
|
```
|
|
|
|
## Step 2: Configure Growing Zones
|
|
|
|
Create zones for different crops:
|
|
|
|
```typescript
|
|
// Zone A: Lettuce (NFT system)
|
|
const zoneA = {
|
|
name: 'Zone A - Lettuce',
|
|
level: 1,
|
|
areaSqm: 150,
|
|
lengthM: 30,
|
|
widthM: 5,
|
|
growingMethod: 'NFT',
|
|
plantPositions: 1800,
|
|
|
|
environmentTargets: {
|
|
temperatureC: { min: 18, max: 24, target: 21 },
|
|
humidityPercent: { min: 55, max: 75, target: 65 },
|
|
co2Ppm: { min: 800, max: 1400, target: 1000 },
|
|
lightPpfd: { min: 200, max: 400, target: 300 },
|
|
lightHours: 16,
|
|
nutrientEc: { min: 1.2, max: 1.8, target: 1.5 },
|
|
nutrientPh: { min: 5.5, max: 6.5, target: 6.0 },
|
|
waterTempC: { min: 18, max: 22, target: 20 }
|
|
}
|
|
};
|
|
|
|
// Zone B: Basil (DWC system)
|
|
const zoneB = {
|
|
name: 'Zone B - Basil',
|
|
level: 2,
|
|
areaSqm: 100,
|
|
lengthM: 20,
|
|
widthM: 5,
|
|
growingMethod: 'DWC',
|
|
plantPositions: 1200,
|
|
|
|
environmentTargets: {
|
|
temperatureC: { min: 20, max: 28, target: 24 },
|
|
humidityPercent: { min: 50, max: 70, target: 60 },
|
|
co2Ppm: { min: 800, max: 1400, target: 1200 },
|
|
lightPpfd: { min: 300, max: 500, target: 400 },
|
|
lightHours: 18,
|
|
nutrientEc: { min: 1.0, max: 1.6, target: 1.3 },
|
|
nutrientPh: { min: 5.5, max: 6.5, target: 6.0 },
|
|
waterTempC: { min: 18, max: 22, target: 20 }
|
|
}
|
|
};
|
|
|
|
// Zone C: Microgreens (Rack system)
|
|
const zoneC = {
|
|
name: 'Zone C - Microgreens',
|
|
level: 3,
|
|
areaSqm: 100,
|
|
lengthM: 20,
|
|
widthM: 5,
|
|
growingMethod: 'rack_system',
|
|
plantPositions: 2000, // Tray positions
|
|
|
|
environmentTargets: {
|
|
temperatureC: { min: 18, max: 24, target: 21 },
|
|
humidityPercent: { min: 60, max: 80, target: 70 },
|
|
co2Ppm: { min: 600, max: 1200, target: 800 },
|
|
lightPpfd: { min: 150, max: 300, target: 250 },
|
|
lightHours: 16,
|
|
nutrientEc: { min: 0.5, max: 1.0, target: 0.8 },
|
|
nutrientPh: { min: 5.5, max: 6.5, target: 6.0 },
|
|
waterTempC: { min: 18, max: 22, target: 20 }
|
|
}
|
|
};
|
|
|
|
// Create zones
|
|
for (const zone of [zoneA, zoneB, zoneC]) {
|
|
await fetch(`/api/vertical-farm/${farm.id}/zones`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(zone)
|
|
});
|
|
}
|
|
|
|
console.log('Zones configured: Lettuce, Basil, Microgreens');
|
|
```
|
|
|
|
## Step 3: View Available Recipes
|
|
|
|
```typescript
|
|
// GET /api/vertical-farm/recipes
|
|
|
|
const response = await fetch('/api/vertical-farm/recipes');
|
|
const { data: recipes } = await response.json();
|
|
|
|
console.log('Available recipes:');
|
|
for (const recipe of recipes) {
|
|
console.log(`- ${recipe.name}`);
|
|
console.log(` Crop: ${recipe.cropType}`);
|
|
console.log(` Days: ${recipe.expectedDays}`);
|
|
console.log(` Yield: ${recipe.expectedYieldGrams}g per plant`);
|
|
}
|
|
|
|
/*
|
|
Available recipes:
|
|
- Butterhead Lettuce - Fast Cycle
|
|
Crop: lettuce
|
|
Days: 35
|
|
Yield: 180g per plant
|
|
|
|
- Genovese Basil - Aromatic
|
|
Crop: basil
|
|
Days: 42
|
|
Yield: 120g per plant
|
|
|
|
- Microgreens Mix - Quick Turn
|
|
Crop: microgreens
|
|
Days: 14
|
|
Yield: 200g per tray
|
|
*/
|
|
```
|
|
|
|
## Step 4: Start Crop Batches
|
|
|
|
### Link to Seed Source
|
|
|
|
First, ensure seeds are tracked in the transport chain:
|
|
|
|
```typescript
|
|
// Record seed acquisition (see seed-to-harvest example)
|
|
await fetch('/api/transport/seed-acquisition', {
|
|
method: 'POST',
|
|
body: JSON.stringify({
|
|
seedBatchId: 'seeds-lettuce-vf-001',
|
|
sourceType: 'purchase',
|
|
species: 'Lactuca sativa',
|
|
quantity: 10000,
|
|
quantityUnit: 'seeds',
|
|
// ... other fields
|
|
})
|
|
});
|
|
```
|
|
|
|
### Start Lettuce Batch
|
|
|
|
```typescript
|
|
// POST /api/vertical-farm/batch/start
|
|
|
|
const lettuceBatch = {
|
|
farmId: farm.id,
|
|
zoneId: 'zone-a-id',
|
|
recipeId: 'recipe-lettuce-butterhead',
|
|
seedBatchId: 'seeds-lettuce-vf-001', // Links to transport chain!
|
|
plantCount: 200
|
|
};
|
|
|
|
const response = await fetch('/api/vertical-farm/batch/start', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(lettuceBatch)
|
|
});
|
|
|
|
const { data: batch } = await response.json();
|
|
|
|
console.log('Batch started:', batch.id);
|
|
console.log('Expected harvest:', batch.expectedHarvestDate);
|
|
console.log('Expected yield:', batch.expectedYieldKg, 'kg');
|
|
console.log('Plant IDs:', batch.plantIds.length, 'plants tracked');
|
|
|
|
/*
|
|
Batch started: batch-lettuce-001
|
|
Expected harvest: 2024-07-06
|
|
Expected yield: 36 kg
|
|
Plant IDs: 200 plants tracked
|
|
*/
|
|
```
|
|
|
|
### Start Microgreens Batch
|
|
|
|
```typescript
|
|
const microgreensBatch = {
|
|
farmId: farm.id,
|
|
zoneId: 'zone-c-id',
|
|
recipeId: 'recipe-microgreens-mix',
|
|
seedBatchId: 'seeds-microgreens-001',
|
|
plantCount: 50 // 50 trays
|
|
};
|
|
|
|
await fetch('/api/vertical-farm/batch/start', {
|
|
method: 'POST',
|
|
body: JSON.stringify(microgreensBatch)
|
|
});
|
|
|
|
// Microgreens harvest in just 14 days!
|
|
```
|
|
|
|
## Step 5: Report Environment Data
|
|
|
|
Set up automated reporting from your control system:
|
|
|
|
```typescript
|
|
// Environmental monitoring script
|
|
|
|
async function reportEnvironment() {
|
|
// Collect sensor data
|
|
const readings = await collectSensorData('zone-a-id');
|
|
|
|
// PUT /api/vertical-farm/batch/{batchId}/environment
|
|
const response = await fetch(`/api/vertical-farm/batch/${batch.id}/environment`, {
|
|
method: 'PUT',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'Authorization': `Bearer ${API_KEY}`
|
|
},
|
|
body: JSON.stringify({
|
|
timestamp: new Date().toISOString(),
|
|
temperatureC: readings.temperature, // 21.5
|
|
humidityPercent: readings.humidity, // 68
|
|
co2Ppm: readings.co2, // 1050
|
|
vpd: readings.vpd, // 0.85
|
|
ppfd: readings.ppfd, // 295
|
|
dli: readings.dli, // 17.0
|
|
waterTempC: readings.waterTemp, // 19.5
|
|
ec: readings.ec, // 1.55
|
|
ph: readings.ph, // 6.1
|
|
dissolvedOxygenPpm: readings.do, // 8.2
|
|
airflowMs: readings.airflow // 0.5
|
|
})
|
|
});
|
|
|
|
const { data } = await response.json();
|
|
|
|
// Handle any alerts
|
|
if (data.alerts && data.alerts.length > 0) {
|
|
console.log('ALERTS:', data.alerts);
|
|
for (const alert of data.alerts) {
|
|
handleAlert(alert);
|
|
}
|
|
}
|
|
|
|
console.log('Environment recorded. Health score:', data.healthScore);
|
|
}
|
|
|
|
// Report every 5 minutes
|
|
setInterval(reportEnvironment, 5 * 60 * 1000);
|
|
```
|
|
|
|
## Step 6: Monitor Batch Progress
|
|
|
|
```typescript
|
|
// Check batch status daily
|
|
|
|
async function checkBatchProgress(batchId: string) {
|
|
// GET /api/vertical-farm/batch/{batchId}
|
|
const response = await fetch(`/api/vertical-farm/batch/${batchId}`);
|
|
const { data: batch } = await response.json();
|
|
|
|
console.log(`
|
|
Batch: ${batch.id}
|
|
Crop: ${batch.cropType}
|
|
Day: ${batch.currentDay} / ${batch.expectedDays}
|
|
Stage: ${batch.currentStage}
|
|
Health: ${batch.healthScore}%
|
|
Status: ${batch.status}
|
|
Expected Harvest: ${batch.expectedHarvestDate}
|
|
`);
|
|
|
|
// Check for issues
|
|
if (batch.issues.length > 0) {
|
|
console.log('ISSUES:');
|
|
for (const issue of batch.issues) {
|
|
console.log(`- ${issue.type}: ${issue.description}`);
|
|
}
|
|
}
|
|
|
|
// Approaching harvest?
|
|
const daysToHarvest = batch.expectedDays - batch.currentDay;
|
|
if (daysToHarvest <= 3) {
|
|
console.log('ALERT: Prepare for harvest in', daysToHarvest, 'days');
|
|
}
|
|
|
|
return batch;
|
|
}
|
|
```
|
|
|
|
## Step 7: Complete Harvest
|
|
|
|
```typescript
|
|
// POST /api/vertical-farm/batch/{batchId}/harvest
|
|
|
|
const harvestData = {
|
|
actualYieldKg: 38.5, // Exceeded expectation!
|
|
qualityGrade: 'A',
|
|
notes: 'Excellent crop. Slight overperformance due to optimal conditions.'
|
|
};
|
|
|
|
const response = await fetch(`/api/vertical-farm/batch/${batch.id}/harvest`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(harvestData)
|
|
});
|
|
|
|
const { data: harvestResult } = await response.json();
|
|
|
|
console.log('Harvest completed!');
|
|
console.log('Actual yield:', harvestResult.actualYieldKg, 'kg');
|
|
console.log('Expected yield:', harvestResult.expectedYieldKg, 'kg');
|
|
console.log('Variance:', harvestResult.yieldVariance, '%');
|
|
console.log('Quality grade:', harvestResult.qualityGrade);
|
|
|
|
/*
|
|
This automatically:
|
|
1. Records harvest in transport chain
|
|
2. Links to seed origin (full traceability)
|
|
3. Updates batch status to 'completed'
|
|
4. Frees zone for next batch
|
|
*/
|
|
```
|
|
|
|
## Step 8: View Analytics
|
|
|
|
```typescript
|
|
// GET /api/vertical-farm/{farmId}/analytics?period=30
|
|
|
|
const response = await fetch(
|
|
`/api/vertical-farm/${farm.id}/analytics?period=30`
|
|
);
|
|
const { data: analytics } = await response.json();
|
|
|
|
console.log(`
|
|
=== FARM ANALYTICS (30 days) ===
|
|
|
|
PRODUCTION
|
|
Total Yield: ${analytics.totalYieldKg} kg
|
|
Yield/sqm/year: ${analytics.yieldPerSqmPerYear} kg
|
|
Cycles Completed: ${analytics.cropCyclesCompleted}
|
|
Avg Cycle Length: ${analytics.averageCyclesDays} days
|
|
|
|
QUALITY
|
|
Avg Health Score: ${analytics.averageQualityScore}
|
|
Grade A: ${analytics.gradeAPercent}%
|
|
Wastage: ${analytics.wastagePercent}%
|
|
|
|
EFFICIENCY
|
|
Success Rate: ${analytics.cropSuccessRate}%
|
|
Space Utilization: ${analytics.spaceUtilization}%
|
|
Labor Hours/kg: ${analytics.laborHoursPerKg}
|
|
|
|
FINANCIAL
|
|
Revenue: $${analytics.revenueUsd}
|
|
Cost: $${analytics.costUsd}
|
|
Profit Margin: ${analytics.profitMarginPercent}%
|
|
Revenue/sqm: $${analytics.revenuePerSqm}
|
|
|
|
ENVIRONMENTAL
|
|
Carbon/kg: ${analytics.carbonFootprintKgPerKg} kg CO2
|
|
Water/kg: ${analytics.waterUseLPerKg} L
|
|
Energy/kg: ${analytics.energyUseKwhPerKg} kWh
|
|
|
|
TOP PERFORMERS
|
|
By Yield: ${analytics.topCropsByYield.map(c => c.crop).join(', ')}
|
|
By Revenue: ${analytics.topCropsByRevenue.map(c => c.crop).join(', ')}
|
|
`);
|
|
```
|
|
|
|
## Complete Setup Script
|
|
|
|
```typescript
|
|
// vertical-farm-setup.ts
|
|
|
|
import { getVerticalFarmController } from '@/lib/vertical-farming/controller';
|
|
|
|
async function setupVerticalFarm() {
|
|
const controller = getVerticalFarmController();
|
|
|
|
// 1. Register farm
|
|
const farm = await registerFarm();
|
|
console.log('Farm registered:', farm.id);
|
|
|
|
// 2. Configure zones
|
|
const zones = await configureZones(farm.id);
|
|
console.log('Zones configured:', zones.length);
|
|
|
|
// 3. View recipes
|
|
const recipes = controller.getRecipes();
|
|
console.log('Available recipes:', recipes.length);
|
|
|
|
// 4. Start batches for each zone
|
|
const batches = [];
|
|
for (const zone of zones) {
|
|
const recipe = selectRecipeForZone(zone, recipes);
|
|
const batch = controller.startCropBatch(
|
|
farm.id,
|
|
zone.id,
|
|
recipe.id,
|
|
`seeds-${recipe.cropType}-001`,
|
|
calculatePlantCount(zone, recipe)
|
|
);
|
|
batches.push(batch);
|
|
console.log(`Started ${recipe.cropType} in ${zone.name}`);
|
|
}
|
|
|
|
// 5. Set up monitoring
|
|
setupEnvironmentMonitoring(batches);
|
|
|
|
// 6. Schedule harvest checks
|
|
scheduleHarvestAlerts(batches);
|
|
|
|
return { farm, zones, batches };
|
|
}
|
|
|
|
// Run setup
|
|
setupVerticalFarm()
|
|
.then(({ farm, zones, batches }) => {
|
|
console.log('\n=== SETUP COMPLETE ===');
|
|
console.log(`Farm: ${farm.name}`);
|
|
console.log(`Zones: ${zones.length}`);
|
|
console.log(`Active batches: ${batches.length}`);
|
|
})
|
|
.catch(console.error);
|
|
```
|
|
|
|
## Production Schedule
|
|
|
|
With continuous operation:
|
|
|
|
```
|
|
Week 1: Start lettuce batch A (200 plants)
|
|
Week 2: Start microgreens batch A (50 trays), basil batch A (150 plants)
|
|
Week 3: Harvest microgreens A, start microgreens B
|
|
Week 4: Harvest microgreens B, start microgreens C
|
|
Week 5: Harvest lettuce A, start lettuce B
|
|
Week 6: Harvest microgreens C, basil A, start new batches
|
|
...
|
|
|
|
Continuous harvest = continuous revenue!
|
|
```
|
|
|
|
## Key Metrics to Track
|
|
|
|
| Metric | Target | Actual |
|
|
|--------|--------|--------|
|
|
| Yield/sqm/year | 60 kg | 65 kg |
|
|
| Energy/kg | 20 kWh | 15 kWh |
|
|
| Water/kg | 5 L | 4.5 L |
|
|
| Profit margin | 40% | 50% |
|
|
| Success rate | 95% | 98% |
|