Finalize documenting and clean up of website code
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

Signed-off-by: Severin Kaderli <severin@kaderli.dev>
This commit is contained in:
Severin Kaderli 2022-11-23 18:35:04 +01:00
parent 436e261fa7
commit 79fbcdedc3
Signed by: severinkaderli
GPG key ID: F419F8835B72F0C4
5 changed files with 142 additions and 69 deletions

View file

@ -10,7 +10,7 @@
<body> <body>
<main> <main>
<!-- Pattern will only match valid ASCII characters --> <!-- The pattern on the input will only match valid ASCII characters -->
<input <input
required required
minlength="1" minlength="1"

View file

@ -1,13 +1,37 @@
/** class Constants {
* The amount of time in ms a bit takes to transmit. /**
* * The amount of time in ms a bit takes to transmit.
* @type {Number} *
*/ * @type {Number}
const CLOCK_TIME = 500; */
static get CLOCK_TIME() {
return 500;
}
/** /**
* The preamble that is sent before the packet. * The preamble that is sent before the packet.
* *
* @type {Number[]} * @type {Number[]}
*/ */
const PREAMBLE = [1, 1, 1, 0, 0, 0, 1, 1, 1]; static get PREAMBLE() {
return [1, 1, 1, 0, 0, 0, 1, 1, 1];
}
/**
* The number of workers that should be started.
*
* @type {Number}
*/
static get NUMBER_OF_WORKERS() {
return 8;
}
/**
* The CSS class to add to buttons that should be hidden.
*
* @type {String}
*/
static get HIDE_CLASS() {
return "hide";
}
}

View file

