feat: add asset-specific analysis functions for conveyors and vehicles to calculate various performance and operational metrics.
This commit is contained in:
@@ -474,17 +474,32 @@ export const analyzeStorage = (storage: any, materials: any[]) => {
|
||||
};
|
||||
};
|
||||
|
||||
// Humans analysis update
|
||||
export const analyzeHuman = (human: any, materials: any[]) => {
|
||||
// Simplified for brevity, but logically complete
|
||||
const assetId = human.modelUuid;
|
||||
const errorCount = errorCounts[assetId] || 0;
|
||||
const timeMetrics = calculateAdvancedTimeMetrics(human.idleTime || 0, human.activeTime || 0, assetId, errorCount);
|
||||
const actionsCompleted = completedActions[assetId] || 0;
|
||||
const distanceTraveled = human.distanceTraveled || 0;
|
||||
const currentLoad = human.currentLoad || 0;
|
||||
const loadCapacity = human.point?.actions?.[0]?.loadCapacity || 1;
|
||||
const loadCapacity = human.point?.action?.loadCapacity || human.point?.actions?.[0]?.loadCapacity || 1;
|
||||
const loadUtilization = (currentLoad / loadCapacity) * 100;
|
||||
|
||||
const workerActions = completedActions[`${assetId}_worker`] || 0;
|
||||
const manufacturerActions = completedActions[`${assetId}_manufacturer`] || 0;
|
||||
const operatorActions = completedActions[`${assetId}_operator`] || 0;
|
||||
const assemblerActions = completedActions[`${assetId}_assembler`] || 0;
|
||||
const totalRecordedActions = workerActions + manufacturerActions + operatorActions + assemblerActions || 1;
|
||||
|
||||
const workloadDistribution = [
|
||||
{ actionType: "Worker", count: workerActions, percentage: (workerActions / totalRecordedActions) * 100 },
|
||||
{ actionType: "Manufacturer", count: manufacturerActions, percentage: (manufacturerActions / totalRecordedActions) * 100 },
|
||||
{ actionType: "Operator", count: operatorActions, percentage: (operatorActions / totalRecordedActions) * 100 },
|
||||
{ actionType: "Assembler", count: assemblerActions, percentage: (assemblerActions / totalRecordedActions) * 100 },
|
||||
].filter((w) => w.count > 0);
|
||||
|
||||
const workloadSummary = workloadDistribution.map((d) => `${d.actionType}: ${Math.round(d.percentage)}%`).join(" | ") || "0%";
|
||||
|
||||
const idealActionsPerHour = PERFORMANCE_BENCHMARKS.HUMAN_IDEAL_ACTIONS_PER_HOUR;
|
||||
const actualActionsPerHour = timeMetrics.totalTime > 0 ? (actionsCompleted / timeMetrics.totalTime) * 3600 : 0;
|
||||
const performanceRate = Math.min((actualActionsPerHour / idealActionsPerHour) * 100, 100);
|
||||
@@ -533,8 +548,8 @@ export const analyzeHuman = (human: any, materials: any[]) => {
|
||||
averageSpeed: timeMetrics.totalTime > 0 ? distanceTraveled / timeMetrics.totalTime : 0,
|
||||
loadEfficiency: loadUtilization,
|
||||
},
|
||||
workloadDistribution: [], // Skipped detail implementation for brevity
|
||||
workloadSummary: "0%",
|
||||
workloadDistribution,
|
||||
workloadSummary,
|
||||
efficiency: {
|
||||
overallEffectiveness: calculateOEE(timeMetrics.uptime, performanceRate, qualityMetrics.firstPassYield),
|
||||
availability: timeMetrics.uptime,
|
||||
@@ -569,6 +584,15 @@ export const analyzeCrane = (crane: any, materials: any[]) => {
|
||||
const avgLiftHeight = totalLifts > 0 ? totalLiftHeight / totalLifts : 0;
|
||||
const avgLoadsPerCycle = cyclesCompleted > 0 ? loadsHandled / cyclesCompleted : 0;
|
||||
|
||||
// Success rates
|
||||
const liftAttempts = totalLifts + errorCount;
|
||||
const liftSuccessRate = liftAttempts > 0 ? (totalLifts / liftAttempts) * 100 : 100; // Use 100 as default if no attempts
|
||||
const positioningAccuracy = totalLifts > 0 ? Math.max(0, 100 - (errorCount / totalLifts) * 50) : 100; // Estimation based on error count
|
||||
|
||||
// Load utilization
|
||||
const maxPickUpCount = crane.point?.action?.maxPickUpCount || crane.point?.actions?.[0]?.maxPickUpCount || 1;
|
||||
const loadUtilization = (avgLoadsPerCycle / maxPickUpCount) * 100;
|
||||
|
||||
const costMetrics = calculateCostMetrics(assetId, "crane", crane.activeTime || 0, loadsHandled);
|
||||
const energyMetrics = calculateEnergyMetrics("crane", crane.activeTime || 0);
|
||||
|
||||
@@ -600,6 +624,7 @@ export const analyzeCrane = (crane: any, materials: any[]) => {
|
||||
currentLoad: crane.currentLoad,
|
||||
currentMaterials: crane.currentMaterials,
|
||||
currentAction: crane.currentAction || null,
|
||||
loadUtilization,
|
||||
},
|
||||
timeMetrics: { ...timeMetrics, idleTime: crane.idleTime, activeTime: crane.activeTime, averageCycleTime: actualCycleTime },
|
||||
throughput: {
|
||||
@@ -614,16 +639,16 @@ export const analyzeCrane = (crane: any, materials: any[]) => {
|
||||
wip: crane.currentLoad,
|
||||
bottleneckIndex: timeMetrics.utilizationRate > ANALYSIS_SETTINGS.BOTTLENECK_UTILIZATION_THRESHOLD ? 1 : 0,
|
||||
},
|
||||
movementMetrics: { totalLifts, averageLiftHeight: avgLiftHeight, movementEfficiency: 0, loadEfficiency: 0, cycleEfficiency: performance.timeEfficiency },
|
||||
movementMetrics: { totalLifts, averageLiftHeight: avgLiftHeight, movementEfficiency: liftSuccessRate, loadEfficiency: loadUtilization, cycleEfficiency: performance.timeEfficiency },
|
||||
efficiency: {
|
||||
overallEffectiveness: calculateOEE(timeMetrics.uptime, performance.performanceRate, qualityMetrics.firstPassYield),
|
||||
availability: timeMetrics.uptime,
|
||||
performance: performance.performanceRate,
|
||||
quality: qualityMetrics.firstPassYield,
|
||||
loadUtilization: 0,
|
||||
loadUtilization,
|
||||
cycleTimeEfficiency: performance.timeEfficiency,
|
||||
},
|
||||
quality: qualityMetrics,
|
||||
quality: { ...qualityMetrics, liftSuccessRate, positioningAccuracy },
|
||||
costMetrics: { ...costMetrics, costPerLift: totalLifts > 0 ? costMetrics.totalCost / totalLifts : 0, costPerCycle: cyclesCompleted > 0 ? costMetrics.totalCost / cyclesCompleted : 0 },
|
||||
energyMetrics: { ...energyMetrics, energyPerLift: totalLifts > 0 ? energyMetrics.energyConsumed / totalLifts : 0 },
|
||||
historicalData: historicalData[assetId] || [],
|
||||
|
||||
Reference in New Issue
Block a user