feat: Add core simulation module with detailed type definitions, dashboard editor, and analysis components.
This commit is contained in:
@@ -235,11 +235,13 @@ const ElementEditor: React.FC<ElementEditorProps> = ({
|
|||||||
const getAssetDropdownItems = useCallback(() => {
|
const getAssetDropdownItems = useCallback(() => {
|
||||||
if (!product?.eventDatas) return [];
|
if (!product?.eventDatas) return [];
|
||||||
|
|
||||||
return product.eventDatas.map((asset) => ({
|
const assetItems = product.eventDatas.map((asset) => ({
|
||||||
id: asset.modelUuid,
|
id: asset.modelUuid,
|
||||||
label: asset.modelName,
|
label: asset.modelName,
|
||||||
icon: <DeviceIcon />,
|
icon: <DeviceIcon />,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
return [{ id: "global", label: "Global System", icon: <DeviceIcon /> }, ...assetItems];
|
||||||
}, [product?.eventDatas]);
|
}, [product?.eventDatas]);
|
||||||
|
|
||||||
const getLableValueDropdownItems = useCallback(
|
const getLableValueDropdownItems = useCallback(
|
||||||
@@ -258,6 +260,41 @@ const ElementEditor: React.FC<ElementEditorProps> = ({
|
|||||||
{ id: "global.materialFlow.averageResidenceTime", label: "Average Residence Time", icon: <ParametersIcon /> },
|
{ id: "global.materialFlow.averageResidenceTime", label: "Average Residence Time", icon: <ParametersIcon /> },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: "Financial Metrics",
|
||||||
|
items: [
|
||||||
|
{ id: "global.advancedAnalytics.financials.totalRevenue", label: "Total Revenue", icon: <ParametersIcon /> },
|
||||||
|
{ id: "global.advancedAnalytics.financials.grossProfit", label: "Gross Profit", icon: <ParametersIcon /> },
|
||||||
|
{ id: "global.advancedAnalytics.financials.netProfitMargin", label: "Net Profit Margin", icon: <ParametersIcon /> },
|
||||||
|
{ id: "global.advancedAnalytics.financials.burnRate", label: "Burn Rate", icon: <ParametersIcon /> },
|
||||||
|
{ id: "global.advancedAnalytics.financials.breakEvenUnits", label: "Break-even Units", icon: <ParametersIcon /> },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Supply Chain Metrics",
|
||||||
|
items: [
|
||||||
|
{ id: "global.advancedAnalytics.supplyChain.totalInventoryValue", label: "Inventory Value", icon: <ParametersIcon /> },
|
||||||
|
{ id: "global.advancedAnalytics.supplyChain.inventoryTurnoverRate", label: "Turnover Rate", icon: <ParametersIcon /> },
|
||||||
|
{ id: "global.advancedAnalytics.supplyChain.stockoutRisk", label: "Stockout Risk", icon: <ParametersIcon /> },
|
||||||
|
{ id: "global.advancedAnalytics.supplyChain.scrapValue", label: "Scrap Value", icon: <ParametersIcon /> },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Sustainability Metrics",
|
||||||
|
items: [
|
||||||
|
{ id: "global.advancedAnalytics.sustainability.totalCarbonFootprint", label: "Carbon Footprint", icon: <ParametersIcon /> },
|
||||||
|
{ id: "global.advancedAnalytics.sustainability.energyIntensity", label: "Energy Intensity", icon: <ParametersIcon /> },
|
||||||
|
{ id: "global.advancedAnalytics.sustainability.ecoEfficiencyScore", label: "Eco Efficiency Score", icon: <ParametersIcon /> },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Reliability Metrics",
|
||||||
|
items: [
|
||||||
|
{ id: "global.advancedAnalytics.reliability.systemMTBF", label: "System MTBF", icon: <ParametersIcon /> },
|
||||||
|
{ id: "global.advancedAnalytics.reliability.systemMTTR", label: "System MTTR", icon: <ParametersIcon /> },
|
||||||
|
{ id: "global.advancedAnalytics.reliability.systemAvailability", label: "System Availability", icon: <ParametersIcon /> },
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: "Critical System Metrics",
|
title: "Critical System Metrics",
|
||||||
items: [
|
items: [
|
||||||
|
|||||||
@@ -2134,6 +2134,101 @@ function Analyzer() {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Advanced Analytics Calculations
|
||||||
|
const calculateAdvancedAnalytics = (): AdvancedAnalytics => {
|
||||||
|
// Financials
|
||||||
|
// Assume average revenue per completed item is $150 (since cost is ~10-100 range)
|
||||||
|
const revenuePerUnit = 150;
|
||||||
|
const totalRevenue = completedMaterials * revenuePerUnit;
|
||||||
|
const grossProfit = totalRevenue - totalCost;
|
||||||
|
const netProfitMargin = totalRevenue > 0 ? (grossProfit / totalRevenue) * 100 : 0;
|
||||||
|
|
||||||
|
// Categorize costs
|
||||||
|
const laborCost = allAssets.filter((a) => a.assetType === "human").reduce((sum, a) => sum + (a.costMetrics?.totalCost || 0), 0);
|
||||||
|
const energyCosts = allAssets.reduce((sum, a) => sum + (a.energyMetrics?.energyCost || 0), 0);
|
||||||
|
const maintenanceCosts = allAssets.reduce((sum, a) => sum + (a.costMetrics?.maintenanceCost || 0), 0);
|
||||||
|
|
||||||
|
// Fixed vs Variable (Assumption: 40% fixed, 60% variable)
|
||||||
|
const fixedCosts = totalCost * 0.4;
|
||||||
|
const variableCosts = totalCost * 0.6;
|
||||||
|
const breakEvenUnits = revenuePerUnit > variableCosts / Math.max(1, completedMaterials) ? fixedCosts / (revenuePerUnit - variableCosts / Math.max(1, completedMaterials)) : 0;
|
||||||
|
|
||||||
|
// Burn Rate
|
||||||
|
const analysisDurationHours = (Date.now() - new Date(startTimeRef.current).getTime()) / 3600000;
|
||||||
|
const burnRate = analysisDurationHours > 0 ? totalCost / analysisDurationHours : 0;
|
||||||
|
|
||||||
|
const financials: FinancialMetrics = {
|
||||||
|
totalRevenue,
|
||||||
|
grossProfit,
|
||||||
|
netProfitMargin,
|
||||||
|
burnRate,
|
||||||
|
laborCostRatio: totalCost > 0 ? laborCost / totalCost : 0,
|
||||||
|
energyCostRatio: totalCost > 0 ? energyCosts / totalCost : 0,
|
||||||
|
maintenanceCostRatio: totalCost > 0 ? maintenanceCosts / totalCost : 0,
|
||||||
|
breakEvenUnits,
|
||||||
|
fixedCosts,
|
||||||
|
variableCosts,
|
||||||
|
revenuePerUnit,
|
||||||
|
costPerUnit: completedMaterials > 0 ? totalCost / completedMaterials : 0,
|
||||||
|
profitPerUnit: completedMaterials > 0 ? grossProfit / completedMaterials : 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Supply Chain
|
||||||
|
// Assign values to materials
|
||||||
|
const avgMaterialValue = 25;
|
||||||
|
const totalInventoryValue = totalMaterialsInSystem * avgMaterialValue;
|
||||||
|
const inventoryTurnoverRate = totalInventoryValue > 0 ? (totalCost * 0.6) / totalInventoryValue : 0; // standard formula COGS/AvgInv
|
||||||
|
const holdingCostRate = 0.25; // 25% annual holding cost
|
||||||
|
const holdingCost = ((totalInventoryValue * holdingCostRate) / (365 * 24)) * analysisDurationHours; // prorated
|
||||||
|
|
||||||
|
// Scrap value
|
||||||
|
const totalScrap = allAssets.reduce((sum, a) => sum + (a.quality?.scrapRate || 0), 0);
|
||||||
|
const scrapValue = totalScrap * (avgMaterialValue * 0.1); // 10% recovery
|
||||||
|
|
||||||
|
const supplyChain: SupplyChainMetrics = {
|
||||||
|
totalInventoryValue,
|
||||||
|
inventoryTurnoverRate,
|
||||||
|
averageLeadTime: averageResidenceTime / 1000, // seconds
|
||||||
|
holdingCost,
|
||||||
|
stockoutRisk: bottlenecks.some((b) => b.severity === "critical") ? 0.8 : 0.2, // Simulated based on bottlenecks
|
||||||
|
supplierDependence: 0.45, // Constant simulation factor
|
||||||
|
materialUtilization: completedMaterials > 0 ? (completedMaterials / (completedMaterials + totalScrap)) * 100 : 100,
|
||||||
|
scrapValue,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sustainability
|
||||||
|
// CO2 factors
|
||||||
|
const totalWaste = totalScrap * 5; // 5kg per scrap unit (simulated)
|
||||||
|
const wasteGenerationRate = analysisDurationHours > 0 ? totalWaste / analysisDurationHours : 0;
|
||||||
|
|
||||||
|
const sustainability: SustainabilityMetrics = {
|
||||||
|
totalCarbonFootprint: totalEnergyConsumed * 0.5, // 0.5 kg/kWh
|
||||||
|
energyIntensity: completedMaterials > 0 ? totalEnergyConsumed / completedMaterials : 0,
|
||||||
|
carbonIntensity: completedMaterials > 0 ? (totalEnergyConsumed * 0.5) / completedMaterials : 0,
|
||||||
|
wasteGenerationRate,
|
||||||
|
recyclableRatio: 0.3, // 30% recyclable (simulated)
|
||||||
|
waterUsage: completedMaterials * 10, // 10L per unit (simulated)
|
||||||
|
ecoEfficiencyScore: Math.min(100, Math.max(0, 80 - totalEnergyConsumed * 0.1 + completedMaterials * 0.5)),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Reliability
|
||||||
|
const totalFailures = assetsInError + allAssets.reduce((sum, a) => sum + (errorCountsRef.current[a.assetId] || 0), 0);
|
||||||
|
const systemMTBF = totalFailures > 0 ? totalSystemTime / totalFailures : totalSystemTime;
|
||||||
|
const systemMTTR = totalFailures > 0 ? totalIdleTime / totalFailures : 0;
|
||||||
|
|
||||||
|
const reliability: ReliabilityMetrics = {
|
||||||
|
systemMTBF: systemMTBF / 3600, // hours
|
||||||
|
systemMTTR: systemMTTR / 3600, // hours
|
||||||
|
systemAvailability: systemUptime,
|
||||||
|
failureFrequency: analysisDurationHours > 0 ? totalFailures / analysisDurationHours : 0,
|
||||||
|
criticalPathReliability: weightedOEE, // Proxy using OEE
|
||||||
|
};
|
||||||
|
|
||||||
|
return { financials, supplyChain, sustainability, reliability };
|
||||||
|
};
|
||||||
|
|
||||||
|
const advancedAnalytics = calculateAdvancedAnalytics();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
assets: allAssets,
|
assets: allAssets,
|
||||||
|
|
||||||
@@ -2166,6 +2261,8 @@ function Analyzer() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
advancedAnalytics,
|
||||||
|
|
||||||
predictiveInsights: {
|
predictiveInsights: {
|
||||||
maintenanceAlerts: maintenanceAlerts.slice(0, 5), // Top 5 alerts
|
maintenanceAlerts: maintenanceAlerts.slice(0, 5), // Top 5 alerts
|
||||||
optimizationOpportunities: optimizationOpportunities.slice(0, 5), // Top 5 opportunities
|
optimizationOpportunities: optimizationOpportunities.slice(0, 5), // Top 5 opportunities
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ function Simulation() {
|
|||||||
const { analysis } = analysisStore();
|
const { analysis } = analysisStore();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// console.log("analysis: ", analysis);
|
console.log("analysis: ", analysis);
|
||||||
}, [analysis]);
|
}, [analysis]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
57
app/src/types/simulationTypes.d.ts
vendored
57
app/src/types/simulationTypes.d.ts
vendored
@@ -514,6 +514,8 @@ interface QualityMetrics {
|
|||||||
count: number;
|
count: number;
|
||||||
averageTime: number;
|
averageTime: number;
|
||||||
}[];
|
}[];
|
||||||
|
scrapRate?: number;
|
||||||
|
reworkRate?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CostMetrics {
|
interface CostMetrics {
|
||||||
@@ -1126,6 +1128,58 @@ interface PredictiveInsights {
|
|||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface FinancialMetrics {
|
||||||
|
totalRevenue: number;
|
||||||
|
grossProfit: number;
|
||||||
|
netProfitMargin: number; // Percentage
|
||||||
|
burnRate: number; // Cost per hour
|
||||||
|
laborCostRatio: number; // Labor cost / Total cost
|
||||||
|
energyCostRatio: number; // Energy cost / Total cost
|
||||||
|
maintenanceCostRatio: number; // Maintenance cost / Total cost
|
||||||
|
breakEvenUnits: number; // Units needed to cover fixed costs
|
||||||
|
fixedCosts: number; // Estimated fixed overhead
|
||||||
|
variableCosts: number; // Direct production costs
|
||||||
|
revenuePerUnit: number;
|
||||||
|
costPerUnit: number;
|
||||||
|
profitPerUnit: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SupplyChainMetrics {
|
||||||
|
totalInventoryValue: number; // Current WIP value
|
||||||
|
inventoryTurnoverRate: number; // COGS / Average Inventory (per hour scaled)
|
||||||
|
averageLeadTime: number; // End-to-end processing time
|
||||||
|
holdingCost: number; // Estimated cost to store WIP
|
||||||
|
stockoutRisk: number; // Probability of starvation
|
||||||
|
supplierDependence: number; // External dependency factor (simulated)
|
||||||
|
materialUtilization: number; // % of raw material converting to product
|
||||||
|
scrapValue: number; // Recoverable value from waste
|
||||||
|
}
|
||||||
|
|
||||||
|
interface SustainabilityMetrics {
|
||||||
|
totalCarbonFootprint: number; // kg CO2e
|
||||||
|
energyIntensity: number; // kWh per unit produced
|
||||||
|
carbonIntensity: number; // kg CO2 per unit produced
|
||||||
|
wasteGenerationRate: number; // kg waste per hour
|
||||||
|
recyclableRatio: number; // Percentage of waste recyclable
|
||||||
|
waterUsage: number; // Estimated water usage (simulated)
|
||||||
|
ecoEfficiencyScore: number; // 0-100 score
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ReliabilityMetrics {
|
||||||
|
systemMTBF: number; // System Mean Time Between Failures
|
||||||
|
systemMTTR: number; // System Mean Time To Repair
|
||||||
|
systemAvailability: number; // Percentage
|
||||||
|
failureFrequency: number; // Failures per hour
|
||||||
|
criticalPathReliability: number; // Reliability of the bottleneck path
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AdvancedAnalytics {
|
||||||
|
financials: FinancialMetrics;
|
||||||
|
supplyChain: SupplyChainMetrics;
|
||||||
|
sustainability: SustainabilityMetrics;
|
||||||
|
reliability: ReliabilityMetrics;
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// MAIN ANALYSIS SCHEMA
|
// MAIN ANALYSIS SCHEMA
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
@@ -1142,6 +1196,9 @@ interface AnalysisSchema {
|
|||||||
// Material Flow
|
// Material Flow
|
||||||
materialFlow: MaterialFlowAnalysis;
|
materialFlow: MaterialFlowAnalysis;
|
||||||
|
|
||||||
|
// Advanced Analytics
|
||||||
|
advancedAnalytics: AdvancedAnalytics;
|
||||||
|
|
||||||
// Predictive Insights
|
// Predictive Insights
|
||||||
predictiveInsights: PredictiveInsights;
|
predictiveInsights: PredictiveInsights;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user