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(() => {
|
||||
if (!product?.eventDatas) return [];
|
||||
|
||||
return product.eventDatas.map((asset) => ({
|
||||
const assetItems = product.eventDatas.map((asset) => ({
|
||||
id: asset.modelUuid,
|
||||
label: asset.modelName,
|
||||
icon: <DeviceIcon />,
|
||||
}));
|
||||
|
||||
return [{ id: "global", label: "Global System", icon: <DeviceIcon /> }, ...assetItems];
|
||||
}, [product?.eventDatas]);
|
||||
|
||||
const getLableValueDropdownItems = useCallback(
|
||||
@@ -258,6 +260,41 @@ const ElementEditor: React.FC<ElementEditorProps> = ({
|
||||
{ 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",
|
||||
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 {
|
||||
assets: allAssets,
|
||||
|
||||
@@ -2166,6 +2261,8 @@ function Analyzer() {
|
||||
},
|
||||
},
|
||||
|
||||
advancedAnalytics,
|
||||
|
||||
predictiveInsights: {
|
||||
maintenanceAlerts: maintenanceAlerts.slice(0, 5), // Top 5 alerts
|
||||
optimizationOpportunities: optimizationOpportunities.slice(0, 5), // Top 5 opportunities
|
||||
|
||||
@@ -26,7 +26,7 @@ function Simulation() {
|
||||
const { analysis } = analysisStore();
|
||||
|
||||
useEffect(() => {
|
||||
// console.log("analysis: ", analysis);
|
||||
console.log("analysis: ", analysis);
|
||||
}, [analysis]);
|
||||
|
||||
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;
|
||||
averageTime: number;
|
||||
}[];
|
||||
scrapRate?: number;
|
||||
reworkRate?: number;
|
||||
}
|
||||
|
||||
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
|
||||
// ============================================================================
|
||||
@@ -1142,6 +1196,9 @@ interface AnalysisSchema {
|
||||
// Material Flow
|
||||
materialFlow: MaterialFlowAnalysis;
|
||||
|
||||
// Advanced Analytics
|
||||
advancedAnalytics: AdvancedAnalytics;
|
||||
|
||||
// Predictive Insights
|
||||
predictiveInsights: PredictiveInsights;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user