Compare commits
	
		
			5 Commits
		
	
	
		
			d524b919fd
			...
			bc2c19dad1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| bc2c19dad1 | |||
| 8f494dfa05 | |||
| e913ce6e1b | |||
| d994fd25a0 | |||
| cebf0db60c | 
@@ -28,6 +28,9 @@
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
  <!-- Connection-Overlay -->
 | 
			
		||||
  <!-- Notification-Container -->
 | 
			
		||||
  <div id="notification-container" class="notification-container"></div>
 | 
			
		||||
  <!-- Notification-Container -->
 | 
			
		||||
  <nav class="navbar fixed-top navbar-dark bg-primary" id="navbar1">
 | 
			
		||||
    <a class="navbar-brand" href="#">
 | 
			
		||||
      <img src="static/img/logo.png" width="30" height="30" class="d-inline-block align-top mr-1" alt="">
 | 
			
		||||
@@ -122,7 +125,7 @@
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="form-group row">
 | 
			
		||||
            <div class="col text-center">
 | 
			
		||||
              <button id="resettank" class="btn-wsevent btn btn-outline-primary ml-2">Tank zurücksetzen</button>
 | 
			
		||||
              <button id="resettank" class="btn-wsevent confirm btn btn-outline-primary ml-2">Tank zurücksetzen</button>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </p>
 | 
			
		||||
@@ -195,7 +198,7 @@
 | 
			
		||||
        <h4>Gerät neustarten</h4>
 | 
			
		||||
          <div class="form-group row">
 | 
			
		||||
            <div class="col text-center">
 | 
			
		||||
              <button id="reboot" class="btn-wsevent btn btn-outline-primary">Reboot</button>
 | 
			
		||||
              <button id="reboot" class="btn-wsevent confirm btn btn-outline-primary">Reboot</button>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </p>
 | 
			
		||||
@@ -230,7 +233,7 @@
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="form-group row">
 | 
			
		||||
            <div class="col text-center">
 | 
			
		||||
              <button id="sourcesave" class="btn-wsevent btn btn-outline-primary">Übernehmen</button>
 | 
			
		||||
              <button id="sourcesave" class="btn-wsevent confirm btn btn-outline-primary">Übernehmen</button>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </p>
 | 
			
		||||
 
 | 
			
		||||
