109 lines
3.4 KiB
TypeScript
109 lines
3.4 KiB
TypeScript
import {
|
|
BehaviorMetrics,
|
|
BehaviorDataPoint,
|
|
BehaviorAnomaly,
|
|
AnomalyType,
|
|
AnomalySeverity,
|
|
} from '../types';
|
|
import { cycleData } from './cycleData.ts';
|
|
|
|
export const initialBehaviorMetrics: BehaviorMetrics = {
|
|
activityIndex: 78,
|
|
stressLevel: { value: 22, status: 'warning' },
|
|
eatingPattern: { value: 91, status: 'warning' },
|
|
drinkingPattern: { value: 94, status: 'ok' },
|
|
};
|
|
|
|
const generateBehaviorHistory = (): BehaviorDataPoint[] => {
|
|
// FIX: `cycleData` is an array. Find the active cycle to get its properties.
|
|
const activeCycle = cycleData.find((c) => c.status === 'Active') || cycleData[0];
|
|
if (!activeCycle) return [];
|
|
|
|
const { startDate, currentDay } = activeCycle;
|
|
const history: BehaviorDataPoint[] = [];
|
|
|
|
for (let day = 0; day < currentDay; day++) {
|
|
for (let hour = 0; hour < 24; hour++) {
|
|
const timestamp = new Date(startDate);
|
|
timestamp.setDate(startDate.getDate() + day);
|
|
timestamp.setHours(hour, 0, 0, 0);
|
|
|
|
const dayHour = timestamp.getHours();
|
|
// Simple diurnal pattern
|
|
const baseActivity = dayHour > 7 && dayHour < 20 ? 60 : 20;
|
|
const activity = baseActivity + Math.sin((dayHour - 7) / 2) * 15 + Math.random() * 10;
|
|
|
|
const baseStress = activity > 50 ? 15 : 10;
|
|
const stress = baseStress + Math.random() * 15;
|
|
|
|
history.push({
|
|
timestamp,
|
|
activity: Math.min(100, Math.max(0, activity)),
|
|
stress: Math.min(100, Math.max(0, stress)),
|
|
});
|
|
}
|
|
}
|
|
return history;
|
|
};
|
|
|
|
export const initialBehaviorHistory: BehaviorDataPoint[] = generateBehaviorHistory();
|
|
|
|
export const initialBehaviorAnomalies: BehaviorAnomaly[] = [
|
|
{
|
|
id: 'ba1',
|
|
type: AnomalyType.AGGRESSION,
|
|
severity: AnomalySeverity.CRITICAL,
|
|
location: 'Kandang C / Lt 2',
|
|
timestamp: new Date(Date.now() - 5 * 60 * 1000),
|
|
details: 'Perkelahian masal terdeteksi di dekat jalur pakan.',
|
|
},
|
|
{
|
|
id: 'ba2',
|
|
type: AnomalyType.ISOLATION,
|
|
severity: AnomalySeverity.WARNING,
|
|
location: 'Kandang A / Lt 1',
|
|
timestamp: new Date(Date.now() - 35 * 60 * 1000),
|
|
details: 'Beberapa ayam mengisolasi diri di sudut.',
|
|
},
|
|
{
|
|
id: 'ba3',
|
|
type: AnomalyType.PANIC,
|
|
severity: AnomalySeverity.CRITICAL,
|
|
location: 'Kandang K-01',
|
|
timestamp: new Date(Date.now() - 2 * 60 * 60 * 1000),
|
|
details: 'Terdeteksi kepanikan masal, kemungkinan ada predator.',
|
|
},
|
|
{
|
|
id: 'ba4',
|
|
type: AnomalyType.REDUCED_MOBILITY,
|
|
severity: AnomalySeverity.WARNING,
|
|
location: 'Kandang B / Lt 1',
|
|
timestamp: new Date(Date.now() - 4 * 60 * 60 * 1000),
|
|
details: 'Tingkat mobilitas umum menurun di bawah ambang batas.',
|
|
},
|
|
{
|
|
id: 'ba5',
|
|
type: AnomalyType.AGGRESSION,
|
|
severity: AnomalySeverity.WARNING,
|
|
location: 'Kandang C / Lt 1',
|
|
timestamp: new Date(Date.now() - 6 * 60 * 60 * 1000),
|
|
details: 'Agresi minor terdeteksi di area minum.',
|
|
},
|
|
{
|
|
id: 'ba6',
|
|
type: AnomalyType.ISOLATION,
|
|
severity: AnomalySeverity.WARNING,
|
|
location: 'Kandang K-02',
|
|
timestamp: new Date(Date.now() - 7 * 60 * 60 * 1000),
|
|
details: 'Satu ayam terisolasi di dekat dinding selama >1 jam.',
|
|
},
|
|
{
|
|
id: 'ba7',
|
|
type: AnomalyType.REDUCED_MOBILITY,
|
|
severity: AnomalySeverity.CRITICAL,
|
|
location: 'Kandang Percobaan',
|
|
timestamp: new Date(Date.now() - 9 * 60 * 60 * 1000),
|
|
details: 'Mobilitas keseluruhan turun 40% dalam 2 jam terakhir.',
|
|
},
|
|
];
|