Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <script type="module">
- import { HudiyClient } from "./common/hudiy_client.js";
- const gaugeCanvas = document.getElementById("gaugeCanvas");
- const engineLight = document.getElementById("g246");
- const tempLight = document.getElementById("g243");
- const gaugeCtx = gaugeCanvas.getContext("2d");
- const minSpeed = 0;
- const maxSpeed = 120;
- const maxRPM = 6;
- let speed = 0;
- let targetSpeed = 0;
- let targetRPM = 0;
- let engineTemp = 0;
- let rpm = 0;
- let animating = false;
- let batVoltage = 0.0 + "V";
- let checkEngineVisible = false;
- let engineTempVisible = false;
- let oilLife = 0 + "%";
- function estOilLife(lastChanged) {
- const currentDate = moment();
- const futureDate = moment(lastChanged);
- const daysDiff = futureDate.diff(currentDate, "days");
- oilLife = Math.round(365 / daysDiff) + "%";
- return oilLife;
- }
- function drawNumSp(xoff, yoff, speed) {
- gaugeCtx.font = "118px 'Arial Black'";
- gaugeCtx.fillStyle = "white";
- gaugeCtx.fillText(speed.toString(), xoff, yoff);
- }
- function drawNumTac(xoff, yoff, speed) {
- gaugeCtx.font = "118px 'Arial Black'";
- gaugeCtx.fillStyle = "white";
- gaugeCtx.fillText(speed.toString(), xoff, yoff);
- }
- function drawNumBat(xoff, yoff, speed) {
- gaugeCtx.font = "20px 'Arial Black'";
- gaugeCtx.fillStyle = "white";
- gaugeCtx.fillText(speed.toString(), xoff, yoff);
- }
- function drawNumOil(xoff, yoff, speed) {
- gaugeCtx.font = "20px 'Arial Black'";
- gaugeCtx.fillStyle = "white";
- gaugeCtx.fillText(speed.toString(), xoff, yoff);
- }
- function drawSpeed(xoff, yoff, xmul, ymul) {
- gaugeCtx.beginPath();
- gaugeCtx.moveTo(171 * xmul + xoff, 456 * ymul + yoff);
- gaugeCtx.bezierCurveTo(
- 151 * xmul + xoff,
- 456 * ymul + yoff,
- 139 * xmul + xoff,
- 454 * ymul + yoff,
- 119 * xmul + xoff,
- 454 * ymul + yoff,
- );
- gaugeCtx.bezierCurveTo(
- 94 * xmul + xoff,
- 451 * ymul + yoff,
- 58 * xmul + xoff,
- 402 * ymul + yoff,
- 43 * xmul + xoff,
- 377 * ymul + yoff,
- );
- gaugeCtx.bezierCurveTo(
- 33.51800353929965 * xmul + xoff,
- 359.3905780015565 * ymul + yoff,
- 8 * xmul + xoff,
- 312 * ymul + yoff,
- 6 * xmul + xoff,
- 281 * ymul + yoff,
- );
- gaugeCtx.bezierCurveTo(
- 4.712354440040691 * xmul + xoff,
- 261.0414938206308 * ymul + yoff,
- 39 * xmul + xoff,
- 214 * ymul + yoff,
- 91 * xmul + xoff,
- 176 * ymul + yoff,
- );
- gaugeCtx.bezierCurveTo(
- 106.7370683471181 * xmul + xoff,
- 163.65720129637796 * ymul + yoff,
- 138 * xmul + xoff,
- 140 * ymul + yoff,
- 182 * xmul + xoff,
- 132 * ymul + yoff,
- );
- gaugeCtx.bezierCurveTo(
- 201 * xmul + xoff,
- 128 * ymul + yoff,
- 280 * xmul + xoff,
- 116 * ymul + yoff,
- 368 * xmul + xoff,
- 111 * ymul + yoff,
- );
- gaugeCtx.lineTo(368 * xmul + xoff, 135 * ymul + yoff);
- gaugeCtx.lineTo(339 * xmul + xoff, 138 * ymul + yoff);
- gaugeCtx.bezierCurveTo(
- 359 * xmul + xoff,
- 138 * ymul + yoff,
- 251 * xmul + xoff,
- 147 * ymul + yoff,
- 191 * xmul + xoff,
- 158 * ymul + yoff,
- );
- gaugeCtx.bezierCurveTo(
- 171.327868852459 * xmul + xoff,
- 161.60655737704917 * ymul + yoff,
- 131 * xmul + xoff,
- 185 * ymul + yoff,
- 109 * xmul + xoff,
- 201 * ymul + yoff,
- );
- gaugeCtx.bezierCurveTo(
- 97 * xmul + xoff,
- 212 * ymul + yoff,
- 49 * xmul + xoff,
- 249 * ymul + yoff,
- 46 * xmul + xoff,
- 279 * ymul + yoff,
- );
- gaugeCtx.bezierCurveTo(
- 44.009925619580024 * xmul + xoff,
- 298.9007438041998 * ymul + yoff,
- 67 * xmul + xoff,
- 344 * ymul + yoff,
- 74 * xmul + xoff,
- 358 * ymul + yoff,
- );
- gaugeCtx.bezierCurveTo(
- 86 * xmul + xoff,
- 375 * ymul + yoff,
- 102 * xmul + xoff,
- 407 * ymul + yoff,
- 122 * xmul + xoff,
- 419 * ymul + yoff,
- );
- gaugeCtx.bezierCurveTo(
- 139.1498585142509 * xmul + xoff,
- 429.28991510855053 * ymul + yoff,
- 195 * xmul + xoff,
- 430 * ymul + yoff,
- 175 * xmul + xoff,
- 430 * ymul + yoff,
- );
- gaugeCtx.closePath();
- }
- function drawBattery(xoff, yoff, xmul, ymul) {
- gaugeCtx.beginPath();
- gaugeCtx.lineTo(533 * xmul + xoff, 385 * ymul + yoff);
- gaugeCtx.lineTo(533 * xmul + xoff, 375 * ymul + yoff);
- gaugeCtx.lineTo(395 * xmul + xoff, 374 * ymul + yoff);
- gaugeCtx.lineTo(395 * xmul + xoff, 386 * ymul + yoff);
- gaugeCtx.closePath();
- }
- function drawBat(xoff, yoff, xmul, ymul, fillPercent) {
- gaugeCtx.save();
- drawBattery(xoff, yoff, xmul, ymul);
- gaugeCtx.clip();
- gaugeCtx.filter = "blur(7px)";
- const leftX = 397 * xmul + xoff;
- const rightX = 533 * xmul + xoff;
- const fill = (leftX - rightX) * fillPercent;
- const fillX = leftX - fill;
- const grad = gaugeCtx.createLinearGradient(fillX, 0, leftX, 0);
- gaugeCtx.fillStyle = grad;
- grad.addColorStop(0, "rgba(240, 240, 255, 0.0)");
- grad.addColorStop(0, "rgba(255, 73, 0, 1)");
- grad.addColorStop(1, "rgba(255, 73, 0, 0.7)");
- gaugeCtx.fillRect(leftX, 0, fillX, gaugeCanvas.height);
- gaugeCtx.restore();
- }
- // Draw the gauge with liquid fill
- function drawTac(xoff, yoff, xmul, ymul, fillPercent) {
- gaugeCtx.save();
- // Define the shape
- drawSpeed(xoff, yoff, xmul * -1, ymul);
- // Clip to this shape
- gaugeCtx.clip();
- gaugeCtx.filter = "blur(10px)";
- // Now draw the liquid fill
- const bottomY = 453 * ymul + yoff;
- const topY = 113 * ymul + yoff;
- const fillHeight = (bottomY - topY) * fillPercent;
- const fillY = bottomY - fillHeight;
- const grad = gaugeCtx.createLinearGradient(
- 0,
- fillY,
- 0,
- bottomY,
- );
- grad.addColorStop(0, "rgba(240, 240, 255, 0.5)");
- grad.addColorStop(0.3, "#ee004d");
- grad.addColorStop(1, "#ee004d");
- gaugeCtx.fillStyle = grad;
- gaugeCtx.fillRect(
- 0,
- fillY,
- gaugeCanvas.width,
- gaugeCanvas.height,
- );
- gaugeCtx.restore();
- }
- function drawGauge(xoff, yoff, xmul, ymul, fillPercent) {
- gaugeCtx.clearRect(0, 0, gaugeCanvas.width, gaugeCanvas.height);
- gaugeCtx.save();
- // Define the shape
- drawSpeed(xoff, yoff, xmul, ymul);
- // Clip to this shape
- gaugeCtx.clip();
- gaugeCtx.filter = "blur(10px)";
- // Now draw the liquid fill
- const bottomY = 453 * ymul + yoff;
- const topY = 113 * ymul + yoff;
- const fillHeight = (bottomY - topY) * fillPercent;
- const fillY = bottomY - fillHeight;
- const grad = gaugeCtx.createLinearGradient(
- 0,
- fillY,
- 0,
- bottomY,
- );
- grad.addColorStop(0, "rgba(240, 240, 255, 0.5)");
- grad.addColorStop(0.3, "#ee004d");
- grad.addColorStop(1, "#ee004d");
- gaugeCtx.fillStyle = grad;
- gaugeCtx.fillRect(
- 0,
- fillY,
- gaugeCanvas.width,
- gaugeCanvas.height,
- );
- gaugeCtx.restore();
- }
- function animateGauge() {
- if (Math.abs(targetSpeed - speed) >= 1) {
- // if difference between target and current is too great
- speed += (targetSpeed - speed) * 0.15; // increment the speed to keep up.
- } else {
- speed = targetSpeed; // else, the speed should just equal whatever the current speed is.
- }
- //prevents jittering
- if (Math.abs(targetRPM - rpm) >= 1) {
- // if the difference between rpm and target rpm is more than one (meaning it is moving)
- rpm += (targetRPM - rpm) * 0.15; // increment the rpm
- } else {
- rpm = targetRPM; // else, the rpm should just be whatever the target rpm is
- }
- gaugeCtx.clearRect(0, 0, gaugeCanvas.width, gaugeCanvas.height); // clear previous frame
- const fillPercent = speed / maxSpeed;
- const tacFillPercent = rpm / maxRPM;
- drawGauge(0, -165, 2.3, 2.3, fillPercent); // draw speedometor
- drawNumSp(330, 538, Math.round(speed)); // draw numerical representation of speed
- drawTac(1725, -165, 2.3, 2.3, tacFillPercent); // draw tachometor
- drawNumTac(1340, 538, Math.round(rpm)); // draw numeriocal representation of rpm
- drawNumBat(948, 848, batVoltage);
- drawNumOil(730, 848, estOilLife("2026-03-05"));
- requestAnimationFrame(animateGauge);
- }
- function startAnimation() {
- if (!animating) {
- animating = true;
- requestAnimationFrame(animateGauge);
- }
- }
- function resizeAndRenderStatic() {
- const rect = gaugeCanvas.getBoundingClientRect();
- gaugeCanvas.width = rect.width;
- gaugeCanvas.height = rect.height;
- const fillPercent = speed / maxSpeed;
- let numSpd = "0";
- let numTac = "0";
- let numOil = "0%";
- //let numBat = "12.6v";
- drawGauge(0, -165, 2.3, 2.3, 0);
- drawTac(1725, -165, 2.3, 2.3, 0);
- drawNumSp(330, 538, numSpd);
- drawNumTac(1340, 538, numTac);
- drawNumBat(948, 848, "0V");
- drawNumOil(730, 848, estOilLife("2026-03-05"));
- }
- const hudiy = { api: {} };
- const root = await protobuf.load("common/Api.proto");
- hudiy.api.protoRoot = root;
- hudiy.api.HelloRequest = root.lookupType(
- "hudiy.app.api.HelloRequest",
- );
- hudiy.api.HelloResponse = root.lookupType(
- "hudiy.app.api.HelloResponse",
- );
- hudiy.api.HelloResponseResult = root.lookup(
- "hudiy.app.api.HelloResponse.HelloResponseResult",
- ).values;
- hudiy.api.QueryObdDeviceRequest = root.lookupType(
- "hudiy.app.api.QueryObdDeviceRequest",
- );
- hudiy.api.QueryObdDeviceResponse = root.lookupType(
- "hudiy.app.api.QueryObdDeviceResponse",
- );
- hudiy.api.MessageType = root.lookup(
- "hudiy.app.api.MessageType",
- ).values;
- hudiy.api.client = new HudiyClient("ws://localhost:44406");
- function sendQueryObdRequest(OBDCode, rNum) {
- const msg = hudiy.api.QueryObdDeviceRequest.create({
- commands: OBDCode,
- requestCode: rNum,
- });
- const payload =
- hudiy.api.QueryObdDeviceRequest.encode(msg).finish();
- hudiy.api.client.sendMessage(
- hudiy.api.MessageType.MESSAGE_QUERY_OBD_DEVICE_REQUEST,
- 0,
- payload,
- );
- }
- hudiy.api.client.onOpen = () => {
- const hello = hudiy.api.HelloRequest.create({
- name: "DigiDash",
- apiVersion: { major: 1, minor: 0 },
- });
- const payload = hudiy.api.HelloRequest.encode(hello).finish();
- hudiy.api.client.sendMessage(
- hudiy.api.MessageType.MESSAGE_HELLO_REQUEST,
- 0,
- payload,
- );
- };
- hudiy.api.client.onMessage = ({ id, payload }) => {
- if (id === hudiy.api.MessageType.MESSAGE_HELLO_RESPONSE) {
- const msg = hudiy.api.HelloResponse.decode(payload);
- if (
- msg.result ===
- hudiy.api.HelloResponseResult.HELLO_RESPONSE_RESULT_OK
- ) {
- sendQueryObdRequest(["010D"], 0); // query speed
- sendQueryObdRequest(["010C"], 1); // query RPM
- sendQueryObdRequest(["0101"], 2); // check system integrity test (check engine light)
- sendQueryObdRequest(["0105"], 3); // check engine coolant temp
- sendQueryObdRequest(["0142"], 4); // check battery voltage
- }
- } else if (
- id ===
- hudiy.api.MessageType.MESSAGE_QUERY_OBD_DEVICE_RESPONSE
- ) {
- const msg =
- hudiy.api.QueryObdDeviceResponse.decode(payload);
- if (msg.requestCode === 0 && msg.result) {
- // get speed
- const bytes = msg.data[0]
- ?.match(/.{1,2}/g)
- ?.map((h) => parseInt(h, 16));
- targetSpeed = bytes ? bytes[2] / 1.609 : 0; // note that the output is divided by 1.609 to convert from kmh to mph
- startAnimation();
- setTimeout(() => sendQueryObdRequest(["010D"], 0), 150);
- } else if (msg.requestCode === 1 && msg.result) {
- // get RPM
- const bytes = msg.data[0]
- ?.match(/.{1,2}/g)
- ?.map((h) => parseInt(h, 16));
- targetRPM = bytes
- ? (256 * bytes[2] + bytes[3]) / 4000
- : 0;
- startAnimation();
- setTimeout(() => sendQueryObdRequest(["010C"], 1), 150);
- // below is used to engage the warning lights (check engine and engine temp warning)
- } else if (
- msg.requestCode === 2 &&
- msg.result &&
- checkEngineVisible == false
- ) {
- checkEngineVisible = true;
- engineLight.style.opacity = "1";
- setTimeout(
- () => sendQueryObdRequest(["0101"], 2),
- 60000,
- );
- } else if (
- msg.requestCode === 2 &&
- !msg.result &&
- checkEngineVisible == true
- ) {
- checkEngineVisible = false;
- engineLight.style.opacity = "0.2";
- setTimeout(
- () => sendQueryObdRequest(["0101"], 2),
- 60000,
- );
- } else if (msg.requestCode === 3 && msg.result) {
- // get engine temp
- const bytes = msg.data[0]
- ?.match(/.{1,2}/g)
- ?.map((h) => parseInt(h, 16));
- engineTemp = bytes ? bytes[2] - 40 : 0;
- // check whether engine is overheating
- if (engineTemp > 105 && engineTempVisible == false) {
- engineTempVisible = true;
- tempLight.style.opacity = "1";
- } else if (
- engineTemp < 105 &&
- engineTempVisible == true
- ) {
- engineTempVisible = false;
- tempLight.style.opacity = "0.2";
- }
- setTimeout(
- () => sendQueryObdRequest(["0105"], 3),
- 60000,
- );
- } else if (msg.requestCode === 4 && msg.result) {
- // get battery voltage
- const bytes = msg.data[0]
- ?.match(/.{1,2}/g)
- ?.map((h) => parseInt(h, 16));
- batVoltage = bytes
- ? ((256 * bytes[2] + bytes[3]) / 1000).toFixed(1) +
- "V"
- : 0;
- startAnimation();
- setTimeout(() => sendQueryObdRequest(["0142"], 4), 150);
- }
- } else if (id === hudiy.api.MessageType.MESSAGE_PING) {
- hudiy.api.client.sendMessage(
- hudiy.api.MessageType.MESSAGE_PONG,
- 0,
- new Uint8Array(0),
- );
- }
- };
- hudiy.api.client.connect();
- window.addEventListener("resize", resizeAndRenderStatic);
- resizeAndRenderStatic();
- </script>
Add Comment
Please, Sign In to add comment