diff --git a/webapp/frontend/src/components/Chart/PowerMetrics/ChannelData.vue b/webapp/frontend/src/components/Chart/PowerMetrics/ChannelData.vue index cfde9fb..16c376d 100644 --- a/webapp/frontend/src/components/Chart/PowerMetrics/ChannelData.vue +++ b/webapp/frontend/src/components/Chart/PowerMetrics/ChannelData.vue @@ -1,8 +1,8 @@ @@ -10,13 +10,13 @@
  • Channel {{ channel }}
    - - - {{ Number(selectedNodeLatestPowerMetric[`ch${channel}_voltage`]).toFixed(2) }}V + + + {{ Number(latest[`ch${channel}_voltage`]).toFixed(2) }}V ??? - - / {{ Number(selectedNodeLatestPowerMetric[`ch${channel}_current`]).toFixed(2) }}mA + + / {{ Number(latest[`ch${channel}_current`]).toFixed(2) }}mA ??? diff --git a/webapp/frontend/src/components/NodeInfo.vue b/webapp/frontend/src/components/NodeInfo.vue index 8ba60a5..c554f31 100644 --- a/webapp/frontend/src/components/NodeInfo.vue +++ b/webapp/frontend/src/components/NodeInfo.vue @@ -20,16 +20,62 @@ import { copyShareLinkForNode, getTimeSpan, buildPath } from '@/utils'; import { useConfigStore } from '@/stores/configStore'; const configStore = useConfigStore(); -const emit = defineEmits(['showPositionHistory']); +const emit = defineEmits(['showPositionHistory', 'showTraceRoute']); const mapData = useMapStore(); -function showPositionHistory(id) { - emit('showPositionHistory', id); +const mqttMetrics = ref([]); +const traceroutes = ref([]); +const deviceMetrics = ref([]); +const environmentMetrics = ref([]); +const powerMetrics = ref([]); + +// Generalized function for loading data +async function loadData(path, params = {}, targetRef, metrics = false) { + try { + const response = await axios.get(buildPath(path), { params }); + + // Grab the first key from the response (assuming it's always an object with a single data array) + const key = Object.keys(response.data)[0]; + const rawData = response.data[key] ?? []; + + // Reverse if it's metric data, otherwise just assign + targetRef.value = metrics ? rawData.slice().reverse() : rawData; + + } catch (error) { + console.error(`Error loading data from ${path}:`, error); + targetRef.value = []; + } } -function showTraceRoute(traceroute) { - emit('showTraceRoute', traceroute); - state.selectedTraceRoute = traceroute; +// Utility function to calculate the timeFrom value based on a given time range +function calculateTimeFrom(timeRange) { + const time = getTimeSpan(timeRange).amount; + return new Date().getTime() - (time * 1000); +} + +// Load MQTT metrics +function loadNodeMqttMetrics(nodeId) { + loadData(`/api/v1/nodes/${nodeId}/mqtt-metrics`, {}, mqttMetrics); +} + +// Load Traceroutes +function loadNodeTraceroutes(nodeId) { + loadData(`/api/v1/nodes/${nodeId}/traceroutes`, { count: 5 }, traceroutes); +} + +// Load Device Metrics +function loadNodeDeviceMetrics(nodeId) { + loadData(`/api/v1/nodes/${nodeId}/device-metrics`, { time_from: calculateTimeFrom(configStore.deviceMetricsTimeRange) }, deviceMetrics, true); +} + +// Load Environment Metrics +function loadNodeEnvironmentMetrics(nodeId) { + loadData(`/api/v1/nodes/${nodeId}/environment-metrics`, { time_from: calculateTimeFrom(configStore.environmentMetricsTimeRange) }, environmentMetrics, true); +} + +// Load Power Metrics +function loadNodePowerMetrics(nodeId) { + loadData(`/api/v1/nodes/${nodeId}/power-metrics`, { time_from: calculateTimeFrom(configStore.powerMetricsTimeRange) }, powerMetrics, true); } function loadNode(nodeId) { @@ -40,73 +86,6 @@ function loadNode(nodeId) { loadNodePowerMetrics(nodeId); } -function loadNodeMqttMetrics(nodeId) { - state.selectedNodeMqttMetrics = []; - axios.get(buildPath(`/api/v1/nodes/${nodeId}/mqtt-metrics`)).then((response) => { - state.selectedNodeMqttMetrics = response.data.mqtt_metrics; - }).catch(() => { - // do nothing - }); -} - -function loadNodeTraceroutes(nodeId) { - state.selectedNodeTraceroutes = []; - axios.get(buildPath(`/api/v1/nodes/${nodeId}/traceroutes`), { - params: { - count: 5, - }, - }).then((response) => { - state.selectedNodeTraceroutes = response.data.traceroutes; - }).catch(() => { - // do nothing - }); -} - -function loadNodeDeviceMetrics(nodeId) { - const time = getTimeSpan(configStore.deviceMetricsTimeRange).amount - const timeFrom = new Date().getTime() - (time * 1000); - axios.get(buildPath(`/api/v1/nodes/${nodeId}/device-metrics`), { - params: { - time_from: timeFrom, - }, - }).then((response) => { - // reverse response, as it's newest to oldest, but we want oldest to newest - state.selectedNodeDeviceMetrics = response.data.device_metrics.reverse(); - }).catch(() => { - state.selectedNodeDeviceMetrics = []; - }); -} - -function loadNodeEnvironmentMetrics(nodeId) { - const time = getTimeSpan(configStore.environmentMetricsTimeRange).amount - const timeFrom = new Date().getTime() - (time * 1000); - axios.get(buildPath(`/api/v1/nodes/${nodeId}/environment-metrics`), { - params: { - time_from: timeFrom, - }, - }).then((response) => { - // reverse response, as it's newest to oldest, but we want oldest to newest - state.selectedNodeEnvironmentMetrics = response.data.environment_metrics.reverse(); - }).catch(() => { - state.selectedNodeEnvironmentMetrics = []; - }); -} - -function loadNodePowerMetrics(nodeId) { - const time = getTimeSpan(configStore.powerMetricsTimeRange).amount - const timeFrom = new Date().getTime() - (time * 1000); - axios.get(buildPath(`/api/v1/nodes/${nodeId}/power-metrics`), { - params: { - time_from: timeFrom, - }, - }).then((response) => { - // reverse response, as it's newest to oldest, but we want oldest to newest - state.selectedNodePowerMetrics = response.data.power_metrics.reverse(); - }).catch(() => { - state.selectedNodePowerMetrics = []; - }); -} - watch( () => state.selectedNode, (newValue) => { @@ -263,17 +242,17 @@ watch( - + - + - + - + - + - + diff --git a/webapp/frontend/src/components/NodeInfo/DeviceMetricsChart.vue b/webapp/frontend/src/components/NodeInfo/DeviceMetricsChart.vue index f1b4bd8..cbf9797 100644 --- a/webapp/frontend/src/components/NodeInfo/DeviceMetricsChart.vue +++ b/webapp/frontend/src/components/NodeInfo/DeviceMetricsChart.vue @@ -1,12 +1,10 @@