135 lines
4.3 KiB
HTML
135 lines
4.3 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>Ecu Watcher</title>
|
|
<script src="https://cdn.jsdelivr.net/npm/vue@3"></script>
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
|
|
</head>
|
|
<body>
|
|
<div id="app">
|
|
<h1>Ecu Watcher</h1>
|
|
<div v-if="!ecuSelected">
|
|
<h2>Select ECU</h2>
|
|
<select v-model="selectedEcu" @change="fetchStatesAndParameters">
|
|
<option v-for="ecu in ecuList" :value="ecu" :key="ecu">
|
|
{{ ecu }}
|
|
</option>
|
|
</select>
|
|
</div>
|
|
<div v-else-if="!watching">
|
|
<h2>Selected ECU: {{ selectedEcu }}</h2>
|
|
<div>
|
|
<h2>States and Parameters</h2>
|
|
<div v-for="(text, code) in statesAndParams" :key="code">
|
|
<input type="checkbox" v-model="selectedItems" :value="code" />{{
|
|
text }}
|
|
</div>
|
|
<button @click="watch">Watch</button>
|
|
</div>
|
|
</div>
|
|
<div v-if="watching">
|
|
<h2>Watching</h2>
|
|
<button style="width: auto; height: auto; font-size: xx-large;" v-if="logging" @click="sendFreeze">FREEZE</button><br>
|
|
<div v-for="item in selectedItems" :key="item">
|
|
{{ statesAndParams[item] }}: {{ itemValues[item] }}
|
|
</div>
|
|
<button @click="startWatch">Start</button>
|
|
<button @click="stopWatch">Stop</button>
|
|
<label>
|
|
Log:
|
|
<input type="checkbox" v-model="logging" />
|
|
</label>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const socket = io();
|
|
const app = Vue.createApp({
|
|
data() {
|
|
return {
|
|
ecuList: [],
|
|
selectedEcu: "",
|
|
ecuSelected: false,
|
|
statesAndParams: {},
|
|
selectedItems: [],
|
|
itemValues: {},
|
|
watching: false,
|
|
logging: false,
|
|
};
|
|
},
|
|
methods: {
|
|
async fetchEcuList() {
|
|
try {
|
|
const response = await fetch("/ecus");
|
|
this.ecuList = await response.json();
|
|
} catch (error) {
|
|
console.error("Error fetching ECU list", error);
|
|
}
|
|
},
|
|
async fetchStatesAndParameters() {
|
|
try {
|
|
const response = await fetch(`/ecus/${this.selectedEcu}/states`);
|
|
const states = await response.json();
|
|
this.statesAndParams = { ...states };
|
|
const paramResponse = await fetch(
|
|
`/ecus/${this.selectedEcu}/parameters`
|
|
);
|
|
const parameters = await paramResponse.json();
|
|
for (const param in parameters) {
|
|
this.statesAndParams[param] = parameters[param];
|
|
}
|
|
this.ecuSelected = true;
|
|
} catch (error) {
|
|
console.error("Error fetching states and parameters", error);
|
|
}
|
|
},
|
|
async watch() {
|
|
try {
|
|
const response = await fetch(`/ecus/${this.selectedEcu}/watch`, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(this.selectedItems),
|
|
});
|
|
if (response.ok) {
|
|
this.watching = true;
|
|
} else {
|
|
console.error("Error starting watch");
|
|
}
|
|
} catch (error) {
|
|
console.error("Error starting watch", error);
|
|
}
|
|
},
|
|
async stopWatch() {
|
|
await fetch(`/stop`, {
|
|
method: "GET",
|
|
});
|
|
},
|
|
async startWatch() {
|
|
await fetch(`/start?log=${this.logging ? "true" : "false"}`, {
|
|
method: "GET",
|
|
});
|
|
},
|
|
async sendFreeze() {
|
|
socket.emit("freeze");
|
|
}
|
|
},
|
|
mounted() {
|
|
this.fetchEcuList();
|
|
socket.on("frame", (msg) => {
|
|
const data = msg.frame;
|
|
for (let i = 0; i < this.selectedItems.length; i++) {
|
|
this.itemValues[this.selectedItems[i]] = data[i];
|
|
}
|
|
});
|
|
},
|
|
});
|
|
|
|
app.mount("#app");
|
|
</script>
|
|
</body>
|
|
</html>
|