432 lines
23 KiB
JavaScript
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,
|
|
};
|