Files
dashboard/backend/services/cp707Knowledge.js
T
Alberto-Audrix 32a36cceff
CI / lint-and-test (push) Canceled after 0s
first commit
2026-07-28 08:55:05 +07:00

432 lines
23 KiB
JavaScript

/**
* CP 707 Knowledge Base
* Sumber: Buku "Manajemen Broiler CP 707" oleh PT Charoen Pokphand Indonesia, Tbk.
* Edisi Juli 2023
*
* File ini berisi seluruh standar teknis dari buku panduan CP 707 yang
* digunakan sebagai referensi on-premise untuk AI Insight.
* TIDAK ada data dari sumber luar - hanya dari buku ini.
*/
// ─── Standar Performa Mingguan CP 707 ───────────────────────────────────────
const PERFORMANCE_STANDARD_WEEKLY = [
{ week: 1, targetBW_g: 195, adg_g: 34, cumFeedConsumption_g: 164.5, fcr: 0.844 },
{ week: 2, targetBW_g: 499, adg_g: 50, cumFeedConsumption_g: 530.5, fcr: 1.063 },
{ week: 3, targetBW_g: 954, adg_g: 80, cumFeedConsumption_g: 1181.5, fcr: 1.238 },
{ week: 4, targetBW_g: 1543, adg_g: 88, cumFeedConsumption_g: 2198.5, fcr: 1.425 },
{ week: 5, targetBW_g: 2191, adg_g: 94, cumFeedConsumption_g: 3461, fcr: 1.580 },
];
// ─── Standar Performa Harian CP 707 (Lampiran 2) ────────────────────────────
const PERFORMANCE_STANDARD_DAILY = [
{ day: 1, bw_g: 57, adg_g: 15, mortalityCum_pct: 0.40, feedDaily_g: 13, feedCum_g: 13, fcr: 0.228, ip: null },
{ day: 2, bw_g: 73, adg_g: 16, mortalityCum_pct: 0.50, feedDaily_g: 17, feedCum_g: 30, fcr: 0.411, ip: null },
{ day: 3, bw_g: 90, adg_g: 17, mortalityCum_pct: 0.60, feedDaily_g: 20.5, feedCum_g: 50.5, fcr: 0.561, ip: null },
{ day: 4, bw_g: 110, adg_g: 20, mortalityCum_pct: 0.70, feedDaily_g: 23, feedCum_g: 73.5, fcr: 0.668, ip: null },
{ day: 5, bw_g: 134, adg_g: 24, mortalityCum_pct: 0.80, feedDaily_g: 26, feedCum_g: 99.5, fcr: 0.743, ip: null },
{ day: 6, bw_g: 161, adg_g: 27, mortalityCum_pct: 0.90, feedDaily_g: 31, feedCum_g: 130.5, fcr: 0.811, ip: null },
{ day: 7, bw_g: 195, adg_g: 34, mortalityCum_pct: 1.00, feedDaily_g: 34, feedCum_g: 164.5, fcr: 0.844, ip: 327 },
{ day: 8, bw_g: 231, adg_g: 36, mortalityCum_pct: 1.10, feedDaily_g: 35, feedCum_g: 199.5, fcr: 0.864, ip: 331 },
{ day: 9, bw_g: 269, adg_g: 38, mortalityCum_pct: 1.20, feedDaily_g: 41, feedCum_g: 240.5, fcr: 0.894, ip: 330 },
{ day: 10, bw_g: 311, adg_g: 42, mortalityCum_pct: 1.30, feedDaily_g: 46, feedCum_g: 286.5, fcr: 0.921, ip: 333 },
{ day: 11, bw_g: 355, adg_g: 44, mortalityCum_pct: 1.40, feedDaily_g: 52, feedCum_g: 338.5, fcr: 0.954, ip: 334 },
{ day: 12, bw_g: 401, adg_g: 46, mortalityCum_pct: 1.50, feedDaily_g: 58, feedCum_g: 396.5, fcr: 0.989, ip: 333 },
{ day: 13, bw_g: 449, adg_g: 48, mortalityCum_pct: 1.60, feedDaily_g: 64, feedCum_g: 460.5, fcr: 1.026, ip: 331 },
{ day: 14, bw_g: 499, adg_g: 50, mortalityCum_pct: 1.70, feedDaily_g: 70, feedCum_g: 530.5, fcr: 1.063, ip: 330 },
{ day: 15, bw_g: 552, adg_g: 53, mortalityCum_pct: 1.80, feedDaily_g: 73, feedCum_g: 603.5, fcr: 1.093, ip: 331 },
{ day: 16, bw_g: 609, adg_g: 57, mortalityCum_pct: 1.90, feedDaily_g: 80, feedCum_g: 683.5, fcr: 1.122, ip: 333 },
{ day: 17, bw_g: 669, adg_g: 60, mortalityCum_pct: 2.00, feedDaily_g: 86, feedCum_g: 769.5, fcr: 1.150, ip: 335 },
{ day: 18, bw_g: 734, adg_g: 65, mortalityCum_pct: 2.10, feedDaily_g: 92, feedCum_g: 861.5, fcr: 1.174, ip: 340 },
{ day: 19, bw_g: 802, adg_g: 68, mortalityCum_pct: 2.20, feedDaily_g: 100, feedCum_g: 961.5, fcr: 1.199, ip: 344 },
{ day: 20, bw_g: 874, adg_g: 72, mortalityCum_pct: 2.30, feedDaily_g: 107, feedCum_g: 1068.5, fcr: 1.223, ip: 349 },
{ day: 21, bw_g: 954, adg_g: 80, mortalityCum_pct: 2.40, feedDaily_g: 113, feedCum_g: 1181.5, fcr: 1.238, ip: 358 },
{ day: 22, bw_g: 1035, adg_g: 81, mortalityCum_pct: 2.52, feedDaily_g: 128, feedCum_g: 1309.5, fcr: 1.265, ip: 362 },
{ day: 23, bw_g: 1117, adg_g: 82, mortalityCum_pct: 2.64, feedDaily_g: 133, feedCum_g: 1442.5, fcr: 1.291, ip: 366 },
{ day: 24, bw_g: 1200, adg_g: 83, mortalityCum_pct: 2.76, feedDaily_g: 139, feedCum_g: 1581.5, fcr: 1.318, ip: 369 },
{ day: 25, bw_g: 1284, adg_g: 84, mortalityCum_pct: 2.88, feedDaily_g: 145, feedCum_g: 1726.5, fcr: 1.345, ip: 371 },
{ day: 26, bw_g: 1369, adg_g: 85, mortalityCum_pct: 3.00, feedDaily_g: 151, feedCum_g: 1877.5, fcr: 1.371, ip: 372 },
{ day: 27, bw_g: 1455, adg_g: 86, mortalityCum_pct: 3.12, feedDaily_g: 157, feedCum_g: 2034.5, fcr: 1.398, ip: 373 },
{ day: 28, bw_g: 1543, adg_g: 88, mortalityCum_pct: 3.25, feedDaily_g: 164, feedCum_g: 2198.5, fcr: 1.425, ip: 374 },
{ day: 29, bw_g: 1633, adg_g: 90, mortalityCum_pct: 3.38, feedDaily_g: 173, feedCum_g: 2371.5, fcr: 1.452, ip: 375 },
{ day: 30, bw_g: 1725, adg_g: 92, mortalityCum_pct: 3.52, feedDaily_g: 176.5, feedCum_g: 2548, fcr: 1.477, ip: 376 },
{ day: 31, bw_g: 1817, adg_g: 92, mortalityCum_pct: 3.66, feedDaily_g: 178, feedCum_g: 2726, fcr: 1.500, ip: 376 },
{ day: 32, bw_g: 1910, adg_g: 93, mortalityCum_pct: 3.80, feedDaily_g: 180, feedCum_g: 2906, fcr: 1.521, ip: 377 },
{ day: 33, bw_g: 2003, adg_g: 93, mortalityCum_pct: 3.95, feedDaily_g: 183, feedCum_g: 3089, fcr: 1.542, ip: 378 },
{ day: 34, bw_g: 2097, adg_g: 94, mortalityCum_pct: 4.10, feedDaily_g: 185, feedCum_g: 3274, fcr: 1.561, ip: 379 },
{ day: 35, bw_g: 2191, adg_g: 94, mortalityCum_pct: 4.25, feedDaily_g: 187, feedCum_g: 3461, fcr: 1.580, ip: 379 },
{ day: 36, bw_g: 2285, adg_g: 94, mortalityCum_pct: 4.45, feedDaily_g: 190, feedCum_g: 3651, fcr: 1.598, ip: 380 },
{ day: 37, bw_g: 2380, adg_g: 95, mortalityCum_pct: 4.65, feedDaily_g: 193, feedCum_g: 3844, fcr: 1.615, ip: 380 },
];
// ─── Target Suhu Pemeliharaan per Umur (Buku CP 707) ────────────────────────
const TEMPERATURE_STANDARD = [
{ ageDay_from: 1, ageDay_to: 2, temp_C: 32, humidity_pct_min: 50, humidity_pct_max: 70 },
{ ageDay_from: 3, ageDay_to: 4, temp_C: 31, humidity_pct_min: 50, humidity_pct_max: 70 },
{ ageDay_from: 5, ageDay_to: 7, temp_C: 30, humidity_pct_min: 50, humidity_pct_max: 70 },
{ ageDay_from: 8, ageDay_to: 14, temp_C: 29, humidity_pct_min: 50, humidity_pct_max: 70 },
{ ageDay_from: 15, ageDay_to: 21, temp_C: 28, humidity_pct_min: 50, humidity_pct_max: 70 },
{ ageDay_from: 22, ageDay_to: 28, temp_C: 26, humidity_pct_min: 50, humidity_pct_max: 70 },
{ ageDay_from: 29, ageDay_to: 35, temp_C: 23, humidity_pct_min: 50, humidity_pct_max: 70 },
{ ageDay_from: 36, ageDay_to: 99, temp_C: 22, humidity_pct_min: 50, humidity_pct_max: 70 },
];
// ─── Target Efektif Temperatur (TET) per Umur ───────────────────────────────
const TARGET_EFFECTIVE_TEMPERATURE = [
{ ageDay_from: 1, ageDay_to: 2, tet_C: 32 },
{ ageDay_from: 3, ageDay_to: 4, tet_C: 31 },
{ ageDay_from: 5, ageDay_to: 7, tet_C: 30 },
{ ageDay_from: 8, ageDay_to: 14, tet_C: 29 },
{ ageDay_from: 15, ageDay_to: 21, tet_C: 27 },
{ ageDay_from: 22, ageDay_to: 28, tet_C: 25 },
{ ageDay_from: 29, ageDay_to: 35, tet_C: 22 },
{ ageDay_from: 36, ageDay_to: 99, tet_C: 21 },
];
// ─── Standar Kualitas Udara (Lampiran 3) ────────────────────────────────────
const AIR_QUALITY_STANDARD = {
ammonia: {
ideal_pct: '<10 ppm',
warning: 10, // >10 ppm: merusak permukaan paru-paru
critical: 25, // >25 ppm: pertumbuhan menurun
severe: 50, // >50 ppm: pertumbuhan menurun signifikan
note: '>20 ppm lebih rentan terhadap penyakit pernapasan'
},
co2: {
ideal: '<3000 ppm',
critical: 3500, // >3500 ppm: ascites dan kematian tinggi
},
co: {
ideal: '10 ppm',
warning: 50, // >50 ppm mempengaruhi kesehatan
critical: 100, // 100 ppm: meningkatkan angka kematian
},
humidity: {
ideal_after_brooding: '50-60%',
warning_high: 70, // >70% pada suhu >29°C berpengaruh pada pertumbuhan
warning_low: 50, // RH <50% selama brooding berpengaruh pada pertumbuhan
}
};
// ─── Standar Mortalitas CP 707 ───────────────────────────────────────────────
const MORTALITY_THRESHOLDS = {
normal_pct: 5, // <5% mortalitas dianggap normal
warning_pct: 7, // 5-7% perlu perhatian
critical_pct: 7, // >7% kritis
// Standar kumulatif per umur (dari tabel harian lampiran 2)
byDayStandard: PERFORMANCE_STANDARD_DAILY.map(d => ({
day: d.day,
mortalityCumStd_pct: d.mortalityCum_pct
}))
};
// ─── Standar FCR per Umur (dari buku) ───────────────────────────────────────
function getFcrStandardByDay(dayAge) {
const std = PERFORMANCE_STANDARD_DAILY.find(d => d.day === dayAge);
if (std) return std.fcr;
// Estimasi untuk umur di luar tabel
if (dayAge > 37) return 1.65;
return null;
}
// ─── Standar Berat Badan per Umur ────────────────────────────────────────────
function getBwStandardByDay(dayAge) {
const std = PERFORMANCE_STANDARD_DAILY.find(d => d.day === dayAge);
if (std) return std.bw_g;
if (dayAge > 37) return 2500;
return null;
}
// ─── Standar Suhu per Umur ────────────────────────────────────────────────────
function getTempStandardByDay(dayAge) {
const std = TEMPERATURE_STANDARD.find(s => dayAge >= s.ageDay_from && dayAge <= s.ageDay_to);
return std || TEMPERATURE_STANDARD[TEMPERATURE_STANDARD.length - 1];
}
// ─── Standar TET per Umur ────────────────────────────────────────────────────
function getTetByDay(dayAge) {
const std = TARGET_EFFECTIVE_TEMPERATURE.find(s => dayAge >= s.ageDay_from && dayAge <= s.ageDay_to);
return std ? std.tet_C : 21;
}
// ─── Standar Mortalitas Kumulatif per Hari ───────────────────────────────────
function getMortalityCumStdByDay(dayAge) {
const std = PERFORMANCE_STANDARD_DAILY.find(d => d.day === dayAge);
if (std) return std.mortalityCum_pct;
if (dayAge > 37) return 4.65 + ((dayAge - 37) * 0.1);
return null;
}
// ─── Kepadatan Kandang (Buku CP 707) ─────────────────────────────────────────
const DENSITY_STANDARD = {
openHouse: {
minKgPerM2: 12,
maxKgPerM2: 13,
description: 'Kandang terbuka dengan ventilasi alami'
},
closedHouse: {
minKgPerM2: 24,
maxKgPerM2: 30,
description: 'Kandang tertutup dapat mencapai 24-30 kg/m2'
},
byHarvestWeight: [
{ minBW_kg: 0.80, maxBW_kg: 0.99, density_ekorPerM2_min: 11.0, density_ekorPerM2_max: 11.1 },
{ minBW_kg: 1.00, maxBW_kg: 1.19, density_ekorPerM2_min: 10.0, density_ekorPerM2_max: 10.5 },
{ minBW_kg: 1.20, maxBW_kg: 1.39, density_ekorPerM2_min: 9.0, density_ekorPerM2_max: 9.5 },
{ minBW_kg: 1.40, maxBW_kg: 1.59, density_ekorPerM2_min: 8.0, density_ekorPerM2_max: 8.5 },
{ minBW_kg: 1.60, maxBW_kg: 1.89, density_ekorPerM2_min: 7.5, density_ekorPerM2_max: 8.0 },
{ minBW_kg: 1.90, maxBW_kg: 99, density_ekorPerM2_min: 7.0, density_ekorPerM2_max: 7.5 },
]
};
// ─── Konsumsi Air per 1000 ekor per hari (suhu 21°C) ─────────────────────────
const WATER_CONSUMPTION_STANDARD = [
{ week: 1, minLiter: 58, maxLiter: 65 },
{ week: 2, minLiter: 102, maxLiter: 115 },
{ week: 3, minLiter: 149, maxLiter: 167 },
{ week: 4, minLiter: 192, maxLiter: 216 },
{ week: 5, minLiter: 232, maxLiter: 261 },
{ week: 6, minLiter: 274, maxLiter: 308 },
{ week: 7, minLiter: 309, maxLiter: 347 },
{ week: 8, minLiter: 342, maxLiter: 385 },
];
// Catatan: Di atas 21°C, kebutuhan air meningkat rata-rata 6.5% per kenaikan 1°C
const WATER_INCREASE_PER_DEGREE_ABOVE_21C_PCT = 6.5;
// ─── Program Pencahayaan CP 707 ───────────────────────────────────────────────
const LIGHTING_PROGRAM = [
{ ageDay_from: 2, ageDay_to: 7, onHours: 23, darkFrom: '20:00', darkTo: '21:00' },
{ ageDay_from: 8, ageDay_to: 14, onHours: 22, darkFrom: '20:00', darkTo: '22:00' },
{ ageDay_from: 15, ageDay_to: 20, onHours: 20, darkFrom: '20:00', darkTo: '23:00' },
{ ageDay_from: 21, ageDay_to: 28, onHours: 20, darkFrom: '20:00', darkTo: '24:00' },
{ ageDay_from: 29, ageDay_to: 99, onHours: 23, darkFrom: '20:00', darkTo: '22:00' },
];
const LIGHTING_MIN_INTENSITY_LUX = 25;
const LIGHTING_BROODING_OPTIMAL_LUX = '40-60';
const LIGHTING_AFTER_15DAYS_LUX = 5;
// ─── Analisis FCR vs Standar CP 707 ──────────────────────────────────────────
function analyzeFcr(actualFcr, dayAge) {
const stdFcr = getFcrStandardByDay(dayAge);
if (!stdFcr) return { status: 'unknown', deviation: null, message: 'Umur di luar standar tabel CP 707.' };
const deviation = ((actualFcr - stdFcr) / stdFcr * 100);
let status = 'ok';
let message = '';
if (deviation > 10) {
status = 'critical';
message = `FCR ${actualFcr.toFixed(2)} melebihi standar CP 707 (${stdFcr.toFixed(3)}) sebesar ${deviation.toFixed(1)}% pada umur hari ke-${dayAge}. Periksa potensi pakan tercecer dan kualitas pakan.`;
} else if (deviation > 5) {
status = 'warning';
message = `FCR ${actualFcr.toFixed(2)} sedikit di atas standar CP 707 (${stdFcr.toFixed(3)}) pada umur hari ke-${dayAge}. Atur ketinggian piringan pakan dan evaluasi fines dalam pakan.`;
} else if (deviation < -5) {
status = 'ok'; // FCR lebih baik dari standar
message = `FCR ${actualFcr.toFixed(2)} lebih baik dari standar CP 707 (${stdFcr.toFixed(3)}) pada umur hari ke-${dayAge}. Pertahankan manajemen pakan.`;
} else {
status = 'ok';
message = `FCR ${actualFcr.toFixed(2)} sesuai standar CP 707 (${stdFcr.toFixed(3)}) pada umur hari ke-${dayAge}.`;
}
return { status, deviation: deviation.toFixed(1), stdFcr, message };
}
// ─── Analisis Berat Badan vs Standar CP 707 ──────────────────────────────────
function analyzeBw(actualBw_g, dayAge) {
const stdBw = getBwStandardByDay(dayAge);
if (!stdBw) return { status: 'unknown', deviation: null, message: 'Umur di luar standar tabel CP 707.' };
const deviation = ((actualBw_g - stdBw) / stdBw * 100);
let status = 'ok';
let message = '';
if (deviation < -15) {
status = 'critical';
message = `Bobot badan aktual ${actualBw_g}g jauh di bawah standar CP 707 (${stdBw}g) pada hari ke-${dayAge}. Deviasi ${Math.abs(deviation).toFixed(1)}%. Lakukan grading segera.`;
} else if (deviation < -5) {
status = 'warning';
message = `Bobot badan aktual ${actualBw_g}g sedikit di bawah standar CP 707 (${stdBw}g) pada hari ke-${dayAge}. Deviasi ${Math.abs(deviation).toFixed(1)}%. Tingkatkan stimulasi pakan.`;
} else if (deviation > 10) {
status = 'ok';
message = `Bobot badan aktual ${actualBw_g}g melampaui standar CP 707 (${stdBw}g) pada hari ke-${dayAge}. Pertumbuhan sangat baik.`;
} else {
status = 'ok';
message = `Bobot badan aktual ${actualBw_g}g sesuai standar CP 707 (${stdBw}g) pada hari ke-${dayAge}.`;
}
return { status, deviation: deviation.toFixed(1), stdBw, message };
}
// ─── Analisis Mortalitas vs Standar CP 707 ───────────────────────────────────
function analyzeMortality(mortalityRate_pct, dayAge) {
const stdMortality = getMortalityCumStdByDay(dayAge);
let status = 'ok';
let message = '';
if (mortalityRate_pct > MORTALITY_THRESHOLDS.critical_pct) {
status = 'critical';
message = `Mortalitas kumulatif ${mortalityRate_pct.toFixed(2)}% melebihi batas kritis CP 707 (>7%). Lakukan nekropsi darurat dan perketat biosekuriti.`;
} else if (mortalityRate_pct >= MORTALITY_THRESHOLDS.warning_pct) {
status = 'warning';
message = `Mortalitas kumulatif ${mortalityRate_pct.toFixed(2)}% perlu diwaspadai. Standar CP 707 <5%.`;
} else if (stdMortality && mortalityRate_pct > stdMortality * 1.5) {
status = 'warning';
message = `Mortalitas ${mortalityRate_pct.toFixed(2)}% melebihi standar kumulatif harian CP 707 (${stdMortality.toFixed(2)}%) pada hari ke-${dayAge}.`;
} else {
status = 'ok';
message = `Mortalitas ${mortalityRate_pct.toFixed(2)}% dalam batas normal CP 707 (<5%).`;
}
return { status, stdMortality, message };
}
// ─── Analisis Suhu/Lingkungan vs Standar CP 707 ──────────────────────────────
function analyzeEnvironment(temp_C, humidity_pct, ammonia_ppm, dayAge) {
const tempStd = getTempStandardByDay(dayAge);
const tet = getTetByDay(dayAge);
const issues = [];
let overallStatus = 'ok';
// Cek suhu
if (temp_C > tempStd.temp_C + 4) {
issues.push(`Suhu ${temp_C.toFixed(1)}°C jauh di atas target CP 707 (${tempStd.temp_C}°C) untuk umur hari ke-${dayAge}. Nyalakan cooling pad/exhaust fan segera.`);
overallStatus = 'critical';
} else if (temp_C > tempStd.temp_C + 2) {
issues.push(`Suhu ${temp_C.toFixed(1)}°C di atas target CP 707 (${tempStd.temp_C}°C) untuk umur hari ke-${dayAge}. Tingkatkan ventilasi.`);
if (overallStatus !== 'critical') overallStatus = 'warning';
} else if (temp_C < tempStd.temp_C - 3) {
issues.push(`Suhu ${temp_C.toFixed(1)}°C di bawah target CP 707 (${tempStd.temp_C}°C). Nyalakan heater.`);
if (overallStatus !== 'critical') overallStatus = 'warning';
}
// Cek kelembapan
if (humidity_pct < tempStd.humidity_pct_min) {
issues.push(`Kelembapan ${humidity_pct.toFixed(1)}% di bawah standar CP 707 (${tempStd.humidity_pct_min}-${tempStd.humidity_pct_max}%).`);
if (overallStatus !== 'critical') overallStatus = 'warning';
} else if (humidity_pct > tempStd.humidity_pct_max) {
issues.push(`Kelembapan ${humidity_pct.toFixed(1)}% di atas standar CP 707 (${tempStd.humidity_pct_min}-${tempStd.humidity_pct_max}%). Periksa kebocoran nipple dan sekam basah.`);
if (overallStatus !== 'critical') overallStatus = 'warning';
}
// Cek amonia
if (ammonia_ppm > AIR_QUALITY_STANDARD.ammonia.critical) {
issues.push(`Amonia ${ammonia_ppm.toFixed(1)} ppm di atas batas kritis CP 707 (>25 ppm). Pertumbuhan ayam menurun. Tingkatkan ventilasi segera dan gemburkan sekam basah.`);
overallStatus = 'critical';
} else if (ammonia_ppm > AIR_QUALITY_STANDARD.ammonia.warning) {
issues.push(`Amonia ${ammonia_ppm.toFixed(1)} ppm melebihi batas aman CP 707 (<10 ppm). Tingkatkan sirkulasi udara.`);
if (overallStatus !== 'critical') overallStatus = 'warning';
}
return {
status: overallStatus,
issues,
tempStd,
tet,
message: issues.length > 0 ? issues.join(' ') : `Lingkungan kandang sesuai standar CP 707 untuk umur hari ke-${dayAge}.`
};
}
// ─── Generate Konteks Referensi Buku untuk Prompt ───────────────────────────
function buildBookReferenceContext(dayAge) {
const stdBw = getBwStandardByDay(dayAge);
const stdFcr = getFcrStandardByDay(dayAge);
const stdMortality = getMortalityCumStdByDay(dayAge);
const tempStd = getTempStandardByDay(dayAge);
const tet = getTetByDay(dayAge);
return `
=== REFERENSI STANDAR BUKU CP 707 (SUMBER TUNGGAL - PT CHAROEN POKPHAND INDONESIA) ===
Umur ayam hari ke-${dayAge}:
- Target bobot badan: ${stdBw || 'N/A'} gram
- Target FCR: ${stdFcr || 'N/A'}
- Target mortalitas kumulatif normal: <5% (standar CP 707)
- Target mortalitas kumulatif standar hari ke-${dayAge}: ${stdMortality ? stdMortality + '%' : 'N/A'}
- Target suhu kandang: ${tempStd.temp_C}°C
- Target kelembapan: ${tempStd.humidity_pct_min}%-${tempStd.humidity_pct_max}%
- Target Efektif Temperatur (TET): ${tet}°C
- Batas amonia aman: <10 ppm (ideal), >25 ppm = pertumbuhan menurun (dari Lampiran 3 CP 707)
- Batas CO2 aman: <3000 ppm (>3500 ppm = ascites & kematian tinggi)
- Konsumsi air normal: 2-2.5x konsumsi pakan
CATATAN PENTING:
- Analisis HANYA berdasarkan standar buku CP 707
- Jika ada data yang tidak ada di buku CP 707, nyatakan "data tidak tersedia di buku CP 707"
- Risiko yang disebutkan HARUS berdasarkan data aktual vs standar CP 707
=== END REFERENSI ===
`;
}
// ─── Analisis Komprehensif berbasis CP 707 ───────────────────────────────────
function analyzeWithCP707Standards(contextPack) {
const dayAge = contextPack?.cycle?.currentAgeDay ||
contextPack?.ageDay ||
contextPack?.umurHari ||
null;
const result = { dayAge, analyses: {} };
// Berat badan
const actualBw = contextPack?.weightStats?.averageWeight?.value ||
contextPack?.berat_rata_rata ||
null;
if (actualBw !== null && dayAge !== null) {
result.analyses.bw = analyzeBw(actualBw, dayAge);
}
// FCR
const actualFcr = contextPack?.fcr ||
contextPack?.fcr_terakhir ||
contextPack?.fcrSummary?.current ||
null;
if (actualFcr !== null && dayAge !== null) {
result.analyses.fcr = analyzeFcr(actualFcr, dayAge);
}
// Mortalitas
const mortalityRate = contextPack?.chickenCounting?.dashboardSummary?.mortalityRate ||
contextPack?.mortalityRate ||
null;
if (mortalityRate !== null) {
result.analyses.mortality = analyzeMortality(mortalityRate, dayAge);
}
// Lingkungan (IoT)
const iot = contextPack?.panel_iot || contextPack?.telemetry || contextPack?.iotData || {};
const temp = iot?.avgTemp || iot?.suhu_rata_rata_C || null;
const hum = iot?.humidity || iot?.kelembapan_persen || null;
const ammonia = iot?.ammonia || iot?.amonia_ppm || null;
if (temp !== null && dayAge !== null) {
result.analyses.environment = analyzeEnvironment(
temp,
hum || 65,
ammonia || 0,
dayAge
);
}
return result;
}
module.exports = {
PERFORMANCE_STANDARD_WEEKLY,
PERFORMANCE_STANDARD_DAILY,
TEMPERATURE_STANDARD,
TARGET_EFFECTIVE_TEMPERATURE,
AIR_QUALITY_STANDARD,
MORTALITY_THRESHOLDS,
DENSITY_STANDARD,
WATER_CONSUMPTION_STANDARD,
LIGHTING_PROGRAM,
getFcrStandardByDay,
getBwStandardByDay,
getTempStandardByDay,
getTetByDay,
getMortalityCumStdByDay,
analyzeFcr,
analyzeBw,
analyzeMortality,
analyzeEnvironment,
analyzeWithCP707Standards,
buildBookReferenceContext,
};