import React, { useState, useEffect } from 'react'; import { Card, CardHeader, CardContent, Divider, Grid, Box, Typography } from '@mui/material'; import EnvChart from './EnvChart'; import LevelChart from './LevelChart'; import { useI18n } from './I18nContext'; export default function ControllerCard({ controllerName, ports, range }) { const { t } = useI18n(); const [envData, setEnvData] = useState([]); const [portData, setPortData] = useState({}); const fetchData = async () => { try { if (ports.length === 0) return; // Fetch all ports concurrently const promises = ports.map(port => fetch(`api/history?devName=${encodeURIComponent(controllerName)}&port=${port.port}&range=${range}`) .then(res => res.json()) .then(data => ({ port: port.port, data })) ); const results = await Promise.all(promises); const newPortData = {}; results.forEach(item => { newPortData[item.port] = item.data; }); setPortData(newPortData); // Use the data from the first port for the Environment Chart // This avoids a redundant network request if (results.length > 0) { setEnvData(results[0].data); } } catch (err) { console.error("Fetch error", err); } }; // Initial Fetch & Auto-Refresh useEffect(() => { fetchData(); const interval = setInterval(fetchData, 60000); return () => clearInterval(interval); }, [controllerName, range]); // Depend on range, controllerName changes rarely return ( {/* Environment Chart */} {t('controller.environment')} {/* Port Grid */} {ports.map((port) => { const isLight = port.port_name && port.port_name.toLowerCase().includes('light'); const isCO2 = port.port_name && port.port_name.toLowerCase().includes('co2'); const pData = portData[port.port] || []; return ( {port.port_name || `${t('controller.port')} ${port.port}`} ); })} ); }