Added axios requests to show the nodes from the database, added calculator for battery level and input field for la and lo
This commit is contained in:
parent
fe65349b54
commit
b2f6f216f6
|
@ -17,6 +17,6 @@ body:json {
|
|||
"coord_lo":2,
|
||||
"battery_minimum":3,
|
||||
"battery_maximum":4,
|
||||
"group":"20abe318-7238-4f63-908f-a484955ee3bc"
|
||||
"group":"54eccfb5-1d5a-4cad-a1a2-468eca68ffd6"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
<div class="d-flex flex-column">
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<span class="mr-2">Coordinates:</span>
|
||||
<span>La: {{ node.coordla }}, Long: {{ node.coordlong }}</span>
|
||||
<span>La: {{ node.coord_la }}, Long: {{ node.coord_lo }}</span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<span class="mr-2">Temperature:</span>
|
||||
<span>{{ sensorData?.temperature }}°C</span>
|
||||
<span>{{ sensorData?.temperature !== undefined ? sensorData.temperature : 'NaN' }}°C</span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<span class="mr-2">Battery Voltage:</span>
|
||||
|
@ -30,9 +30,9 @@
|
|||
</div>
|
||||
<div class="d-flex align-items-center mb-2">
|
||||
<span class="mr-2">Runtime:</span>
|
||||
<span>{{ sensorData?.uptime }} hours</span>
|
||||
</div>
|
||||
<span>{{ sensorData?.uptime ? (sensorData.uptime / 3600).toFixed(2) + ' hours' : 'N/A' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</v-expansion-panel-text>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
|
@ -62,24 +62,10 @@ watch([searching, visibleIds], ([searching, visibleIds]) => {
|
|||
onMounted(async () => {
|
||||
try {
|
||||
const { data } = await axios.get<SensorData>(
|
||||
`http://localhost:8080/api/v1/data?nodeId=${props.node.id}`
|
||||
`http://localhost:8080/api/v1/data?id=${props.node.id}`
|
||||
);
|
||||
sensorData.value = data;
|
||||
} catch (error) {
|
||||
console.error("Error fetching sensor data:", error);
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.values {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.v-text-field {
|
||||
max-width: 200px;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -14,25 +14,25 @@
|
|||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(node, index) in tableData" :key="index">
|
||||
<td>{{ node.name }}</td>
|
||||
<td>{{ node.id }}</td>
|
||||
<td>
|
||||
<span :class="node.sensorData.voltage ? 'status-online' : 'status-offline'">
|
||||
{{ node.sensorData.voltage ? 'ONLINE' : 'OFFLINE' }}
|
||||
<span :class="node.sensorData.voltage !== 'N/A' ? 'status-online' : 'status-offline'">
|
||||
{{ node.sensorData.voltage !== 'N/A' ? 'ONLINE' : 'OFFLINE' }}
|
||||
</span>
|
||||
</td>
|
||||
<td
|
||||
contenteditable="true"
|
||||
@blur="validateAndUpdateLatLng(node, 'coordla', $event)"
|
||||
>{{ node.coordla }}</td>
|
||||
@blur="validateAndUpdateLatLng(node, 'coord_la', $event)"
|
||||
>{{ node.coord_la }}</td>
|
||||
<td
|
||||
contenteditable="true"
|
||||
@blur="validateAndUpdateLatLng(node, 'coordlong', $event)"
|
||||
>{{ node.coordlong }}</td>
|
||||
<td>{{ calculateBatteryPercentage(node.sensorData.voltage, node.batteryMinimum, node.batteryMaximum) }}%</td>
|
||||
@blur="validateAndUpdateLatLng(node, 'coord_lo', $event)"
|
||||
>{{ node.coord_lo }}</td>
|
||||
<td>{{ calculateBatteryPercentage(node.sensorData.voltage, node.battery_minimum, node.battery_maximum) }}%</td>
|
||||
<td>{{ node.sensorData.temperature }}°C</td>
|
||||
<td>{{ formatRuntime(node.sensorData.uptime) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -50,29 +50,32 @@ export default {
|
|||
this.fetchNodesAndData();
|
||||
},
|
||||
methods: {
|
||||
async fetchNodesAndData() {
|
||||
try {
|
||||
const nodesResponse = await axios.get('http://localhost:8080/api/v1/nodes');
|
||||
const nodes = nodesResponse.data;
|
||||
async fetchNodesAndData() {
|
||||
try {
|
||||
const nodeGroupsResponse = await axios.get('http://localhost:8080/api/v1/nodes');
|
||||
const nodeGroups = nodeGroupsResponse.data;
|
||||
|
||||
const sensorDataResponse = await axios.get('http://localhost:8080/api/v1/data');
|
||||
const sensorData = sensorDataResponse.data;
|
||||
const nodes = nodeGroups.flatMap(group => group.node);
|
||||
|
||||
this.tableData = nodes.map((node) => {
|
||||
const nodeSensorData = sensorData.find((data) => data.id === node.id);
|
||||
return {
|
||||
...node,
|
||||
sensorData: nodeSensorData || {
|
||||
temperature: 'N/A',
|
||||
voltage: 'N/A',
|
||||
uptime: 'N/A',
|
||||
},
|
||||
};
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error fetching node or sensor data:', error);
|
||||
}
|
||||
},
|
||||
const sensorDataResponse = await axios.get('http://localhost:8080/api/v1/data');
|
||||
const sensorDataArray = sensorDataResponse.data;
|
||||
|
||||
this.tableData = nodes.map(node => {
|
||||
const nodeSensorData = sensorDataArray.find(data => data.node.id === node.id);
|
||||
|
||||
return {
|
||||
...node,
|
||||
sensorData: nodeSensorData ? nodeSensorData.sensor_data : {
|
||||
temperature: 'N/A',
|
||||
voltage: 'N/A',
|
||||
uptime: 'N/A',
|
||||
},
|
||||
};
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error fetching node or sensor data:', error);
|
||||
}
|
||||
},
|
||||
calculateBatteryPercentage(voltage, batteryMinimum, batteryMaximum) {
|
||||
if (voltage <= batteryMinimum) {
|
||||
return 0;
|
||||
|
@ -92,22 +95,16 @@ export default {
|
|||
const originalValue = node[field];
|
||||
let newValue = event.target.innerText;
|
||||
|
||||
// Normalize separated values
|
||||
newValue = newValue.replace(',', '.');
|
||||
|
||||
// Check if it's a valid float value
|
||||
const validNumberRegex = /^-?\d+(\.\d+)?$/;
|
||||
|
||||
if (validNumberRegex.test(newValue)) {
|
||||
const parsedValue = parseFloat(newValue);
|
||||
|
||||
// Update if valid
|
||||
node[field] = parsedValue;
|
||||
console.log(`Updated ${field} of ${node.name}: ${parsedValue}`);
|
||||
console.log(`Updated ${field} of ${node.id}: ${parsedValue}`);
|
||||
} else {
|
||||
// Reset to original value if invalid
|
||||
event.target.innerText = originalValue;
|
||||
console.log(`Failed to set ${field} of ${node.name}: Invalid input "${newValue}"`);
|
||||
console.log(`Failed to set ${field} of ${node.id}: Invalid input "${newValue}"`);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -115,7 +112,6 @@ export default {
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* Styling remains the same */
|
||||
.table-container {
|
||||
background-color: white;
|
||||
padding: 0.5rem 1rem;
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
export interface Node {
|
||||
id: string;
|
||||
coordla: number;
|
||||
coordlong: number;
|
||||
batteryMinimum: number;
|
||||
batteryMaximum: number;
|
||||
coord_la: number;
|
||||
coord_lo: number;
|
||||
battery_minimum: number;
|
||||
battery_maximum: number;
|
||||
group: string;
|
||||
sensorData: SensorData[];
|
||||
}
|
||||
|
||||
export interface NodeGroup {
|
||||
id: string;
|
||||
name: string;
|
||||
node: Node[];
|
||||
}
|
||||
|
||||
export interface SensorData {
|
||||
|
|
Loading…
Reference in a new issue