Skip to content

Commit

Permalink
ping-viewer-next-frontend: Add Ping1D widget
Browse files Browse the repository at this point in the history
  • Loading branch information
RaulTrombin committed Sep 24, 2024
1 parent 8094ff2 commit b725c83
Show file tree
Hide file tree
Showing 4 changed files with 483 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import Sonar360 from '../widgets/Sonar360.vue'
import WebsocketClient from '../widgets/WebsocketClient.vue'
import DevicesCardboard from '../widgets/DevicesCardboard.vue'
import Sonar360Menu from '../widgets/Sonar360Menu.vue'
import Ping1D_loader from '../widgets/Ping1D_loader.vue'
const selectedComponent = ref('WebsocketClient')
const isCollapsed = ref(false)
Expand All @@ -35,7 +36,8 @@ const components = {
DynamicFormGenerator,
DynamicForm,
Sonar360,
Sonar360Menu
Sonar360Menu,
Ping1D_loader
}
const toggleSidebar = () => {
Expand Down
109 changes: 109 additions & 0 deletions ping-viewer-next-frontend/src/components/widgets/Ping1D.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<template>
<div class="flex flex-col bg-gray-900 p-4">
<div class="flex-grow overflow-hidden">
<WaterfallShader
:width="400"
:height="226"
:column-count="columnCount"
:sensor-data="sensorData"
:color-palette="colorPalette"
@update:columnCount="columnCount = $event"
/>
</div>
</div>
</template>

<script>
import { ref, reactive, watch, onUnmounted } from 'vue';
import WaterfallShader from './WaterfallShader.vue';
export default {
components: {
WaterfallShader
},
props: {
websocketUrl: {
type: String,
required: true
},
colorPalette: {
type: String,
required: true
},
isConnected: {
type: Boolean,
required: true
}
},
emits: ['update:lastUpdateTime', 'update:isConnected'],
setup(props, { emit }) {
const columnCount = ref(100);
const sensorData = reactive([]);
let socket = null;
watch(() => props.isConnected, (newIsConnected) => {
if (newIsConnected) {
connectWebSocket();
} else {
disconnectWebSocket();
}
});
function connectWebSocket() {
if (socket) return;
socket = new WebSocket(props.websocketUrl);
socket.onopen = () => {
console.log('WebSocket connected');
emit('update:isConnected', true);
};
socket.onmessage = (event) => {
try {
const parsedData = JSON.parse(event.data);
const profileData = parsedData.DeviceMessage.PingMessage.Ping1D.Profile.profile_data;
sensorData.splice(0, sensorData.length, ...profileData);
emit('update:lastUpdateTime', new Date().toLocaleTimeString());
console.log('Received new sensor data:', profileData.length, 'values');
} catch (error) {
console.error('Error parsing WebSocket data:', error);
}
};
socket.onerror = (error) => {
console.error('WebSocket error:', error);
};
socket.onclose = () => {
console.log('WebSocket disconnected');
emit('update:isConnected', false);
socket = null;
};
}
function disconnectWebSocket() {
if (socket) {
socket.close();
socket = null;
}
}
onUnmounted(() => {
disconnectWebSocket();
});
watch(() => sensorData, (newData) => {
console.log('sensorData updated:', newData.length, 'values');
}, { deep: true });
return {
columnCount,
sensorData
};
}
};
</script>
129 changes: 129 additions & 0 deletions ping-viewer-next-frontend/src/components/widgets/Ping1D_loader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<template>
<div class="ping1d-loader-container">
<div class="ping1d-loader-content">
<h2 class="text-2xl font-bold text-white mb-4">Ping1D Waterfall Display</h2>

<div class="mb-4">
<label for="websocketUrl" class="block text-sm font-medium text-gray-300">WebSocket URL:</label>
<input
id="websocketUrl"
v-model="websocketUrl"
type="text"
class="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md bg-gray-700 text-white"
placeholder="Enter WebSocket URL"
/>
</div>

<div class="mb-4 flex items-center justify-between">
<div class="w-1/2 mr-2">
<label for="colorPalette" class="block text-sm font-medium text-gray-300">Color Palette:</label>
<select
id="colorPalette"
v-model="selectedColorPalette"
class="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md bg-gray-700 text-white"
>
<option v-for="palette in colorPalettes" :key="palette.value" :value="palette.value">
{{ palette.label }}
</option>
</select>
</div>
<div class="w-1/2 ml-2">
<button @click="toggleWebSocket" class="w-full px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors">
{{ isConnected ? 'Disconnect' : 'Connect' }} WebSocket
</button>
</div>
</div>

<div class="mb-4 text-white">
Last update: {{ lastUpdateTime }}
</div>

<div class="ping1d-display">
<Ping1D
:websocket-url="websocketUrl"
:color-palette="selectedColorPalette"
:is-connected="isConnected"
@update:lastUpdateTime="lastUpdateTime = $event"
@update:isConnected="isConnected = $event"
/>
</div>
</div>
</div>
</template>

<script>
import { ref, onMounted } from 'vue';
import Ping1D from './Ping1D.vue';
export default {
components: {
Ping1D
},
setup() {
const websocketUrl = ref('');
onMounted(() => {
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
const host = window.location.host;
websocketUrl.value = `${protocol}//${host}/ws?device_number=00000000-0000-0000-1cc4-7b702224f52d`;
});
const colorPalettes = [
{ value: 'transparent', label: 'Transparent' },
{ value: 'heatmap', label: 'Heatmap' },
{ value: 'grayscale', label: 'Grayscale' },
{ value: 'ocean', label: 'Ocean' }
];
const selectedColorPalette = ref('transparent');
const isConnected = ref(false);
const lastUpdateTime = ref('Not updated yet');
function toggleWebSocket() {
if (isConnected.value) {
isConnected.value = false;
} else {
if (websocketUrl.value.trim() !== '') {
isConnected.value = true;
} else {
alert('Please enter a valid WebSocket URL');
}
}
}
return {
websocketUrl,
colorPalettes,
selectedColorPalette,
isConnected,
lastUpdateTime,
toggleWebSocket
};
}
};
</script>

<style scoped>
.ping1d-loader-container {
display: flex;
flex-direction: column;
height: 100%;
background-color: #1a202c;
color: white;
overflow: hidden;
}
.ping1d-loader-content {
flex: 1;
padding: 1rem;
overflow-y: auto;
display: flex;
flex-direction: column;
}
.ping1d-display {
flex: 1;
min-height: 300px;
overflow: hidden;
}
</style>
Loading

0 comments on commit b725c83

Please sign in to comment.