add simulations data

This commit is contained in:
2025-09-04 17:26:18 +05:30
parent 1cef2987a6
commit f6a63c20d7
11 changed files with 736 additions and 346 deletions

View File

@@ -1,4 +1,5 @@
import { DepthOfField, Bloom, EffectComposer, N8AO } from "@react-three/postprocessing";
// import OutlineInstances from "./outlineInstances/outlineInstances";
import OutlineInstances from "./outlineInstances/outlineInstances";
import { useDeletableEventSphere, useSelectedEventSphere } from "../../../store/simulation/useSimulationStore";

View File

@@ -1,8 +1,10 @@
import React, { useEffect } from 'react'
import { CompareProduct, useCompareProductDataStore, useInputValues, useMachineDowntime, useMachineUptime, useProductionCapacityData, useROISummaryData, useThroughPutData } from '../../../../store/builder/store';
import { CompareProduct, comparsionMaterialData, useCompareProductDataStore, useInputValues, useMachineDowntime, useMachineUptime, useProductionCapacityData, useROISummaryData, useThroughPutData } from '../../../../store/builder/store';
import { usePlayButtonStore } from '../../../../store/usePlayButtonStore';
import { useProductContext } from '../../products/productContext';
import { useSceneContext } from '../../../scene/sceneContext';
import { saveSimulationData } from '../../../../components/layout/scenes/functions/simulationStorage';
import { set } from 'immer/dist/internal';
export default function ROIData() {
const { selectedProductStore } = useProductContext();
@@ -17,6 +19,7 @@ export default function ROIData() {
const { machineActiveTime } = useMachineUptime();
const { machineIdleTime } = useMachineDowntime();
const { throughputData } = useThroughPutData()
const { materialData, setMaterialData } = comparsionMaterialData()
useEffect(() => {
if (isPlaying) return;
@@ -136,6 +139,22 @@ export default function ROIData() {
const Annual_net_profit = (Annual_units * (sellingPrice - materialCost - laborCost)) - (maintenanceCost + electricityCost + fixedCost) * workingDaysPerYear + (salvageValue * workingDaysPerYear)
const Payback_period_years = initialInvestment / Annual_net_profit;
const data = {
productName: selectedProduct.productName,
roiPercentage: ROI,
paybackPeriod: Payback_period_years,
totalCost: Total_cost,
revenueGenerated: Total_revenue,
netProfit: Net_profit > 0 ? Net_profit : 0,
netLoss: Net_profit < 0 ? -Net_profit : 0
}
console.log('selectedProduct.productUuid: ', selectedProduct.productUuid);
saveSimulationData({ key: selectedProduct.productUuid, data: data });
const datas = {
roi: data
}
setMaterialData(datas);
setRoiSummaryData({
productName: selectedProduct.productName,

View File

@@ -1,12 +1,15 @@
import { useEffect } from 'react'
import { useInputValues, useProductionCapacityData, useThroughPutData } from '../../../../store/builder/store'
import { comparsionMaterialData, useInputValues, useProductionCapacityData, useThroughPutData } from '../../../../store/builder/store'
import { usePlayButtonStore } from '../../../../store/usePlayButtonStore';
import { saveSimulationData } from '../../../../components/layout/scenes/functions/simulationStorage';
export default function ProductionCapacityData() {
const { throughputData } = useThroughPutData()
const { setProductionCapacityData } = useProductionCapacityData()
const { inputValues } = useInputValues();
const { isPlaying } = usePlayButtonStore();
const { materialData, setMaterialData } = comparsionMaterialData()
useEffect(() => {
if (!isPlaying) {
@@ -21,10 +24,12 @@ export default function ProductionCapacityData() {
if (!isNaN(workingDaysPerYear) && throughputData > 0) {
const Monthly_working_days = workingDaysPerYear / 12;
const Production_capacity_per_month = throughputData * Monthly_working_days;
const data = Number(Production_capacity_per_month.toFixed(2));
saveSimulationData({ key: 'productionCapacity', data: data });
setMaterialData({ ...materialData, productionCapacity: data });
setProductionCapacityData(Number(Production_capacity_per_month.toFixed(2)));
}
}, [throughputData, inputValues, isPlaying]);
}, [throughputData, inputValues, isPlaying, materialData]);
return (
<></>

View File

@@ -1,9 +1,10 @@
import { useEffect } from 'react';
import { determineExecutionMachineSequences } from '../../simulator/functions/determineExecutionMachineSequences';
import { useInputValues, useMachineCount, useMachineDowntime, useMachineUptime, useMaterialCycle, useProcessBar, useThroughPutData } from '../../../../store/builder/store';
import { comparsionMaterialData, useInputValues, useMachineCount, useMachineDowntime, useMachineUptime, useMaterialCycle, useProcessBar, useThroughPutData } from '../../../../store/builder/store';
import { usePlayButtonStore } from '../../../../store/usePlayButtonStore';
import { useSceneContext } from '../../../scene/sceneContext';
import { useProductContext } from '../../products/productContext';
import { saveSimulationData } from '../../../../components/layout/scenes/functions/simulationStorage';
export default function ThroughPutData() {
const { materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, productStore } = useSceneContext();
@@ -24,6 +25,7 @@ export default function ThroughPutData() {
const { setThroughputData } = useThroughPutData()
const { isPlaying } = usePlayButtonStore();
const { inputValues } = useInputValues();
const { materialData, setMaterialData } = comparsionMaterialData()
// Setting machine count
let totalItems = 0;
@@ -219,9 +221,13 @@ export default function ThroughPutData() {
const Units_per_shift = (shiftLength * 60) / (materialCycleTime / 60);
const Throughput_per_day = Units_per_shift * shiftsPerDay * (yieldRate / 100);
const data = Number(Throughput_per_day.toFixed(2))
saveSimulationData({ key: selectedProduct.productUuid, data: data });
setMaterialData({ ...materialData, throughput: data });
setThroughputData(Number(Throughput_per_day.toFixed(2))); // Keep as number
}
}, [materialCycleTime, machineCount, isPlaying, inputValues]);
}, [materialCycleTime, machineCount, isPlaying, inputValues, materialData]);
return (
<>

View File

@@ -0,0 +1,181 @@
import React, { useEffect } from 'react';
import { useSceneContext } from '../../scene/sceneContext';
import { useProductContext } from '../products/productContext';
import { determineExecutionMachineSequences } from './functions/determineExecutionMachineSequences';
import { usePlayButtonStore } from '../../../store/usePlayButtonStore';
import { useSimulationManager } from '../../../store/rough/useSimulationManagerStore';
import { useParams } from 'react-router-dom';
import { useVersionContext } from '../../builder/version/versionContext';
interface SimulationUsageRecord {
activeTime: number;
isActive: boolean;
idleTime: number;
type:
| "roboticArm"
| "vehicle"
| "transfer"
| "storageUnit"
| "crane"
| "human"
| "machine";
}
// Product → holds multiple usage records
interface ProductSimulation {
productId: string;
data: SimulationUsageRecord[];
}
// Version → holds multiple products
interface VersionSimulation {
versionId: string;
products: ProductSimulation[];
}
// Project → holds multiple versions
interface ProjectSimulation {
projectId: string | undefined;
versions: VersionSimulation[];
}
const SimulationHandler = () => {
const { materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, productStore, craneStore, humanStore } = useSceneContext();
const { armBots, getArmBotById } = armBotStore();
const { vehicles, getVehicleById } = vehicleStore();
const { getConveyorById } = conveyorStore();
const { materialHistory, materials } = materialStore();
const { getProductById } = productStore();
const { selectedProductStore } = useProductContext();
const { selectedProduct } = selectedProductStore();
const { machines, getMachineById } = machineStore();
const { getHumanById } = humanStore();
const { getCraneById, } = craneStore();
const { getStorageUnitById } = storageUnitStore();
const { isPlaying, setIsPlaying } = usePlayButtonStore();
const { simulationData, addData } = useSimulationManager();
const { projectId } = useParams();
const { selectedVersionStore } = useVersionContext();
const { selectedVersion } = selectedVersionStore();
useEffect(() => {
let checkTimer: ReturnType<typeof setTimeout>;
if (!projectId) return;
async function checkActiveMachines() {
const currentProduct = getProductById(selectedProduct.productUuid);
let hasActiveEntity = false;
if (currentProduct) {
const executionSequences = await determineExecutionMachineSequences([currentProduct]);
if (executionSequences?.length > 0) {
executionSequences.forEach(sequence => {
sequence.forEach(entity => {
if (entity.type === 'roboticArm') {
const roboticArm = getArmBotById(entity.modelUuid);
if (roboticArm?.isActive) {
hasActiveEntity = true;
}
}
if (entity.type === 'vehicle') {
const vehicle = getVehicleById(entity.modelUuid);
if (vehicle?.isActive) {
hasActiveEntity = true;
}
}
if (entity.type === 'machine') {
const machine = getMachineById(entity.modelUuid);
if (machine?.isActive) {
hasActiveEntity = true;
}
}
if (entity.type === 'human') {
const human = getHumanById(entity.modelUuid);
if (human?.isActive) {
hasActiveEntity = true;
}
}
if (entity.type === 'crane') {
const crane = getCraneById(entity.modelUuid);
if (crane?.isActive) {
hasActiveEntity = true;
}
}
if (entity.type === 'storageUnit') {
const storageUnit = getStorageUnitById(entity.modelUuid);
if (storageUnit?.isActive) {
hasActiveEntity = true;
}
}
if (entity.type === "transfer") {
const storageUnit = getConveyorById(entity.modelUuid);
if (storageUnit?.isActive) {
hasActiveEntity = true;
}
}
});
});
}
if (materials.length === 0 && materialHistory.length >= 0 && !hasActiveEntity) {
if (executionSequences?.length > 0) {
executionSequences.forEach((sequence) => {
sequence.forEach((entity) => {
const typeToGetter: Record<string, (id: string) => any> = {
roboticArm: getArmBotById,
vehicle: getVehicleById,
machine: getMachineById,
human: getHumanById,
crane: getCraneById,
storageUnit: getStorageUnitById,
transfer: getConveyorById,
};
const getter = typeToGetter[entity.type];
if (!getter) return; // skip unknown entity types
const obj = getter(entity.modelUuid);
if (!obj) return; // skip if not found
addData(
projectId,
selectedVersion?.versionId || "",
selectedProduct?.productUuid,
{
activeTime: obj.activeTime ?? 0,
isActive: obj.isActive ?? false,
idleTime: obj.idleTime ?? 0,
type: entity.type as
| "roboticArm"
| "vehicle"
| "machine"
| "human"
| "crane"
| "storageUnit"
| "transfer",
}
);
});
});
}
setIsPlaying(false);
}
}
}
if (isPlaying) {
checkTimer = setTimeout(() => {
checkActiveMachines();
}, 1500);
}
return () => {
if (checkTimer) clearTimeout(checkTimer);
};
}, [materials, materialHistory, selectedVersion, selectedProduct?.productUuid, isPlaying, armBots, vehicles, machines]);
return null;
}
export default SimulationHandler;

View File

@@ -4,6 +4,7 @@ import { usePlayButtonStore, useResetButtonStore } from '../../../store/usePlayB
import { determineExecutionOrder } from './functions/determineExecutionOrder';
import { useProductContext } from '../products/productContext';
import { useSceneContext } from '../../scene/sceneContext';
import SimulationHandler from './SimulationHandler';
function Simulator() {
const { selectedProductStore } = useProductContext();
@@ -32,6 +33,9 @@ function Simulator() {
<>
{/* <simulationHandler/> */}
<SimulationHandler />
</>
);