Implements detailed tracking of soil composition, nutrients, climate, lighting, and surrounding environment to help understand plant success and optimize growing conditions. Environmental Data Types (lib/environment/types.ts): - Soil composition (type, pH, texture, drainage, organic matter) - Soil amendments (compost, perlite, amendments tracking) - Nutrient profiles (NPK, secondary nutrients, micronutrients, EC, TDS) - Fertilizer applications (type, schedule, NPK values) - Lighting conditions (natural/artificial, hours, spectrum, PPFD/DLI) - Climate tracking (temperature, humidity, airflow, CO2, USDA zones) - Growing location (indoor/outdoor/greenhouse with details) - Container information (type, material, size, drainage) - Watering schedule (method, frequency, water quality/pH) - Surrounding environment (companion plants, pests, diseases, ecosystem) - Growth metrics (measurements, health scores, vigor tracking) Environmental Analysis (lib/environment/analysis.ts): - Compare environments with similarity scoring (0-100) - Generate personalized growing recommendations - Calculate environmental health scores - Find plants with similar conditions - Analyze growth correlations across network - Identify optimal growing conditions API Endpoints: - /api/environment/recommendations - Get plant-specific advice - /api/environment/similar - Find plants with similar conditions - /api/environment/compare - Compare two plants environments - /api/environment/analysis - Network-wide growth correlation Features: - Comprehensive soil tracking (pH, texture, drainage, amendments) - Full NPK and micronutrient monitoring - Sunlight exposure and artificial light tracking - Temperature and humidity ranges - Water quality monitoring (pH, TDS, chlorine) - Pest and disease tracking - Companion planting recommendations - Environmental health scoring with priority-based recommendations - Growth success analysis across similar environments Integration: - Updated PlantData type to include environment and growthMetrics - Compatible with existing blockchain structure - Optional environmental data (backward compatible) Use Cases: - Track what works for your plants - Learn from successful growers with similar conditions - Get personalized recommendations based on your setup - Compare your environment with thriving plants - Optimize conditions for better yield/health - Share growing knowledge with the community - Research optimal conditions by species This enables growers to: - Understand why plants thrive or struggle - Replicate successful growing conditions - Make data-driven decisions - Learn from the collective experience - Improve propagation success rates
95 lines
2.9 KiB
TypeScript
95 lines
2.9 KiB
TypeScript
/**
|
|
* API Route: Analyze growth correlations across all plants
|
|
* GET /api/environment/analysis?species=tomato (optional species filter)
|
|
*/
|
|
|
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
|
import { getBlockchain } from '../../../lib/blockchain/manager';
|
|
import { analyzeGrowthCorrelation } from '../../../lib/environment/analysis';
|
|
|
|
export default async function handler(
|
|
req: NextApiRequest,
|
|
res: NextApiResponse
|
|
) {
|
|
if (req.method !== 'GET') {
|
|
return res.status(405).json({ error: 'Method not allowed' });
|
|
}
|
|
|
|
try {
|
|
const { species } = req.query;
|
|
|
|
const blockchain = getBlockchain();
|
|
|
|
// Get all plants
|
|
let allPlants = Array.from(
|
|
new Set(blockchain.chain.map(block => block.plant.id))
|
|
)
|
|
.map(id => blockchain.getPlant(id)!)
|
|
.filter(Boolean);
|
|
|
|
// Filter by species if specified
|
|
if (species && typeof species === 'string') {
|
|
allPlants = allPlants.filter(
|
|
p =>
|
|
p.scientificName?.toLowerCase().includes(species.toLowerCase()) ||
|
|
p.commonName?.toLowerCase().includes(species.toLowerCase())
|
|
);
|
|
}
|
|
|
|
// Only include plants with environmental data
|
|
const plantsWithEnv = allPlants.filter(p => p.environment);
|
|
|
|
if (plantsWithEnv.length === 0) {
|
|
return res.status(200).json({
|
|
success: true,
|
|
message: 'No plants with environmental data found',
|
|
plantsAnalyzed: 0,
|
|
});
|
|
}
|
|
|
|
const analysis = analyzeGrowthCorrelation(plantsWithEnv);
|
|
|
|
// Calculate some additional statistics
|
|
const successRate =
|
|
(plantsWithEnv.filter(
|
|
p => p.status === 'mature' || p.status === 'flowering' || p.status === 'fruiting'
|
|
).length /
|
|
plantsWithEnv.length) *
|
|
100;
|
|
|
|
const locationTypes = plantsWithEnv.reduce((acc, p) => {
|
|
const type = p.environment!.location.type;
|
|
acc[type] = (acc[type] || 0) + 1;
|
|
return acc;
|
|
}, {} as Record<string, number>);
|
|
|
|
const soilTypes = plantsWithEnv.reduce((acc, p) => {
|
|
const type = p.environment!.soil.type;
|
|
acc[type] = (acc[type] || 0) + 1;
|
|
return acc;
|
|
}, {} as Record<string, number>);
|
|
|
|
res.status(200).json({
|
|
success: true,
|
|
plantsAnalyzed: plantsWithEnv.length,
|
|
successRate: Math.round(successRate),
|
|
insights: analysis.insights,
|
|
statistics: {
|
|
locationTypes,
|
|
soilTypes,
|
|
avgTemperature:
|
|
plantsWithEnv.reduce((sum, p) => sum + (p.environment!.climate.temperatureDay || 0), 0) /
|
|
plantsWithEnv.length,
|
|
avgHumidity:
|
|
plantsWithEnv.reduce((sum, p) => sum + (p.environment!.climate.humidityAverage || 0), 0) /
|
|
plantsWithEnv.length,
|
|
avgSoilPH:
|
|
plantsWithEnv.reduce((sum, p) => sum + (p.environment!.soil.pH || 0), 0) /
|
|
plantsWithEnv.length,
|
|
},
|
|
});
|
|
} catch (error: any) {
|
|
console.error('Error analyzing growth correlation:', error);
|
|
res.status(500).json({ error: error.message || 'Internal server error' });
|
|
}
|
|
}
|