updated comparision
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import * as THREE from 'three';
|
||||
|
||||
import * as Types from "../../../../types/world/worldTypes";
|
||||
|
||||
function hideWalls(
|
||||
@@ -7,21 +6,24 @@ function hideWalls(
|
||||
scene: THREE.Scene,
|
||||
camera: THREE.Camera
|
||||
): void {
|
||||
|
||||
////////// Altering the visibility of the Walls when the world direction of the wall is facing the camera //////////
|
||||
|
||||
const v = new THREE.Vector3();
|
||||
const u = new THREE.Vector3();
|
||||
const wallNormal = new THREE.Vector3();
|
||||
const cameraToWall = new THREE.Vector3();
|
||||
const cameraDirection = new THREE.Vector3();
|
||||
|
||||
if (visibility === true) {
|
||||
for (const children of scene.children) {
|
||||
if (children.name === "Walls" && children.children[0]?.children.length > 0) {
|
||||
children.children[0].children.forEach((child: any) => {
|
||||
if (child.children[0]?.userData.WallType === "RoomWall") {
|
||||
child.children[0].getWorldDirection(v);
|
||||
camera.getWorldDirection(u);
|
||||
if (child.children[0].material) {
|
||||
child.children[0].material.visible = (2 * v.dot(u)) >= -0.5;
|
||||
const wallMesh = child.children[0];
|
||||
wallMesh.getWorldDirection(wallNormal);
|
||||
cameraToWall.copy(wallMesh.position).sub(camera.position).normalize();
|
||||
camera.getWorldDirection(cameraDirection);
|
||||
const isFacingCamera = wallNormal.dot(cameraToWall) > 0;
|
||||
const isInFrontOfCamera = cameraDirection.dot(cameraToWall) > -0.3;
|
||||
|
||||
if (wallMesh.material) {
|
||||
wallMesh.material.visible = isFacingCamera && isInFrontOfCamera;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -31,10 +33,8 @@ function hideWalls(
|
||||
for (const children of scene.children) {
|
||||
if (children.name === "Walls" && children.children[0]?.children.length > 0) {
|
||||
children.children[0].children.forEach((child: any) => {
|
||||
if (child.children[0]?.userData.WallType === "RoomWall") {
|
||||
if (child.children[0].material) {
|
||||
child.children[0].material.visible = true;
|
||||
}
|
||||
if (child.children[0]?.userData.WallType === "RoomWall" && child.children[0].material) {
|
||||
child.children[0].material.visible = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -42,4 +42,4 @@ function hideWalls(
|
||||
}
|
||||
}
|
||||
|
||||
export default hideWalls;
|
||||
export default hideWalls;
|
||||
@@ -49,6 +49,7 @@ function CommentsGroup() {
|
||||
!intersect.object.name.includes("zonePlane") &&
|
||||
!intersect.object.name.includes("SelectionGroup") &&
|
||||
!intersect.object.name.includes("selectionAssetGroup") &&
|
||||
!intersect.object.name.includes("commentHolder") &&
|
||||
!intersect.object.name.includes("SelectionGroupBoundingBoxLine") &&
|
||||
!intersect.object.name.includes("SelectionGroupBoundingBox") &&
|
||||
!intersect.object.name.includes("SelectionGroupBoundingLine") &&
|
||||
@@ -76,11 +77,13 @@ function CommentsGroup() {
|
||||
!intersect.object.name.includes("zonePlane") &&
|
||||
!intersect.object.name.includes("SelectionGroup") &&
|
||||
!intersect.object.name.includes("selectionAssetGroup") &&
|
||||
!intersect.object.name.includes("commentHolder") &&
|
||||
!intersect.object.name.includes("SelectionGroupBoundingBoxLine") &&
|
||||
!intersect.object.name.includes("SelectionGroupBoundingBox") &&
|
||||
!intersect.object.name.includes("SelectionGroupBoundingLine") &&
|
||||
intersect.object.type !== "GridHelper"
|
||||
);
|
||||
console.log('intersects: ', intersects);
|
||||
if (intersects.length > 0) {
|
||||
const position = new Vector3(intersects[0].point.x, Math.max(intersects[0].point.y, 0), intersects[0].point.z);
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { useMemo } from "react";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { Canvas } from "@react-three/fiber";
|
||||
import { Color } from "three";
|
||||
import { KeyboardControls } from "@react-three/drei";
|
||||
import { SceneProvider } from "./sceneContext";
|
||||
|
||||
@@ -9,6 +8,12 @@ import Visualization from "../visualization/visualization";
|
||||
import Setup from "./setup/setup";
|
||||
import Simulation from "../simulation/simulation";
|
||||
import Collaboration from "../collaboration/collaboration";
|
||||
import useModuleStore from "../../store/useModuleStore";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { getAllProjects } from "../../services/dashboard/getAllProjects";
|
||||
import { getUserData } from "../../components/Dashboard/functions/getUserData";
|
||||
import { useLoadingProgress, useSocketStore } from "../../store/builder/store";
|
||||
import { useAssetsStore } from "../../store/builder/useAssetStore";
|
||||
|
||||
export default function Scene({ layout }: { readonly layout: 'Main Layout' | 'Comparison Layout' }) {
|
||||
const map = useMemo(() => [
|
||||
@@ -17,19 +22,76 @@ export default function Scene({ layout }: { readonly layout: 'Main Layout' | 'Co
|
||||
{ name: "left", keys: ["ArrowLeft", "a", "A"] },
|
||||
{ name: "right", keys: ["ArrowRight", "d", "D"] },
|
||||
], []);
|
||||
const { assets } = useAssetsStore();
|
||||
const { userId, organization } = getUserData();
|
||||
const { activeModule } = useModuleStore();
|
||||
const { projectId } = useParams();
|
||||
const { projectSocket } = useSocketStore();
|
||||
const { loadingProgress } = useLoadingProgress();
|
||||
const handleUpdatingProject = async () => {
|
||||
if (!projectId) return;
|
||||
try {
|
||||
const projects = await getAllProjects(userId, organization);
|
||||
let projectUuid = projects.Projects.find(
|
||||
(val: any) => val.projectUuid === projectId || val._id === projectId
|
||||
);
|
||||
|
||||
|
||||
if (activeModule === "builder" && loadingProgress !== 1) {
|
||||
const canvas =
|
||||
document.getElementById("sceneCanvas")?.children[0]?.children[0];
|
||||
const screenshotDataUrl = (canvas as HTMLCanvasElement)?.toDataURL("image/png");
|
||||
setTimeout(() => {
|
||||
const updateProjects = {
|
||||
projectId: projectUuid,
|
||||
organization,
|
||||
userId,
|
||||
projectName: projectUuid.projectName,
|
||||
thumbnail: screenshotDataUrl,
|
||||
};
|
||||
if (projectSocket) {
|
||||
projectSocket.emit("v1:project:update", updateProjects);
|
||||
}
|
||||
}, 8000);
|
||||
} else {
|
||||
const canvas =
|
||||
document.getElementById("sceneCanvas")?.children[0]?.children[0];
|
||||
const screenshotDataUrl = (canvas as HTMLCanvasElement)?.toDataURL("image/png");
|
||||
const updateProjects = {
|
||||
projectId: projectUuid,
|
||||
organization,
|
||||
userId,
|
||||
projectName: projectUuid.projectName,
|
||||
thumbnail: screenshotDataUrl,
|
||||
};
|
||||
// console.log('screenshotDataUrl: ', screenshotDataUrl);
|
||||
// console.log('updateProjects: ', updateProjects);
|
||||
if (projectSocket) {
|
||||
projectSocket.emit("v1:project:update", updateProjects);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (error) { }
|
||||
};
|
||||
useEffect(() => {
|
||||
handleUpdatingProject()
|
||||
}, [activeModule, assets, loadingProgress])
|
||||
|
||||
return (
|
||||
<SceneProvider layout={layout}>
|
||||
<KeyboardControls map={map}>
|
||||
<Canvas
|
||||
id="sceneCanvas"
|
||||
shadows
|
||||
color="#aaaa"
|
||||
eventPrefix="client"
|
||||
gl={{ powerPreference: "high-performance", antialias: true }}
|
||||
onContextMenu={(e) => {
|
||||
e.preventDefault();
|
||||
}}
|
||||
onCreated={(e) => {
|
||||
e.scene.background = new Color(0x19191d);
|
||||
e.scene.background = null;
|
||||
}}
|
||||
gl={{ powerPreference: "high-performance", antialias: true, preserveDrawingBuffer: true }}
|
||||
>
|
||||
<Setup />
|
||||
<Collaboration />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { useInputValues, useProductionCapacityData, useROISummaryData } from '../../../../store/builder/store';
|
||||
import React, { useEffect } from 'react'
|
||||
import { CompareProduct, useCompareProductDataStore, useInputValues, useMachineDowntime, useMachineUptime, useProductionCapacityData, useROISummaryData, useThroughPutData } from '../../../../store/builder/store';
|
||||
import { usePlayButtonStore } from '../../../../store/usePlayButtonStore';
|
||||
import { useProductContext } from '../../products/productContext';
|
||||
import { useProductStore } from '../../../../store/simulation/useProductStore';
|
||||
@@ -12,28 +12,31 @@ export default function ROIData() {
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { setRoiSummaryData } = useROISummaryData();
|
||||
const { products, getProductById } = useProductStore();
|
||||
const [compareProducts, setCompareProducts] = useState<any[]>([]);
|
||||
const { compareProductsData, setCompareProductsData } = useCompareProductDataStore();
|
||||
const { machineActiveTime, setMachineActiveTime } = useMachineUptime();
|
||||
const { machineIdleTime, setMachineIdleTime } = useMachineDowntime();
|
||||
const { throughputData } = useThroughPutData()
|
||||
|
||||
useEffect(() => {
|
||||
if (!isPlaying) {
|
||||
setRoiSummaryData({
|
||||
productName: "",
|
||||
roiPercentage: 0,
|
||||
paybackPeriod: 0,
|
||||
totalCost: 0,
|
||||
revenueGenerated: 0,
|
||||
netProfit: 0,
|
||||
netLoss: 0,
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
if (inputValues === undefined) return;
|
||||
if (isPlaying) return;
|
||||
setRoiSummaryData({
|
||||
productName: "",
|
||||
roiPercentage: 0,
|
||||
paybackPeriod: 0,
|
||||
totalCost: 0,
|
||||
revenueGenerated: 0,
|
||||
netProfit: 0,
|
||||
netLoss: 0,
|
||||
});
|
||||
}, [isPlaying]);
|
||||
|
||||
useEffect(() => {
|
||||
if (inputValues === undefined || !isPlaying) return;
|
||||
const electricityCost = parseFloat(inputValues["Electricity cost"]);
|
||||
const fixedCost = parseFloat(inputValues["Fixed costs"]);
|
||||
const laborCost = parseFloat(inputValues["Labor Cost"]);
|
||||
const maintenanceCost = parseFloat(inputValues["Maintenance cost"]); // Remove space typ
|
||||
const laborCount = parseFloat(inputValues["Labor Count"]);
|
||||
const maintenanceCost = parseFloat(inputValues["Maintenance cost"]);
|
||||
const materialCost = parseFloat(inputValues["Material cost"]);
|
||||
const productionPeriod = parseFloat(inputValues["Production period"]);
|
||||
const salvageValue = parseFloat(inputValues["Salvage value"]);
|
||||
@@ -46,109 +49,146 @@ export default function ROIData() {
|
||||
if (!isNaN(electricityCost) && !isNaN(fixedCost) && !isNaN(laborCost) && !isNaN(maintenanceCost) &&
|
||||
!isNaN(materialCost) && !isNaN(productionPeriod) && !isNaN(salvageValue) && !isNaN(sellingPrice) &&
|
||||
!isNaN(shiftLength) && !isNaN(shiftsPerDay) && !isNaN(workingDaysPerYear) && productionCapacityData > 0) {
|
||||
|
||||
const totalHoursPerYear = shiftLength * shiftsPerDay * workingDaysPerYear;
|
||||
// Total good units produced per year
|
||||
const annualProductionUnits = productionCapacityData * totalHoursPerYear;
|
||||
// Revenue for a year
|
||||
const annualRevenue = annualProductionUnits * sellingPrice;
|
||||
// Costs
|
||||
const totalMaterialCost = annualProductionUnits * materialCost;
|
||||
const totalLaborCost = laborCost * totalHoursPerYear;
|
||||
const totalEnergyCost = electricityCost * totalHoursPerYear;
|
||||
const totalMaintenanceCost = maintenanceCost + fixedCost;
|
||||
const totalAnnualCost = totalMaterialCost + totalLaborCost + totalEnergyCost + totalMaintenanceCost;
|
||||
// Annual Profit
|
||||
const annualProfit = annualRevenue - totalAnnualCost;
|
||||
|
||||
// Net Profit over production period
|
||||
const netProfit = annualProfit * productionPeriod;
|
||||
// ROI
|
||||
const roiPercentage = ((netProfit + salvageValue - initialInvestment) / initialInvestment) * 100;
|
||||
// Payback Period
|
||||
const paybackPeriod = initialInvestment / (annualProfit || 1); // Avoid division by 0
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// const totalHoursPerYear = shiftLength * shiftsPerDay * workingDaysPerYear;
|
||||
// const annualProductionUnits = productionCapacityData * totalHoursPerYear;
|
||||
// const annualRevenue = annualProductionUnits * sellingPrice;
|
||||
|
||||
// const totalMaterialCost = annualProductionUnits * materialCost;
|
||||
// const totalLaborCost = laborCost * totalHoursPerYear;
|
||||
// const totalEnergyCost = electricityCost * totalHoursPerYear;
|
||||
// const totalMaintenanceCost = maintenanceCost + fixedCost;
|
||||
// const totalAnnualCost = totalMaterialCost + totalLaborCost + totalEnergyCost + totalMaintenanceCost;
|
||||
// const annualProfit = annualRevenue - totalAnnualCost;
|
||||
|
||||
// const netProfit = annualProfit * productionPeriod;
|
||||
// const roiPercentage = ((annualProfit + salvageValue - initialInvestment) / initialInvestment) * 100;
|
||||
// const paybackPeriod = initialInvestment / (annualProfit || 1); // Avoid division by 0
|
||||
|
||||
// setRoiSummaryData({
|
||||
// productName: selectedProduct.productName,
|
||||
// roiPercentage: parseFloat((roiPercentage / 100).toFixed(2)),
|
||||
// paybackPeriod: parseFloat(paybackPeriod.toFixed(2)),
|
||||
// totalCost: parseFloat(totalAnnualCost.toFixed(2)),
|
||||
// revenueGenerated: parseFloat(annualRevenue.toFixed(2)),
|
||||
// netProfit: netProfit > 0 ? parseFloat(netProfit.toFixed(2)) : 0,
|
||||
// netLoss: netProfit < 0 ? -netProfit : 0
|
||||
// });
|
||||
|
||||
// const productCount = 1000;
|
||||
// const costPerUnit = totalAnnualCost / annualProductionUnits;
|
||||
// const costForTargetUnits = productCount * costPerUnit;
|
||||
// const revenueForTargetUnits = productCount * sellingPrice;
|
||||
// const profitForTargetUnits = revenueForTargetUnits - costForTargetUnits;
|
||||
|
||||
// const netProfitForTarget = profitForTargetUnits > 0 ? profitForTargetUnits : 0;
|
||||
// const netLossForTarget = profitForTargetUnits < 0 ? -profitForTargetUnits : 0;
|
||||
|
||||
// const productData = getProductById(selectedProduct.productUuid);
|
||||
// const prev = useCompareProductDataStore.getState().compareProductsData;
|
||||
// const newData: CompareProduct = {
|
||||
// productUuid: productData?.productUuid ?? '',
|
||||
// productName: productData?.productName ?? '',
|
||||
// simulationData: {
|
||||
// // costPerUnit: parseFloat(costPerUnit.toFixed(2)),
|
||||
// // workingDaysPerYear: parseFloat(workingDaysPerYear.toFixed(2)),
|
||||
// // shiftLength: parseFloat(shiftLength.toFixed(2)),
|
||||
// // shiftsPerDay: parseFloat(shiftsPerDay.toFixed(2)),
|
||||
// roiPercentage: parseFloat((roiPercentage / 100).toFixed(2)),
|
||||
// // paybackPeriod: parseFloat(paybackPeriod.toFixed(2)),
|
||||
// // totalCost: parseFloat(totalAnnualCost.toFixed(2)),
|
||||
// // revenueGenerated: parseFloat(annualRevenue.toFixed(2)),
|
||||
// netProfit: netProfit > 0 ? parseFloat(netProfit.toFixed(2)) : 0,
|
||||
// productionCapacity: parseFloat(productionCapacityData.toFixed(2)),
|
||||
// // netLoss: netProfit < 0 ? parseFloat((-netProfit).toFixed(2)) : 0,
|
||||
// machineIdleTime: parseFloat(machineIdleTime.toFixed(2)),
|
||||
// machineActiveTime: parseFloat(machineActiveTime.toFixed(2)),
|
||||
// throughputData: throughputData,
|
||||
// }
|
||||
// };
|
||||
|
||||
// const existingIndex = prev.findIndex((item: CompareProduct) =>
|
||||
// item.productUuid === productData?.productUuid
|
||||
// );
|
||||
|
||||
// if (existingIndex !== -1) {
|
||||
// const updated = [...prev];
|
||||
// updated[existingIndex] = newData;
|
||||
// setCompareProductsData(updated);
|
||||
// } else {
|
||||
// setCompareProductsData([...prev, newData]);
|
||||
// }
|
||||
|
||||
const Annual_units = throughputData * workingDaysPerYear
|
||||
const Total_units = Annual_units * productionPeriod
|
||||
|
||||
const Total_revenue = Total_units * sellingPrice
|
||||
const Total_variable_cost = Total_units * (materialCost + (laborCost))
|
||||
|
||||
const Total_fixed_cost = (maintenanceCost + electricityCost + fixedCost) * workingDaysPerYear * productionPeriod
|
||||
const Total_cost = Total_variable_cost + Total_fixed_cost
|
||||
|
||||
const Net_profit = Total_revenue - Total_cost + (salvageValue * workingDaysPerYear * productionPeriod)
|
||||
|
||||
const ROI = (Net_profit / initialInvestment) * 100
|
||||
|
||||
const Annual_net_profit = (Annual_units * (sellingPrice - materialCost - laborCost)) - (maintenanceCost + electricityCost + fixedCost) * workingDaysPerYear + (salvageValue * workingDaysPerYear)
|
||||
const Payback_period_years = initialInvestment / Annual_net_profit;
|
||||
|
||||
setRoiSummaryData({
|
||||
productName: selectedProduct.productName,
|
||||
roiPercentage: parseFloat((roiPercentage / 100).toFixed(2)), // normalized to 0.x format
|
||||
paybackPeriod: parseFloat(paybackPeriod.toFixed(2)),
|
||||
totalCost: parseFloat(totalAnnualCost.toFixed(2)),
|
||||
revenueGenerated: parseFloat(annualRevenue.toFixed(2)),
|
||||
netProfit: netProfit > 0 ? parseFloat(netProfit.toFixed(2)) : 0,
|
||||
netLoss: netProfit < 0 ? -netProfit : 0
|
||||
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
|
||||
});
|
||||
|
||||
const productCount = 1000;
|
||||
|
||||
// Cost per unit (based on full annual cost)
|
||||
const costPerUnit = totalAnnualCost / annualProductionUnits;
|
||||
|
||||
const costForTargetUnits = productCount * costPerUnit;
|
||||
const revenueForTargetUnits = productCount * sellingPrice;
|
||||
const profitForTargetUnits = revenueForTargetUnits - costForTargetUnits;
|
||||
|
||||
const netProfitForTarget = profitForTargetUnits > 0 ? profitForTargetUnits : 0;
|
||||
const netLossForTarget = profitForTargetUnits < 0 ? -profitForTargetUnits : 0;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
const productData = getProductById(selectedProduct.productUuid);
|
||||
|
||||
|
||||
setCompareProducts(prev => {
|
||||
const newData = {
|
||||
productUuid: productData?.productUuid,
|
||||
productName: productData?.productName,
|
||||
costPerUnit: parseFloat(costPerUnit.toFixed(2)),
|
||||
workingDaysPerYear: parseFloat(workingDaysPerYear.toFixed(2)),
|
||||
shiftLength: parseFloat(shiftLength.toFixed(2)),
|
||||
shiftsPerDay: parseFloat(shiftsPerDay.toFixed(2)),
|
||||
roiPercentage: parseFloat((roiPercentage / 100).toFixed(2)),
|
||||
paybackPeriod: parseFloat(paybackPeriod.toFixed(2)),
|
||||
totalCost: parseFloat(totalAnnualCost.toFixed(2)),
|
||||
revenueGenerated: parseFloat(annualRevenue.toFixed(2)),
|
||||
netProfit: netProfit > 0 ? parseFloat(netProfit.toFixed(2)) : 0,
|
||||
netLoss: netProfit < 0 ? parseFloat((-netProfit).toFixed(2)) : 0
|
||||
};
|
||||
|
||||
const existingIndex = prev.findIndex(
|
||||
item => item.productUuid === productData?.productUuid
|
||||
);
|
||||
|
||||
if (existingIndex !== -1) {
|
||||
// Replace the existing item
|
||||
const updated = [...prev];
|
||||
updated[existingIndex] = newData;
|
||||
return updated;
|
||||
} else {
|
||||
// Add as new item
|
||||
return [...prev, newData];
|
||||
const prev = useCompareProductDataStore.getState().compareProductsData;
|
||||
const newData: CompareProduct = {
|
||||
productUuid: productData?.productUuid ?? '',
|
||||
productName: productData?.productName ?? '',
|
||||
simulationData: {
|
||||
// costPerUnit: costPerUnit,
|
||||
// workingDaysPerYear: workingDaysPerYear,
|
||||
// shiftLength: shiftLength,
|
||||
// shiftsPerDay: shiftsPerDay,
|
||||
roiPercentage: ROI,
|
||||
paybackPeriod: Payback_period_years,
|
||||
// paybackPeriod: paybackPeriod,
|
||||
// totalCost: totalAnnualCost,
|
||||
// revenueGenerated: annualRevenue,
|
||||
netProfit: Net_profit > 0 ? Net_profit : 0,
|
||||
productionCapacity: productionCapacityData,
|
||||
// netLoss: netProfit < 0 ? (-netProfit) : 0,
|
||||
machineIdleTime: machineIdleTime,
|
||||
machineActiveTime: machineActiveTime,
|
||||
throughputData: throughputData,
|
||||
}
|
||||
});
|
||||
// console.log('compareProducts: ', compareProducts);
|
||||
|
||||
};
|
||||
|
||||
const existingIndex = prev.findIndex((item: CompareProduct) =>
|
||||
item.productUuid === productData?.productUuid
|
||||
);
|
||||
|
||||
if (existingIndex !== -1) {
|
||||
const updated = [...prev];
|
||||
updated[existingIndex] = newData;
|
||||
setCompareProductsData(updated);
|
||||
} else {
|
||||
setCompareProductsData([...prev, newData]);
|
||||
}
|
||||
}
|
||||
|
||||
}, [inputValues, productionCapacityData]);
|
||||
}, [inputValues, productionCapacityData, throughputData, isPlaying]);
|
||||
|
||||
return (
|
||||
<></>
|
||||
)
|
||||
useEffect(() => {
|
||||
|
||||
}, [compareProductsData])
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,47 +1,36 @@
|
||||
import React, { useEffect } from 'react'
|
||||
import { useInputValues, useProductionCapacityData, useThroughPutData } from '../../../../store/builder/store'
|
||||
import { usePlayButtonStore } from '../../../../store/usePlayButtonStore';
|
||||
import { useProductContext } from '../../products/productContext';
|
||||
|
||||
export default function ProductionCapacityData() {
|
||||
const { throughputData } = useThroughPutData()
|
||||
const { productionCapacityData, setProductionCapacityData } = useProductionCapacityData()
|
||||
const { inputValues } = useInputValues();
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { selectedProduct } = selectedProductStore();
|
||||
|
||||
useEffect(() => {
|
||||
if (!isPlaying) {
|
||||
|
||||
setProductionCapacityData(0);
|
||||
return;
|
||||
}
|
||||
if (!inputValues || throughputData === undefined) return;
|
||||
}, [isPlaying]);
|
||||
|
||||
const shiftLength = parseFloat(inputValues["Shift length"]);
|
||||
const shiftsPerDay = parseFloat(inputValues["Shifts / day"]);
|
||||
useEffect(() => {
|
||||
if (!inputValues || throughputData === undefined || !isPlaying) return;
|
||||
const workingDaysPerYear = parseFloat(inputValues["Working days / year"]);
|
||||
const yieldRate = parseFloat(inputValues["Yield rate"]);
|
||||
|
||||
if (!isNaN(shiftLength) && !isNaN(shiftsPerDay) && !isNaN(workingDaysPerYear) &&
|
||||
!isNaN(yieldRate) && throughputData >= 0) {
|
||||
// Total units produced per day before yield
|
||||
const dailyProduction = throughputData * shiftLength * shiftsPerDay;
|
||||
|
||||
if (!isNaN(workingDaysPerYear) && throughputData > 0) {
|
||||
const Monthly_working_days = workingDaysPerYear / 12;
|
||||
const Production_capacity_per_month = throughputData * Monthly_working_days;
|
||||
|
||||
// Units after applying yield rate
|
||||
const goodUnitsPerDay = dailyProduction * (yieldRate / 100);
|
||||
|
||||
|
||||
// Annual output
|
||||
const annualProduction = goodUnitsPerDay * workingDaysPerYear;
|
||||
|
||||
|
||||
// Final production capacity per hour (after yield)
|
||||
const productionPerHour = throughputData * (yieldRate / 100);
|
||||
|
||||
|
||||
// Set the final capacity (units/hour)
|
||||
setProductionCapacityData(Number(productionPerHour.toFixed(2)));
|
||||
setProductionCapacityData(Number(Production_capacity_per_month.toFixed(2)));
|
||||
}
|
||||
}, [throughputData, inputValues]);
|
||||
}, [throughputData, inputValues, isPlaying]);
|
||||
|
||||
return (
|
||||
<></>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useProductStore } from '../../../../store/simulation/useProductStore';
|
||||
import { determineExecutionMachineSequences } from '../../simulator/functions/determineExecutionMachineSequences';
|
||||
import { useMachineCount, useMachineUptime, useMaterialCycle, useProcessBar, useThroughPutData } from '../../../../store/builder/store';
|
||||
import { 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 { set } from 'immer/dist/internal';
|
||||
|
||||
export default function ThroughPutData() {
|
||||
const { materialStore, armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore } = useSceneContext();
|
||||
@@ -19,25 +20,34 @@ export default function ThroughPutData() {
|
||||
const { materialHistory, materials } = materialStore();
|
||||
const { machineCount, setMachineCount } = useMachineCount();
|
||||
const { machineActiveTime, setMachineActiveTime } = useMachineUptime();
|
||||
const { machineIdleTime, setMachineIdleTime } = useMachineDowntime();
|
||||
const { materialCycleTime, setMaterialCycleTime } = useMaterialCycle();
|
||||
const { setProcessBar } = useProcessBar();
|
||||
const { setThroughputData } = useThroughPutData()
|
||||
const { isPlaying } = usePlayButtonStore();
|
||||
const { inputValues } = useInputValues();
|
||||
|
||||
// Setting machine count
|
||||
let totalItems = 0;
|
||||
let totalActiveTime = 0;
|
||||
let totalIdleTime = 0
|
||||
|
||||
useEffect(() => {
|
||||
if (!isPlaying) {
|
||||
totalActiveTime = 0;
|
||||
totalItems = 0;
|
||||
totalIdleTime = 0;
|
||||
setMachineCount(0);
|
||||
setMachineActiveTime(0);
|
||||
setMachineIdleTime(0);
|
||||
setMaterialCycleTime(0);
|
||||
setProcessBar([]);
|
||||
setThroughputData(0);
|
||||
return;
|
||||
} else {
|
||||
}
|
||||
}, [isPlaying])
|
||||
|
||||
useEffect(() => {
|
||||
if (isPlaying) {
|
||||
let process: any = [];
|
||||
const fetchProductSequenceData = async () => {
|
||||
const productData = getProductById(selectedProduct.productUuid);
|
||||
@@ -53,6 +63,9 @@ export default function ThroughPutData() {
|
||||
process.push({ modelid: arm.modelUuid, modelName: arm.modelName, activeTime: arm?.activeTime })
|
||||
totalActiveTime += arm.activeTime;
|
||||
}
|
||||
if (arm.idleTime > 0) {
|
||||
totalIdleTime += arm.idleTime;
|
||||
}
|
||||
});
|
||||
} else if (item.type === "vehicle") {
|
||||
vehicles.filter(vehicle => vehicle.modelUuid === item.modelUuid)
|
||||
@@ -62,6 +75,9 @@ export default function ThroughPutData() {
|
||||
|
||||
totalActiveTime += vehicle.activeTime;
|
||||
}
|
||||
if (vehicle.idleTime > 0) {
|
||||
totalIdleTime += vehicle.idleTime;
|
||||
}
|
||||
});
|
||||
} else if (item.type === "machine") {
|
||||
machines.filter(machine => machine.modelUuid === item.modelUuid)
|
||||
@@ -70,6 +86,9 @@ export default function ThroughPutData() {
|
||||
process.push({ modelid: machine.modelUuid, modelName: machine.modelName, activeTime: machine?.activeTime })
|
||||
totalActiveTime += machine.activeTime;
|
||||
}
|
||||
if (machine.idleTime > 0) {
|
||||
totalIdleTime += machine.idleTime;
|
||||
}
|
||||
});
|
||||
} else if (item.type === "transfer") {
|
||||
conveyors.filter(conveyor => conveyor.modelUuid === item.modelUuid)
|
||||
@@ -83,7 +102,7 @@ export default function ThroughPutData() {
|
||||
.forEach(storage => {
|
||||
if (storage.activeTime > 0) {
|
||||
// totalActiveTime += storage.activeTime;
|
||||
//
|
||||
//
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -92,9 +111,10 @@ export default function ThroughPutData() {
|
||||
totalItems += sequence.length;
|
||||
});
|
||||
|
||||
|
||||
|
||||
setMachineCount(totalItems);
|
||||
setMachineActiveTime(totalActiveTime);
|
||||
setMachineIdleTime(totalIdleTime);
|
||||
let arr = process.map((item: any) => ({
|
||||
name: item.modelName,
|
||||
completed: Math.round((item.activeTime / totalActiveTime) * 100)
|
||||
@@ -107,15 +127,15 @@ export default function ThroughPutData() {
|
||||
fetchProductSequenceData();
|
||||
}
|
||||
// if (materialCycleTime <= 0) return
|
||||
}, [products, selectedProduct, getProductById, setMachineCount, materialCycleTime, armBots, vehicles, machines]);
|
||||
}, [products, selectedProduct?.productUuid, getProductById, setMachineCount, materialCycleTime, armBots, vehicles, machines]);
|
||||
|
||||
useEffect(() => {
|
||||
let timeoutId: ReturnType<typeof setTimeout>;
|
||||
async function getMachineActive() {
|
||||
const productData = getProductById(selectedProduct.productUuid);
|
||||
let anyArmActive;
|
||||
let anyVehicleActive;
|
||||
let anyMachineActive;
|
||||
|
||||
if (productData) {
|
||||
const productSequenceData = await determineExecutionMachineSequences([productData]);
|
||||
if (productSequenceData?.length > 0) {
|
||||
@@ -160,8 +180,8 @@ export default function ThroughPutData() {
|
||||
}
|
||||
|
||||
const allInactive = !anyArmActive && !anyVehicleActive && !anyMachineActive;
|
||||
if (allInactive && materials.length === 0 && materialHistory.length > 0) {
|
||||
|
||||
if (materials.length >= 0 && materialHistory.length > 0) {
|
||||
|
||||
let totalCycleTimeSum = 0;
|
||||
let cycleCount = 0;
|
||||
|
||||
@@ -182,21 +202,28 @@ export default function ThroughPutData() {
|
||||
}
|
||||
}
|
||||
if (isPlaying) {
|
||||
setTimeout(() => {
|
||||
timeoutId = setTimeout(() => {
|
||||
getMachineActive();
|
||||
}, 500)
|
||||
}, 1500);
|
||||
}
|
||||
}, [armBots, materials, materialHistory, machines, vehicles, selectedProduct])
|
||||
|
||||
return () => {
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
};
|
||||
}, [armBots, materials, materialHistory, machines, vehicles, selectedProduct?.productUuid])
|
||||
|
||||
useEffect(() => {
|
||||
if (machineActiveTime > 0 && materialCycleTime > 0 && machineCount > 0) {
|
||||
const utilization = machineActiveTime / 3600; // Active time per hour
|
||||
const unitsPerMachinePerHour = 3600 / materialCycleTime;
|
||||
const throughput = unitsPerMachinePerHour * machineCount * utilization;
|
||||
setThroughputData(Number(throughput.toFixed(2))); // Keep as number
|
||||
//
|
||||
const shiftLength = parseFloat(inputValues["Shift length"]);
|
||||
const shiftsPerDay = parseFloat(inputValues["Shifts / day"]);
|
||||
const yieldRate = parseFloat(inputValues["Yield rate"]);
|
||||
|
||||
if (shiftLength > 0 && materialCycleTime > 0 && machineCount > 0 && isPlaying) {
|
||||
const Units_per_shift = (shiftLength * 60) / (materialCycleTime / 60);
|
||||
|
||||
const Throughput_per_day = Units_per_shift * shiftsPerDay * (yieldRate / 100);
|
||||
setThroughputData(Number(Throughput_per_day.toFixed(2))); // Keep as number
|
||||
}
|
||||
}, [machineActiveTime, materialCycleTime, machineCount]);
|
||||
}, [materialCycleTime, machineCount, isPlaying, inputValues]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -13,6 +13,7 @@ function Products() {
|
||||
const { armBotStore, machineStore, conveyorStore, vehicleStore, storageUnitStore, layout } = useSceneContext();
|
||||
const { products, getProductById, addProduct, setProducts } = useProductStore();
|
||||
const { selectedProductStore } = useProductContext();
|
||||
const { setMainProduct } = useMainProduct();
|
||||
const { selectedProduct, setSelectedProduct } = selectedProductStore();
|
||||
const { addVehicle, clearvehicles } = vehicleStore();
|
||||
const { addArmBot, clearArmBots } = armBotStore();
|
||||
@@ -51,11 +52,13 @@ function Products() {
|
||||
})
|
||||
if (layout === 'Main Layout') {
|
||||
setSelectedProduct(id, name);
|
||||
setMainProduct(id, name);
|
||||
}
|
||||
} else {
|
||||
setProducts(data);
|
||||
if (layout === 'Main Layout') {
|
||||
setSelectedProduct(data[0].productUuid, data[0].productName);
|
||||
setMainProduct(data[0].productUuid, data[0].productName);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -48,7 +48,6 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
|
||||
const computePath = useCallback(
|
||||
(start: any, end: any) => {
|
||||
console.log('end: ', end);
|
||||
try {
|
||||
const navMeshQuery = new NavMeshQuery(navMesh);
|
||||
const { path: segmentPath } = navMeshQuery.computePath(start, end);
|
||||
@@ -57,7 +56,6 @@ function VehicleInstance({ agvDetail }: Readonly<{ agvDetail: VehicleStatus }>)
|
||||
Math.round(segmentPath[segmentPath.length - 1].x) == Math.round(end.x) &&
|
||||
Math.round(segmentPath[segmentPath.length - 1].z) == Math.round(end.z)
|
||||
) {
|
||||
console.log('if ', segmentPath);
|
||||
return segmentPath?.map(({ x, y, z }) => [x, 0, z] as [number, number, number]) || [];
|
||||
} else {
|
||||
console.log("There is no path here...Choose valid path")
|
||||
|
||||
Reference in New Issue
Block a user