@@ -4075,9 +4075,9 @@ input[type=submit].btn-block {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.alert-success {
 | 
			
		||||
    color: #012d36;
 | 
			
		||||
    background-color: #ccdde1;
 | 
			
		||||
    border-color: #b8d0d5
 | 
			
		||||
    color: #002200;
 | 
			
		||||
    background-color: #99ff99;
 | 
			
		||||
    border-color: #20bb20
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.alert-success hr {
 | 
			
		||||
@@ -4089,9 +4089,9 @@ input[type=submit].btn-block {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.alert-info {
 | 
			
		||||
    color: #084367;
 | 
			
		||||
    background-color: #cfe6f4;
 | 
			
		||||
    border-color: #bcdcef
 | 
			
		||||
    color: #000022;
 | 
			
		||||
    background-color: #99ddff;
 | 
			
		||||
    border-color: #2040FF
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.alert-info hr {
 | 
			
		||||
@@ -4103,9 +4103,9 @@ input[type=submit].btn-block {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.alert-warning {
 | 
			
		||||
    color: #07767a;
 | 
			
		||||
    background-color: #cff9fb;
 | 
			
		||||
    border-color: #bbf7f9
 | 
			
		||||
    color: #222200;
 | 
			
		||||
    background-color: #FFFF99;
 | 
			
		||||
    border-color: #FFFF00
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.alert-warning hr {
 | 
			
		||||
@@ -4117,9 +4117,9 @@ input[type=submit].btn-block {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.alert-danger {
 | 
			
		||||
    color: #851929;
 | 
			
		||||
    background-color: #ffd6dc;
 | 
			
		||||
    border-color: #ffc5ce
 | 
			
		||||
    color: #200000;
 | 
			
		||||
    background-color: #ffcccc;
 | 
			
		||||
    border-color: #AA2020
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.alert-danger hr {
 | 
			
		||||
 
 | 
			
		||||
@@ -76,3 +76,15 @@ hr {
 | 
			
		||||
      transform: rotate(360deg);
 | 
			
		||||
    }
 | 
			
		||||
  } 
 | 
			
		||||
 | 
			
		||||
  .notification-container {
 | 
			
		||||
    position: fixed;
 | 
			
		||||
    top: 30%;
 | 
			
		||||
    left: 50%;
 | 
			
		||||
    transform: translateX(-50%);
 | 
			
		||||
    z-index: 1000;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  .notification {
 | 
			
		||||
    margin-bottom: 20px; /* Fügen Sie bei Bedarf weitere Stile hinzu */
 | 
			
		||||
  }
 | 
			
		||||
@@ -2,142 +2,111 @@ const jsonFilePath = "static/dtc_table.json";
 | 
			
		||||
 | 
			
		||||
var dtcState = {};
 | 
			
		||||
 | 
			
		||||
function processDTCNotifications(dtcArray) {
 | 
			
		||||
async function processDTCNotifications(dtcArray) {
 | 
			
		||||
  if (dtcArray.length === 0 || dtcArray[0] == "0") {
 | 
			
		||||
    dtcState = {};
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (var i = 0; i < dtcArray.length; i++) {
 | 
			
		||||
    var dtcInfo = dtcArray[i].split(",");
 | 
			
		||||
    var errorCode = dtcInfo[1];
 | 
			
		||||
    var errorCode = parseInt(dtcInfo[1]);
 | 
			
		||||
    var activity = parseInt(dtcInfo[3]);
 | 
			
		||||
    var severity = parseInt(dtcInfo[2]);
 | 
			
		||||
 | 
			
		||||
    if (dtcState[errorCode]) {
 | 
			
		||||
      // Überprüfen, ob sich der Zustand von "previous" auf "active" geändert hat
 | 
			
		||||
      if (activity !== dtcState[errorCode]) {
 | 
			
		||||
        dtcState[errorCode] = activity;
 | 
			
		||||
        if (activity === 1) showDTCNotification(errorCode);
 | 
			
		||||
    try {
 | 
			
		||||
      var { title, description } = await getDescriptionForDTCNumber(errorCode);
 | 
			
		||||
 | 
			
		||||
      switch (severity) {
 | 
			
		||||
        case 1:
 | 
			
		||||
          severity = "info";
 | 
			
		||||
          break;
 | 
			
		||||
        case 2:
 | 
			
		||||
          severity = "warning";
 | 
			
		||||
          break;
 | 
			
		||||
        case 3:
 | 
			
		||||
          severity = "danger";
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      // DTC ist neu, Zustand speichern und Benachrichtigung anzeigen
 | 
			
		||||
      dtcState[errorCode] = activity;
 | 
			
		||||
      showDTCNotification(errorCode);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function showDTCNotification(dtctext, severity) {
 | 
			
		||||
  // Überprüfen, ob der Browser die Notification API unterstützt
 | 
			
		||||
  if ("Notification" in window) {
 | 
			
		||||
    // Überprüfen, ob der Benutzer bereits Berechtigungen erteilt hat
 | 
			
		||||
    if (Notification.permission === "granted") {
 | 
			
		||||
      // Benachrichtigung anzeigen
 | 
			
		||||
      showNotification(dtctext, severity);
 | 
			
		||||
    } else if (Notification.permission !== "denied") {
 | 
			
		||||
      // Aufforderung zur Erlaubnis einholen
 | 
			
		||||
      Notification.requestPermission().then(function (permission) {
 | 
			
		||||
        if (permission === "granted") {
 | 
			
		||||
          // Benachrichtigung anzeigen
 | 
			
		||||
          showNotification(dtctext, severity);
 | 
			
		||||
        } else {
 | 
			
		||||
          // Der Benutzer hat die Berechtigung abgelehnt oder das Dialogfeld geschlossen
 | 
			
		||||
          console.log("Benachrichtigungsberechtigung wurde verweigert.");
 | 
			
		||||
      if (dtcState[errorCode]) {
 | 
			
		||||
        // Überprüfen, ob sich der Zustand von "previous" auf "active" geändert hat
 | 
			
		||||
        if (activity !== dtcState[errorCode]) {
 | 
			
		||||
          dtcState[errorCode] = activity;
 | 
			
		||||
          if (activity === 1) showNotification(description, severity);
 | 
			
		||||
        }
 | 
			
		||||
      });
 | 
			
		||||
    } else {
 | 
			
		||||
      // Der Benutzer hat die Berechtigung bereits verweigert
 | 
			
		||||
      console.log("Benachrichtigungsberechtigung wurde bereits verweigert.");
 | 
			
		||||
      } else {
 | 
			
		||||
        // DTC ist neu, Zustand speichern und Benachrichtigung anzeigen
 | 
			
		||||
        dtcState[errorCode] = activity;
 | 
			
		||||
        showNotification(description, severity);
 | 
			
		||||
      }
 | 
			
		||||
    } catch (error) {
 | 
			
		||||
      console.error("Error processing DTC:", error);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Funktion zum Anzeigen der Benachrichtigung
 | 
			
		||||
function showNotification(dtctext, severity) {
 | 
			
		||||
  var severityIcon;
 | 
			
		||||
  switch (severity) {
 | 
			
		||||
    case 1:
 | 
			
		||||
      severityIcon = "static/img/info.png";
 | 
			
		||||
      break;
 | 
			
		||||
    case 2:
 | 
			
		||||
      severityIcon = "static/img/warn.png";
 | 
			
		||||
      break;
 | 
			
		||||
    case 3:
 | 
			
		||||
      severityIcon = "static/img/critical.png";
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      severityIcon = "static/img/none.png";
 | 
			
		||||
  }
 | 
			
		||||
function getDescriptionForDTCNumber(number) {
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    fetch(jsonFilePath)
 | 
			
		||||
      .then((response) => response.json())
 | 
			
		||||
      .then((data) => {
 | 
			
		||||
        const dtcList = data.dtc_table_data;
 | 
			
		||||
        const foundEntry = dtcList.find((entry) => entry.num === number);
 | 
			
		||||
 | 
			
		||||
  var options = {
 | 
			
		||||
    body: dtctext,
 | 
			
		||||
    icon: severityIcon,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  var notification = new Notification("KTM Chain Oiler DTC", options);
 | 
			
		||||
 | 
			
		||||
  // Optional: Handle Click-Event
 | 
			
		||||
  notification.onclick = function () {
 | 
			
		||||
    console.log("Benachrichtigung wurde angeklickt.");
 | 
			
		||||
  };
 | 
			
		||||
        if (foundEntry) {
 | 
			
		||||
          const description = foundEntry.description;
 | 
			
		||||
          const title = foundEntry.title;
 | 
			
		||||
          resolve({ title, description });
 | 
			
		||||
        } else {
 | 
			
		||||
          // Wenn die Nummer nicht gefunden wurde, geben Sie einen Fehler zurück
 | 
			
		||||
          reject(`Beschreibung für Nummer ${number} nicht gefunden.`);
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
      .catch((error) => {
 | 
			
		||||
        // Im Fehlerfall geben Sie den Fehler zurück
 | 
			
		||||
        reject(error);
 | 
			
		||||
      });
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getDescriptionForDTCNumber(number, callback) {
 | 
			
		||||
  fetch(jsonFilePath)
 | 
			
		||||
    .then((response) => response.json())
 | 
			
		||||
    .then((data) => {
 | 
			
		||||
      const dtcList = data.dtc_table_data;
 | 
			
		||||
      const foundEntry = dtcList.find((entry) => entry.num === number);
 | 
			
		||||
 | 
			
		||||
      if (foundEntry) {
 | 
			
		||||
        const description = foundEntry.description;
 | 
			
		||||
        const title = foundEntry.title;
 | 
			
		||||
        callback(null, title, description);
 | 
			
		||||
      } else {
 | 
			
		||||
        // Wenn die Nummer nicht gefunden wurde, geben Sie einen Fehler zurück
 | 
			
		||||
        callback(
 | 
			
		||||
          `Beschreibung für Nummer ${number} nicht gefunden.`,
 | 
			
		||||
          null,
 | 
			
		||||
          null
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
    .catch((error) => {
 | 
			
		||||
      // Im Fehlerfall geben Sie den Fehler zurück
 | 
			
		||||
      callback(error, null, null);
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function showDTCModal(event) {
 | 
			
		||||
async function showDTCModal(event) {
 | 
			
		||||
  var dtc = parseInt(event.currentTarget.getAttribute("data-dtc"));
 | 
			
		||||
  var debugval = event.currentTarget.getAttribute("data-debugval");
 | 
			
		||||
  var modal = $("#dtcModal");
 | 
			
		||||
 | 
			
		||||
  getDescriptionForDTCNumber(dtc, function (error, title, description) {
 | 
			
		||||
    if (error) {
 | 
			
		||||
      console.error("Fehler beim Abrufen der Beschreibung:", error);
 | 
			
		||||
      modal.find(".modal-title").text("Fehler");
 | 
			
		||||
      modal
 | 
			
		||||
        .find(".dtc-desc")
 | 
			
		||||
        .text("DTC-Beschreibung konnte nicht geladen werden");
 | 
			
		||||
  try {
 | 
			
		||||
    var { title, description } = await getDescriptionForDTCNumber(dtc);
 | 
			
		||||
 | 
			
		||||
    modal.find(".modal-title").text(title);
 | 
			
		||||
    modal.find(".dtc-desc").text(description);
 | 
			
		||||
 | 
			
		||||
    if (debugval > 0) {
 | 
			
		||||
      modal.find(".dtc-debugval").text("Debugvalue: " + debugval);
 | 
			
		||||
    } else {
 | 
			
		||||
      modal.find(".modal-title").text(title);
 | 
			
		||||
      modal.find(".dtc-desc").text(description);
 | 
			
		||||
      if (debugval > 0) {
 | 
			
		||||
        modal.find(".dtc-debugval").text("Debugvalue: " + debugval);
 | 
			
		||||
      } else {
 | 
			
		||||
        modal.find(".dtc-debugval").remove();
 | 
			
		||||
      }
 | 
			
		||||
      modal.find(".dtc-debugval").remove();
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
  } catch (error) {
 | 
			
		||||
    console.error("Fehler beim Abrufen der Beschreibung:", error);
 | 
			
		||||
    modal.find(".modal-title").text("Fehler");
 | 
			
		||||
    modal.find(".dtc-desc").text("DTC-Beschreibung konnte nicht geladen werden");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Modal anzeigen
 | 
			
		||||
  modal.modal("show");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
function fillDTCTable(dtcArray) {
 | 
			
		||||
  // Referenz auf das Tabellen-Element
 | 
			
		||||
  var table = document.getElementById("dtc_table");
 | 
			
		||||
  var tablediv = document.getElementById("dtc_container");
 | 
			
		||||
 | 
			
		||||
  // Prüfen, ob DTC vorhanden sind
 | 
			
		||||
  if (dtcArray.length === 0) {
 | 
			
		||||
  if (dtcArray.length === 0 || dtcArray[0] == "0") {
 | 
			
		||||
    // Verstecke das Tabellen-Div, wenn keine DTC vorhanden sind
 | 
			
		||||
    tablediv.hidden = true;
 | 
			
		||||
    table.innerHTML = "";
 | 
			
		||||
    return;
 | 
			
		||||
  } else {
 | 
			
		||||
    // Zeige das Tabellen-Div, wenn DTC vorhanden sind
 | 
			
		||||
 
 | 
			
		||||
@@ -25,9 +25,7 @@ function initButtons() {
 | 
			
		||||
  if (elements.length > 0) {
 | 
			
		||||
    for (var i = 0; i < elements.length; i++) {
 | 
			
		||||
      let element = elements[i];
 | 
			
		||||
      element.addEventListener("click", function () {
 | 
			
		||||
        websocket_sendevent("btn-" + element.id, 0);
 | 
			
		||||
      });
 | 
			
		||||
      element.addEventListener("click", sendButton);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -55,57 +53,58 @@ function onClose(event) {
 | 
			
		||||
  overlay.style.display = "flex";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function sendButton(event) {
 | 
			
		||||
  var targetElement = event.target;
 | 
			
		||||
 | 
			
		||||
  if (
 | 
			
		||||
    targetElement.classList.contains("confirm") &&
 | 
			
		||||
    window.confirm("Sicher?") == false
 | 
			
		||||
  )
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  websocket_sendevent("btn-" + targetElement.id, targetElement.value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function onMessage(event) {
 | 
			
		||||
  var data = event.data;
 | 
			
		||||
  console.log("ws_msg:" + event.data + "\n");
 | 
			
		||||
 | 
			
		||||
  if (data.startsWith("DEBUG:")) {
 | 
			
		||||
  if (data.startsWith("NOTIFY:")) {
 | 
			
		||||
    var notify_data = data.slice(7).split(";")[1];
 | 
			
		||||
    var notify_type = data.slice(7).split(";")[0];
 | 
			
		||||
    showNotification(notify_data, notify_type);
 | 
			
		||||
  } else if (data.startsWith("DEBUG:")) {
 | 
			
		||||
    var addtext = data.slice(6);
 | 
			
		||||
    var livedebug_out = document.getElementById("livedebug-out");
 | 
			
		||||
    livedebug_out.value += addtext;
 | 
			
		||||
    livedebug_out.scrollTop = livedebug_out.scrollHeight;
 | 
			
		||||
    do_resize(livedebug_out);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (data.startsWith("DTC:")) {
 | 
			
		||||
  } else if (data.startsWith("DTC:")) {
 | 
			
		||||
    const dtcs = data.slice(4);
 | 
			
		||||
    const dtcArray = dtcs.trim() !== "" ? dtcs.split(";").filter(Boolean) : [];
 | 
			
		||||
 | 
			
		||||
    if (dtcArray[0] != "0") {
 | 
			
		||||
      processDTCNotifications(dtcArray);
 | 
			
		||||
      fillDTCTable(dtcArray);
 | 
			
		||||
    }
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
    processDTCNotifications(dtcArray);
 | 
			
		||||
    fillDTCTable(dtcArray);
 | 
			
		||||
 | 
			
		||||
  if (data.startsWith("MAPPING_STATUS:")) {
 | 
			
		||||
  } else if (data.startsWith("MAPPING_STATUS:")) {
 | 
			
		||||
    const data_sliced = data.slice(15);
 | 
			
		||||
    statusMapping = createMapping(data_sliced);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (data.startsWith("MAPPING_STATIC:")) {
 | 
			
		||||
  } else if (data.startsWith("MAPPING_STATIC:")) {
 | 
			
		||||
    const data_sliced = data.slice(15);
 | 
			
		||||
    staticMapping = createMapping(data_sliced);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (data.startsWith("STATUS:")) {
 | 
			
		||||
  } else if (data.startsWith("STATUS:")) {
 | 
			
		||||
    const data_sliced = data.slice(7);
 | 
			
		||||
    const result = processDataString(data_sliced, statusMapping);
 | 
			
		||||
    console.log("STATUS:");
 | 
			
		||||
    console.log(JSON.stringify(result, null, 2));
 | 
			
		||||
    fillValuesToHTML(result);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (data.startsWith("STATIC:")) {
 | 
			
		||||
  } else if (data.startsWith("STATIC:")) {
 | 
			
		||||
    const data_sliced = data.slice(7);
 | 
			
		||||
    const result = processDataString(data_sliced, staticMapping);
 | 
			
		||||
    console.log("STATIC:");
 | 
			
		||||
    console.log(JSON.stringify(result, null, 2));
 | 
			
		||||
    fillValuesToHTML(result);
 | 
			
		||||
    overlay.style.display = "none";
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -211,3 +210,27 @@ function updateProgressBar(progressBar, value) {
 | 
			
		||||
  progressBar.style.width = value + "%";
 | 
			
		||||
  progressBar.textContent = value + "%";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function showNotification(message, type) {
 | 
			
		||||
  // Erstellen Sie ein Bootstrap-Alert-Element
 | 
			
		||||
  var alertElement = $(
 | 
			
		||||
    '<div class="alert alert-' +
 | 
			
		||||
    type +
 | 
			
		||||
    ' alert-dismissible fade show notification" role="alert">' +
 | 
			
		||||
    "<strong>" +
 | 
			
		||||
    message +
 | 
			
		||||
    "</strong>" +
 | 
			
		||||
    '<button type="button" class="close" data-dismiss="alert" aria-label="Close">' +
 | 
			
		||||
    '<span aria-hidden="true">×</span>' +
 | 
			
		||||
    "</button>" +
 | 
			
		||||
    "</div>"
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  // Fügen Sie das Alert-Element dem Container hinzu
 | 
			
		||||
  $("#notification-container").append(alertElement);
 | 
			
		||||
 | 
			
		||||
  // Nach 5 Sekunden das Alert-Element ausblenden
 | 
			
		||||
  setTimeout(function () {
 | 
			
		||||
    alertElement.alert("close");
 | 
			
		||||
  }, 5000);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -31,10 +31,19 @@
 | 
			
		||||
#include "debugger.h"
 | 
			
		||||
#include "struct2json.h"
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
    info,
 | 
			
		||||
    success,
 | 
			
		||||
    warning,
 | 
			
		||||
    error
 | 
			
		||||
} NotificationType_t;
 | 
			
		||||
 | 
			
		||||
void initWebUI();
 | 
			
		||||
void Webserver_Process();
 | 
			
		||||
void Webserver_Shutdown();
 | 
			
		||||
 | 
			
		||||
void Websocket_PushLiveDebug(String Message);
 | 
			
		||||
void Websocket_PushNotification(String Message, NotificationType_t type);
 | 
			
		||||
 | 
			
		||||
#endif // _WEBUI_H_
 | 
			
		||||
 
 | 
			
		||||
@@ -73,6 +73,7 @@ void Debug_Process()
 | 
			
		||||
            inputBuffer[inputCnt] = 0; // terminate the String
 | 
			
		||||
            inputCnt = 0;
 | 
			
		||||
            InputProcessed = CMD_COMPLETE;
 | 
			
		||||
            Serial.write(inputChar);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        case 0x1B: // Esc
 | 
			
		||||
@@ -84,6 +85,7 @@ void Debug_Process()
 | 
			
		||||
        case 0x21 ... 0x7E: // it's a real letter or sign and not some control-chars
 | 
			
		||||
            inputBuffer[inputCnt] = inputChar;
 | 
			
		||||
            inputCnt++;
 | 
			
		||||
            Serial.write(inputChar);
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
@@ -117,6 +119,10 @@ void Debug_Process()
 | 
			
		||||
    default:
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    if (InputProcessed != IDLE)
 | 
			
		||||
        Serial.print(">");
 | 
			
		||||
 | 
			
		||||
    InputProcessed = IDLE;
 | 
			
		||||
}
 | 
			
		||||
/**
 | 
			
		||||
@@ -152,7 +158,7 @@ void Debug_pushMessage(const char *format, ...)
 | 
			
		||||
    if ((DebuggerStatus[dbg_Serial] == enabled) || (DebuggerStatus[dbg_Webui] == enabled))
 | 
			
		||||
    {
 | 
			
		||||
        char buff[128]; // Buffer to hold the formatted message
 | 
			
		||||
        va_list arg;   // Variable argument list for vsnprintf
 | 
			
		||||
        va_list arg;    // Variable argument list for vsnprintf
 | 
			
		||||
        va_start(arg, format);
 | 
			
		||||
 | 
			
		||||
        // Format the message and store it in the buffer
 | 
			
		||||
@@ -257,6 +263,14 @@ void processCmdDebug(String command)
 | 
			
		||||
        MaintainDTC(DTC_FAKE_DTC_WARN, true, millis());
 | 
			
		||||
    else if (command == "dtc_info")
 | 
			
		||||
        MaintainDTC(DTC_FAKE_DTC_INFO, true, millis());
 | 
			
		||||
    else if (command == "notify_error")
 | 
			
		||||
        Websocket_PushNotification("Debug Error Notification", error);
 | 
			
		||||
    else if (command == "notify_warning")
 | 
			
		||||
        Websocket_PushNotification("Debug Warning Notification", warning);
 | 
			
		||||
    else if (command == "notify_success")
 | 
			
		||||
        Websocket_PushNotification("Debug Success Notification", success);
 | 
			
		||||
    else if (command == "notify_info")
 | 
			
		||||
        Websocket_PushNotification("Debug Info Notification", info);
 | 
			
		||||
    else
 | 
			
		||||
        Debug_pushMessage("unknown Command\n");
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -492,6 +492,10 @@ void Websocket_HandleButtons(uint8_t *data)
 | 
			
		||||
  {
 | 
			
		||||
    globals.systemStatus = sysStat_Shutdown;
 | 
			
		||||
  }
 | 
			
		||||
  else if (strcmp(identifier, "resettank") == 0)
 | 
			
		||||
  {
 | 
			
		||||
    PersistenceData.tankRemain_microL = LubeConfig.tankCapacity_ml * 1000;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    Debug_pushMessage("Got unknown Button-id '%s' from ws-client\n", identifier);
 | 
			
		||||
@@ -532,6 +536,38 @@ void Websocket_HandleSettings(uint8_t *data)
 | 
			
		||||
    int index = findIndexByString(value, GPSBaudRateString, GPSBaudRateString_Elements);
 | 
			
		||||
    LubeConfig.GPSBaudRate = (GPSBaudRate_t)index;
 | 
			
		||||
  }
 | 
			
		||||
  else if (strcmp(identifier, "ledmaxbrightness") == 0)
 | 
			
		||||
  {
 | 
			
		||||
    LubeConfig.LED_Max_Brightness = atoi(value);
 | 
			
		||||
  }
 | 
			
		||||
  else if (strcmp(identifier, "ledminbrightness") == 0)
 | 
			
		||||
  {
 | 
			
		||||
    LubeConfig.LED_Min_Brightness = atoi(value);
 | 
			
		||||
  }
 | 
			
		||||
  else if (strcmp(identifier, "pumppulse") == 0)
 | 
			
		||||
  {
 | 
			
		||||
    LubeConfig.BleedingPulses = atoi(value);
 | 
			
		||||
  }
 | 
			
		||||
  else if (strcmp(identifier, "tankwarn") == 0)
 | 
			
		||||
  {
 | 
			
		||||
    LubeConfig.TankRemindAtPercentage = atoi(value);
 | 
			
		||||
  }
 | 
			
		||||
  else if (strcmp(identifier, "tankcap") == 0)
 | 
			
		||||
  {
 | 
			
		||||
    LubeConfig.tankCapacity_ml = atoi(value);
 | 
			
		||||
  }
 | 
			
		||||
  else if (strcmp(identifier, "lubedistancerain") == 0)
 | 
			
		||||
  {
 | 
			
		||||
    LubeConfig.DistancePerLube_Rain = atoi(value);
 | 
			
		||||
  }
 | 
			
		||||
  else if (strcmp(identifier, "lubedistancenormal") == 0)
 | 
			
		||||
  {
 | 
			
		||||
    LubeConfig.DistancePerLube_Default = atoi(value);
 | 
			
		||||
  }
 | 
			
		||||
  else if (strcmp(identifier, "ledmodeflash") == 0)
 | 
			
		||||
  {
 | 
			
		||||
    LubeConfig.LED_Mode_Flash = value[0] == '1' ? true : false;
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    Debug_pushMessage("Got unknown Settings-id and value '%s' from ws-client\n", identifier);
 | 
			
		||||
@@ -795,3 +831,37 @@ int findIndexByString(const char *searchString, const char *const *array, int ar
 | 
			
		||||
  // String nicht gefunden, gib -1 zurück
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief Pushes a notification to all WebSocket clients.
 | 
			
		||||
 *
 | 
			
		||||
 * This function sends a live debug message to all connected WebSocket clients.
 | 
			
		||||
 *
 | 
			
		||||
 * @param Message The debug message to be sent.
 | 
			
		||||
 * @param type The type of notification (info, success, warning, error).
 | 
			
		||||
 *             - Use NotificationType_t::info for informational messages.
 | 
			
		||||
 *             - Use NotificationType_t::success for successful operation messages.
 | 
			
		||||
 *             - Use NotificationType_t::warning for warning messages.
 | 
			
		||||
 *             - Use NotificationType_t::error for error messages.
 | 
			
		||||
 */
 | 
			
		||||
void Websocket_PushNotification(String Message, NotificationType_t type)
 | 
			
		||||
{
 | 
			
		||||
  String typeString = "";
 | 
			
		||||
  switch (type)
 | 
			
		||||
  {
 | 
			
		||||
  case info:
 | 
			
		||||
    typeString = "info";
 | 
			
		||||
    break;
 | 
			
		||||
  case success:
 | 
			
		||||
    typeString = "success";
 | 
			
		||||
    break;
 | 
			
		||||
  case warning:
 | 
			
		||||
    typeString = "warning";
 | 
			
		||||
    break;
 | 
			
		||||
  case error:
 | 
			
		||||
    typeString = "danger";
 | 
			
		||||
    break;
 | 
			
		||||
  }
 | 
			
		||||
  webSocket.textAll("NOTIFY:" + typeString + ";" + Message);
 | 
			
		||||
  Debug_pushMessage("Sending Notification to WebUI: %s\n", typeString);
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user