Show eventlog in live view

This commit is contained in:
Thomas Basler 2022-07-09 12:44:13 +02:00
parent c2a7f487f1
commit 06529f7187
2 changed files with 125 additions and 5 deletions

View File

@ -23,13 +23,26 @@
:id="'v-pills-' + inverter.serial" role="tabpanel" :id="'v-pills-' + inverter.serial" role="tabpanel"
:aria-labelledby="'v-pills-' + inverter.serial + '-tab'" tabindex="0"> :aria-labelledby="'v-pills-' + inverter.serial + '-tab'" tabindex="0">
<div class="card"> <div class="card">
<div class="card-header text-white bg-primary" :class="{ <div class="card-header text-white bg-primary d-flex justify-content-between align-items-center"
'bg-danger': inverter.age_critical, :class="{
'bg-primary': !inverter.age_critical, 'bg-danger': inverter.age_critical,
}"> 'bg-primary': !inverter.age_critical,
}">
{{ inverter.name }} (Inverter Serial Number: {{ inverter.name }} (Inverter Serial Number:
{{ inverter.serial }}) (Data Age: {{ inverter.serial }}) (Data Age:
{{ inverter.data_age }} seconds) {{ inverter.data_age }} seconds)
<button v-if="inverter.events >= 0" type="button"
class="btn btn-sm btn-secondary position-relative"
@click="onShowEventlog(inverter.serial)"
title="Show Eventlog">
<BIconJournalText style="font-size:24px;" />
<span
class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">
{{ inverter.events }}
<span class="visually-hidden">unread messages</span>
</span>
</button>
</div> </div>
<div class="card-body"> <div class="card-body">
<div class="row flex-row-reverse flex-wrap-reverse align-items-end g-3"> <div class="row flex-row-reverse flex-wrap-reverse align-items-end g-3">
@ -47,6 +60,33 @@
</div> </div>
</div> </div>
</template> </template>
<div class="modal" id="eventView" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Event Log</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="text-center" v-if="eventLogLoading">
<div class="spinner-border" role="status">
<span class="visually-hidden">Loading...</span>
</div>
</div>
<EventLog v-if="!eventLogLoading" :eventLogList="eventLogList" />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" @click="onHideEventlog"
data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div> </div>
</template> </template>
@ -54,17 +94,20 @@
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import InverterChannelInfo from "@/components/partials/InverterChannelInfo.vue"; import InverterChannelInfo from "@/components/partials/InverterChannelInfo.vue";
import * as bootstrap from 'bootstrap'; import * as bootstrap from 'bootstrap';
import EventLog from '@/components/partials/EventLog.vue';
declare interface Inverter { declare interface Inverter {
serial: number, serial: number,
name: string, name: string,
age_critical: boolean, age_critical: boolean,
data_age: 0 data_age: 0,
events: 0
} }
export default defineComponent({ export default defineComponent({
components: { components: {
InverterChannelInfo, InverterChannelInfo,
EventLog
}, },
data() { data() {
return { return {
@ -73,11 +116,17 @@ export default defineComponent({
waitForData: true, waitForData: true,
inverterData: [] as Inverter[], inverterData: [] as Inverter[],
isFirstFetchAfterConnect: true, isFirstFetchAfterConnect: true,
eventLogView: {} as bootstrap.Modal,
eventLogList: {},
eventLogLoading: true
}; };
}, },
created() { created() {
this.initSocket(); this.initSocket();
}, },
mounted() {
this.eventLogView = new bootstrap.Modal('#eventView');
},
unmounted() { unmounted() {
this.closeSocket(); this.closeSocket();
}, },
@ -140,6 +189,20 @@ export default defineComponent({
this.heartInterval && clearTimeout(this.heartInterval); this.heartInterval && clearTimeout(this.heartInterval);
this.isFirstFetchAfterConnect = true; this.isFirstFetchAfterConnect = true;
}, },
onHideEventlog() {
this.eventLogView.hide();
},
onShowEventlog(serial: number) {
this.eventLogLoading = true;
fetch("/api/eventlog/status")
.then((response) => response.json())
.then((data) => {
this.eventLogList = data[serial];
this.eventLogLoading = false;
});
this.eventLogView.show();
},
}, },
}); });
</script> </script>

View File

@ -0,0 +1,57 @@
<template>
<table class="table table-hover">
<thead>
<th scope="col">Start</th>
<th scope="col">Stop</th>
<th scope="col">ID</th>
<th scope="col">Message</th>
</thead>
<tbody>
<template v-for="event in eventLogList.count" :key="event">
<tr>
<td>{{ timeInHours(eventLogList.events[event - 1].start_time) }}</td>
<td>{{ timeInHours(eventLogList.events[event - 1].end_time) }}</td>
<td>{{ eventLogList.events[event - 1].message_id }}</td>
<td>{{ eventLogList.events[event - 1].message }}</td>
</tr>
</template>
</tbody>
</table>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
declare interface EventData {
message_id: number,
message: string,
start_time: number,
end_time: number
}
declare interface EventLogData {
count: number,
events: { [key: number]: EventData }
}
export default defineComponent({
props: {
eventLogList: { type: Object as () => EventLogData, required: true },
},
computed: {
timeInHours() {
return (value: number) => {
const hours = Math.floor((value) / 3600);
const minutes = Math.floor((value - hours * 3600) / 60);
const seconds = (value - hours * 3600 + minutes * 60) % 60;
const dHours = hours > 9 ? hours : "0" + hours;
const dMins = minutes > 9 ? minutes : "0" + minutes;
const dSecs = seconds > 9 ? seconds : "0" + seconds;
return dHours + ":" + dMins + ":" + dSecs;
};
},
},
});
</script>