update
This commit is contained in:
@@ -37,15 +37,15 @@
|
|||||||
<input
|
<input
|
||||||
v-model.number="numericValue"
|
v-model.number="numericValue"
|
||||||
type="range"
|
type="range"
|
||||||
:min="action.parameters.min"
|
:min="action.parameters?.min"
|
||||||
:max="action.parameters.max"
|
:max="action.parameters?.max"
|
||||||
:step="action.parameters.step"
|
:step="action.parameters?.step"
|
||||||
class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer slider"
|
class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer slider"
|
||||||
/>
|
/>
|
||||||
<div class="flex justify-between text-sm text-gray-600">
|
<div class="flex justify-between text-sm text-gray-600">
|
||||||
<span>{{ action.parameters.min }}</span>
|
<span>{{ action.parameters?.min }}</span>
|
||||||
<span class="font-medium">{{ numericValue }}{{ getUnit() }}</span>
|
<span class="font-medium">{{ numericValue }}{{ getUnit() }}</span>
|
||||||
<span>{{ action.parameters.max }}</span>
|
<span>{{ action.parameters?.max }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -157,9 +157,9 @@ watch(
|
|||||||
(action) => {
|
(action) => {
|
||||||
if (action) {
|
if (action) {
|
||||||
if (action.parameters?.min !== undefined) {
|
if (action.parameters?.min !== undefined) {
|
||||||
numericValue.value = action.parameters.min
|
numericValue.value = action.parameters?.min ?? 0
|
||||||
}
|
}
|
||||||
if (action.parameters?.options?.length > 0) {
|
if (action.parameters?.options && action.parameters.options.length > 0) {
|
||||||
selectedOption.value = action.parameters.options[0]
|
selectedOption.value = action.parameters.options[0]
|
||||||
}
|
}
|
||||||
toggleValue.value = false
|
toggleValue.value = false
|
||||||
|
|||||||
@@ -379,14 +379,14 @@ class ApiClient {
|
|||||||
return await response.json()
|
return await response.json()
|
||||||
}
|
}
|
||||||
|
|
||||||
async post<T>(endpoint: string, data?: Record<string, unknown> | unknown[]): Promise<T> {
|
async post<T>(endpoint: string, data?: unknown): Promise<T> {
|
||||||
return this.request<T>(endpoint, {
|
return this.request<T>(endpoint, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: data ? JSON.stringify(data) : undefined,
|
body: data ? JSON.stringify(data) : undefined,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async put<T>(endpoint: string, data?: Record<string, unknown> | unknown[]): Promise<T> {
|
async put<T>(endpoint: string, data?: unknown): Promise<T> {
|
||||||
return this.request<T>(endpoint, {
|
return this.request<T>(endpoint, {
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
body: data ? JSON.stringify(data) : undefined,
|
body: data ? JSON.stringify(data) : undefined,
|
||||||
|
|||||||
@@ -5,15 +5,15 @@ import { useRoomStore } from './room'
|
|||||||
|
|
||||||
const MAX_DATA_POINTS = 100
|
const MAX_DATA_POINTS = 100
|
||||||
|
|
||||||
interface SensorReading {
|
interface WebSocketReading {
|
||||||
sensorId: string
|
sensorId: string
|
||||||
room: string
|
room: string
|
||||||
timestamp: number
|
timestamp: number
|
||||||
energy: {
|
energy?: {
|
||||||
value: number
|
value: number
|
||||||
unit: string
|
unit: string
|
||||||
}
|
}
|
||||||
co2: {
|
co2?: {
|
||||||
value: number
|
value: number
|
||||||
unit: string
|
unit: string
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,7 @@ interface SensorReading {
|
|||||||
|
|
||||||
export const useWebSocketStore = defineStore('websocket', () => {
|
export const useWebSocketStore = defineStore('websocket', () => {
|
||||||
const isConnected = ref<boolean>(false)
|
const isConnected = ref<boolean>(false)
|
||||||
const latestMessage = ref<SensorReading | null>(null)
|
const latestMessage = ref<WebSocketReading | null>(null)
|
||||||
const timeSeriesData = reactive<{
|
const timeSeriesData = reactive<{
|
||||||
labels: string[]
|
labels: string[]
|
||||||
datasets: { data: number[] }[]
|
datasets: { data: number[] }[]
|
||||||
@@ -35,7 +35,7 @@ export const useWebSocketStore = defineStore('websocket', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
let socket: WebSocket | null = null
|
let socket: WebSocket | null = null
|
||||||
const newDataBuffer: SensorReading[] = []
|
const newDataBuffer: WebSocketReading[] = []
|
||||||
|
|
||||||
function connect(url: string): void {
|
function connect(url: string): void {
|
||||||
if (isConnected.value && socket) {
|
if (isConnected.value && socket) {
|
||||||
@@ -115,9 +115,9 @@ export const useWebSocketStore = defineStore('websocket', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function processIncomingData(data: SensorReading): void {
|
function processIncomingData(data: WebSocketReading): void {
|
||||||
// Skip non-data messages
|
// Skip non-data messages
|
||||||
if ('type' in data && (data.type === 'connection_established' || data.type === 'proxy_info')) {
|
if ('type' in data && (data as any).type === 'connection_established' || (data as any).type === 'proxy_info') {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,21 +125,21 @@ export const useWebSocketStore = defineStore('websocket', () => {
|
|||||||
const roomStore = useRoomStore()
|
const roomStore = useRoomStore()
|
||||||
|
|
||||||
// Update individual sensor readings first
|
// Update individual sensor readings first
|
||||||
sensorStore.updateLatestReading(data)
|
sensorStore.updateLatestReading(data as any)
|
||||||
|
|
||||||
// Update room data if we have room information (accepts partial readings)
|
// Update room data if we have room information (accepts partial readings)
|
||||||
if (data.room) {
|
if (data.room) {
|
||||||
if (data.energy) {
|
if (data.energy) {
|
||||||
sensorStore.updateEnergySensors(data)
|
sensorStore.updateEnergySensors(data as any)
|
||||||
}
|
}
|
||||||
roomStore.updateRoomData(data)
|
roomStore.updateRoomData(data as any)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update time series for chart if energy data is available
|
// Update time series for chart if energy data is available
|
||||||
if (data.energy) {
|
if (data.energy) {
|
||||||
const newLabel = new Date(data.timestamp * 1000).toLocaleTimeString()
|
const newLabel = new Date(data.timestamp * 1000).toLocaleTimeString()
|
||||||
timeSeriesData.labels.push(newLabel)
|
timeSeriesData.labels.push(newLabel)
|
||||||
timeSeriesData.datasets[0].data.push(data.energy?.value)
|
timeSeriesData.datasets[0].data.push(data.energy.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -222,11 +222,11 @@
|
|||||||
<div v-else class="space-y-3">
|
<div v-else class="space-y-3">
|
||||||
<div
|
<div
|
||||||
v-for="room in apiRooms"
|
v-for="room in apiRooms"
|
||||||
:key="room.name || room.room"
|
:key="room.room"
|
||||||
class="p-3 bg-gray-50 rounded-lg"
|
class="p-3 bg-gray-50 rounded-lg"
|
||||||
>
|
>
|
||||||
<div class="flex items-center justify-between mb-2">
|
<div class="flex items-center justify-between mb-2">
|
||||||
<p class="font-medium text-gray-900">{{ room.name || room.room }}</p>
|
<p class="font-medium text-gray-900">{{ room.room }}</p>
|
||||||
<span class="text-sm text-gray-500">{{ room.sensor_count }} sensors</span>
|
<span class="text-sm text-gray-500">{{ room.sensor_count }} sensors</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-xs text-gray-600 space-y-1">
|
<div class="text-xs text-gray-600 space-y-1">
|
||||||
|
|||||||
@@ -184,7 +184,7 @@
|
|||||||
|
|
||||||
<!-- Action Modal -->
|
<!-- Action Modal -->
|
||||||
<ActionModal
|
<ActionModal
|
||||||
v-if="showActionModal"
|
v-if="showActionModal && selectedSensor && selectedAction"
|
||||||
:sensor="selectedSensor"
|
:sensor="selectedSensor"
|
||||||
:action="selectedAction"
|
:action="selectedAction"
|
||||||
@execute="handleActionExecute"
|
@execute="handleActionExecute"
|
||||||
|
|||||||
Reference in New Issue
Block a user