Files
dashboard/mockData/feedSchedulingData.ts

94 lines
3.2 KiB
TypeScript

import {
FeedScheduleRecommendation,
FeedingEvent,
ConsumptionPatternPoint,
ScheduleInfluencingFactors,
} from '../types';
import { initialUsers, initialRoles } from './accessManagementData.ts';
const operatorRoleId = initialRoles.find((r) => r.name === 'Operator')?.id;
const operators = operatorRoleId ? initialUsers.filter((u) => u.roleId === operatorRoleId) : [];
export const initialFeedSchedule: FeedScheduleRecommendation = {
nextFeedingTime: new Date(Date.now() + 2 * 60 * 60 * 1000), // in 2 hours
lastFeedingTime: new Date(Date.now() - 3 * 60 * 60 * 1000), // 3 hours ago
reason: 'Jadwal dimundurkan untuk menghindari stres panas akibat suhu tinggi pada siang hari.',
};
export const initialFeedingEvents: FeedingEvent[] = (() => {
const events: FeedingEvent[] = [];
const now = new Date();
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
for (let day = 0; day < 30; day++) {
const currentDate = new Date(startOfMonth);
currentDate.setDate(startOfMonth.getDate() + day);
// Add 4 feeding events per day at different times
const feedingTimes = [8, 12, 16, 20];
feedingTimes.forEach((hour, index) => {
const eventTime = new Date(currentDate);
eventTime.setHours(hour, 0, 0, 0);
if (eventTime > new Date(now.getTime() + 3 * 24 * 60 * 60 * 1000)) {
return; // Don't generate events too far in the future
}
let status: 'completed' | 'upcoming' | 'skipped' = 'upcoming';
if (eventTime < now) {
status = Math.random() < 0.05 ? 'skipped' : 'completed';
}
const type: 'AI Recommended' | 'Manual' = Math.random() < 0.3 ? 'AI Recommended' : 'Manual';
const operator = operators[Math.floor(Math.random() * operators.length)] ?? {
id: 'user-3',
name: 'Siti Aminah',
};
const quantityKg = 250 + Math.floor(Math.random() * 100);
events.push({
id: `event-${day}-${index}`,
time: eventTime,
type: status === 'skipped' ? 'Skipped' : type,
status,
operatorId: operator.id,
operatorName: operator.name,
feedType: 'CP 511 Bravo',
quantityKg: quantityKg,
quantitySacks: Math.round(quantityKg / 50),
});
});
}
// Ensure the next upcoming event matches the recommendation
const nextUpcoming = events.find((e) => e.status === 'upcoming');
if (nextUpcoming) {
nextUpcoming.time = initialFeedSchedule.nextFeedingTime;
nextUpcoming.type = 'AI Recommended';
}
return events;
})();
export const initialConsumptionPattern: ConsumptionPatternPoint[] = Array.from(
{ length: 24 },
(_, i) => {
const isFeedingHour = [8, 12, 16, 20].includes(i);
const predicted = 1 + Math.sin((i - 6) / 4) * 3 + (isFeedingHour ? 5 : 0) + Math.random();
const actual = i < new Date().getHours() ? predicted - 0.5 + Math.random() * 1.5 : null;
return {
hour: i,
predicted: Math.max(0, predicted),
actual: actual ? Math.max(0, actual) : null,
};
}
);
export const initialScheduleFactors: ScheduleInfluencingFactors = {
temperature: { value: 31.8, unit: '°C', status: 'warning' },
humidity: { value: 78, unit: '%', status: 'warning' },
activityLevel: { value: 65, unit: '%', status: 'ok' },
};