@ -1,27 +1,61 @@
const hideClass = "hide"; /**
let isSending = false; * Global flag that indicates if any bits should be transmitted. This flag
* is used to stop the transmission of bits.
*
* @type {Boolean}
*/
let isTransmitting = false;
/**
* Array that contains all currently running web workers.
*
* @type {Worker[]}
*/
let workers = []; let workers = [];
/**
* @type {HTMLInputElement}
*/
const textInput = document.getElementById("textInput"); const textInput = document.getElementById("textInput");
/**
* @type {HTMLButtonElement}
*/
const startSendingButton = document.getElementById("start-sending-button"); const startSendingButton = document.getElementById("start-sending-button");
/**
* @type {HTMLButtonElement}
*/
const stopSendingButton = document.getElementById("stop-sending-button"); const stopSendingButton = document.getElementById("stop-sending-button");
/**
* @type {HTMLButtonElement}
*/
const startCalibrationButton = document.getElementById("start-calibration-button"); const startCalibrationButton = document.getElementById("start-calibration-button");
/**
* @type {HTMLButtonElement}
*/
const stopCalibrationButton = document.getElementById("stop-calibration-button"); const stopCalibrationButton = document.getElementById("stop-calibration-button");
// Add event listeners to the buttons
startCalibrationButton.addEventListener("click", startCalibration); startCalibrationButton.addEventListener("click", startCalibration);
stopCalibrationButton.addEventListener("click", stopCalibration); stopCalibrationButton.addEventListener("click", stopCalibration);
startSendingButton.addEventListener("click", startSending); startSendingButton.addEventListener("click", startSending);
stopSendingButton.addEventListener("click", stopSending); stopSendingButton.addEventListener("click", stopSending);
function getWebWorker() { /**
return new Worker("./scripts/Worker.js"); * Starts the web workers and add them to the global worker array.
} */
function startWorkers() { function startWorkers() {
for (let i = 0; i < 8; i++) { for (let i = 0; i < Constants.NUMBER_OF_WORKERS; i++) {
workers.push(getWebWorker()); workers.push(new Worker("./scripts/Worker.js"));
} }
} }
/**
* Terminates all currently running workers and clear out the worker array.
*/
function stopWorkers() { function stopWorkers() {
for (const worker of workers) { for (const worker of workers) {
worker.terminate(); worker.terminate();
@ -30,32 +64,38 @@ function stopWorkers() {
workers = []; workers = [];
} }
/**
* Starts the calibration process by simply starting all web workers.
*/
function startCalibration() { function startCalibration() {
console.log("Starting calibration");
startCalibrationButton.classList.add(hideClass);
stopCalibrationButton.classList.remove(hideClass);
Utility.setMessage("Calibration currently ongoing."); Utility.setMessage("Calibration currently ongoing.");
startCalibrationButton.classList.add(Constants.HIDE_CLASS);
stopCalibrationButton.classList.remove(Constants.HIDE_CLASS);
startWorkers(); startWorkers();
} }
/**
* Stops the calibration process by stopping all currently running web workers.
*/
function stopCalibration() { function stopCalibration() {
console.log("Stopping calibration");
stopCalibrationButton.classList.add(hideClass);
startCalibrationButton.classList.remove(hideClass);
Utility.setMessage(""); Utility.setMessage("");
stopCalibrationButton.classList.add(Constants.HIDE_CLASS);
startCalibrationButton.classList.remove(Constants.HIDE_CLASS);
stopWorkers(); stopWorkers();
} }
/**
* Starts sending the message in the input after validating that the input is
* valid.
*/
function startSending() { function startSending() {
textInput.setCustomValidity("");
// Validate the input // Validate the input
textInput.setCustomValidity("");
if (!textInput.checkValidity()) { if (!textInput.checkValidity()) {
console.log(textInput.validity);
if (textInput.validity.valueMissing) { if (textInput.validity.valueMissing) {
textInput.setCustomValidity("Please enter between 1 and 16 characters."); textInput.setCustomValidity("Please enter between 1 and 16 characters.");
} }
@ -68,37 +108,41 @@ function startSending() {
return; return;
} }
startSendingButton.classList.add(hideClass);
stopSendingButton.classList.remove(hideClass);
Utility.setMessage(`Sending message: ${textInput.value}`); Utility.setMessage(`Sending message: ${textInput.value}`);
console.log(`Start sending message: ${textInput.value}`); console.log(`Start sending message: ${textInput.value}`);
startSendingButton.classList.add(Constants.HIDE_CLASS);
stopSendingButton.classList.remove(Constants.HIDE_CLASS);
const packet = new Packet(textInput.value); const packet = new Packet(textInput.value);
const signal = Utility.manchesterEncode(packet.getData()); const signal = Utility.manchesterEncode(packet.getData());
isSending = true; isTransmitting = true;
transmitSignal(signal); transmitSignal(signal);
} }
/**
* Stop the sending process.
*/
function stopSending() { function stopSending() {
console.log("Stop Sending"); console.log("Stop Sending");
Utility.setMessage(""); Utility.setMessage("");
stopSendingButton.classList.add(hideClass); stopSendingButton.classList.add(Constants.HIDE_CLASS);
startSendingButton.classList.remove(hideClass); startSendingButton.classList.remove(Constants.HIDE_CLASS);
isSending = false; isTransmitting = false;
} }
/** /**
* Transmit the given bit array until the sending is stopped. * Transmits the given bit array until the sending is stopped. The transmission
* is stopped when the global isTransmitting flag is set to false.
* *
* @param {Number[]} signal * @param {Number[]} signal
*/ */
async function transmitSignal(signal) { async function transmitSignal(signal) {
while (isSending) { while (isTransmitting) {
// Send the preamble // Send the preamble
for (const bit of PREAMBLE) { for (const bit of Constants.PREAMBLE) {
if (!isSending) { if (!isTransmitting) {
stopWorkers(); stopWorkers();
return; return;
} }
@ -108,7 +152,7 @@ async function transmitSignal(signal) {
} }
for (let i = 0; i < signal.length; i++) { for (let i = 0; i < signal.length; i++) {
if (!isSending) { if (!isTransmitting) {
stopWorkers(); stopWorkers();
return; return;
} }
@ -120,17 +164,17 @@ async function transmitSignal(signal) {
} }
/** /**
* This either starts or stops the web workers depending on the bit value * Starts or stops the web workers depending on the bit value and then waits
* and then waits for a duration of CLOCK_TIME. * for a duration of Constants.CLOCK_TIME.
* *
* @param {Number} bit * @param {Number} bit
*/ */
function transmitBit(bit) { function transmitBit(bit) {
if (bit === 1) { if (bit === 1) {
startWorkers(); startWorkers();
return new Promise((resolve) => setTimeout(resolve, CLOCK_TIME)); return new Promise((resolve) => setTimeout(resolve, Constants.CLOCK_TIME));
} }
stopWorkers(); stopWorkers();
return new Promise((resolve) => setTimeout(resolve, CLOCK_TIME)); return new Promise((resolve) => setTimeout(resolve, Constants.CLOCK_TIME));
} }

View file

@ -1,6 +1,5 @@
/** /**
* * This class represents a packet containing a header, payload and checksum.
*/ */
class Packet { class Packet {
/** /**
@ -26,6 +25,8 @@ class Packet {
#checksum = []; #checksum = [];
/** /**
* Creates a new packet with the given text as the payload.
*
* @param {String} payloadText * @param {String} payloadText
*/ */
constructor(payloadText) { constructor(payloadText) {
@ -53,11 +54,11 @@ class Packet {
} }
/** /**
* Turn a string into an array of ASCII code points. * Turns a string into an array of ASCII code points.
* *
* @param {String} text * @param {String} text
* @return {Number[]} * @return {Number[]}
*/ */
#textToCodePoints(text) { #textToCodePoints(text) {
const codePoints = []; const codePoints = [];
for (let i = 0; i < text.length; i++) { for (let i = 0; i < text.length; i++) {
@ -67,11 +68,11 @@ class Packet {
} }
/** /**
* Turn a string into an bit array. * Turns a string into a bit array.
* *
* @param {String} text * @param {String} text
* @return {Number[]} * @return {Number[]}
*/ */
#textToBitArray(text) { #textToBitArray(text) {
const codePoints = this.#textToCodePoints(text); const codePoints = this.#textToCodePoints(text);
let bitArray = []; let bitArray = [];
@ -82,17 +83,22 @@ class Packet {
} }
/** /**
* Calculate the checksum of the given array of bytes and return it * Calculates the checksum of the given array of bytes and return it
* as an bit array. * as a bit array.
* *
* @param {Number[]} bytes * @param {Number[]} bytes
* @return {Number[]} * @return {Number[]}
*/ */
#calculateChecksum(bytes) { #calculateChecksum(bytes) {
const checksum = Utility.crc8Autosar(bytes); const checksum = Utility.crc8Autosar(bytes);
return this.#numberToBitArray(checksum, 8); return this.#numberToBitArray(checksum, 8);
} }
/**
* Returns all data of the packet as a bit array.
*
* @return {Number[]}
*/
getData() { getData() {
return [...this.#header, ...this.#payload, ...this.#checksum]; return [...this.#header, ...this.#payload, ...this.#checksum];
} }

View file

@ -1,7 +1,6 @@
class Utility { class Utility {
/** /**
* This method calculates the CRC-8-AUTOSAR checksum of the given * Calculates the CRC-8-AUTOSAR checksum of the given array of bytes.
* array of bytes.
* *
* This code is based on the code examples from the following page: * This code is based on the code examples from the following page:
* http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html * http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html
@ -48,7 +47,7 @@ class Utility {
} }
/** /**
* Take a bit array and encode the contents using manchester encoding. * Eencode the contents of the given bit array using manchester encoding.
* *
* @param {Number[]} bitArray * @param {Number[]} bitArray
* @return {Number[]} * @return {Number[]}
@ -65,7 +64,7 @@ class Utility {
} }
/** /**
* Set the information message on the page to the given string. * Sets the information message on the page to the given string.
* @param {String} text * @param {String} text
*/ */
static setMessage(text) { static setMessage(text) {