mirror of
https://github.com/daniviga/django-ram.git
synced 2025-08-04 21:27:49 +02:00
Import WebThrottle-EX from ca33f6a
This commit is contained in:
187
ram/driver/static/wt/js/emulator.js
Normal file
187
ram/driver/static/wt/js/emulator.js
Normal file
@@ -0,0 +1,187 @@
|
||||
/* This is part of the DCC++ EX Project for model railroading and more.
|
||||
For licence information, please see index.html.
|
||||
For more information, see us at dcc-ex.com.
|
||||
|
||||
emulator.js
|
||||
|
||||
Allows the software to operate without a Command Station attached. This
|
||||
file manages the correct response that a Command Station would provide.
|
||||
*/
|
||||
/**
|
||||
* Utility function can be moved when we can import files
|
||||
* @description Removes control characters "<", ">" and "\n"
|
||||
* @param {string} packet
|
||||
* @return {string}
|
||||
*/
|
||||
function removeControlCharacters(packet) {
|
||||
return [...packet].filter(char => !["<", ">", "\n"].includes(char)).join("")
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function can be moved when we can import files
|
||||
* @description Finds the first non-blank character after control characters are removed
|
||||
* @param {string} packet
|
||||
* @return {string}
|
||||
*/
|
||||
function extractPacketKey(packet) {
|
||||
const cleanedPacket = [...removeControlCharacters(packet)]
|
||||
return cleanedPacket.find(char => char !== " ");
|
||||
}
|
||||
|
||||
class Emulator {
|
||||
constructor({logger}) {
|
||||
this.turnoutEmulator = new TurnoutEmulator()
|
||||
this.logger = logger
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} packet
|
||||
*/
|
||||
write(packet) {
|
||||
if (packet === "<credits>") {
|
||||
console.log("Credits")
|
||||
return credits()
|
||||
}
|
||||
|
||||
let packetKey = extractPacketKey(packet);
|
||||
|
||||
switch (packetKey) {
|
||||
// Cab control
|
||||
case ("t"):
|
||||
this.logger('[RECEIVE] '+ this.#cabControlCommand(packet))
|
||||
break;
|
||||
|
||||
// Track power off
|
||||
case ('0') :
|
||||
this.logger('[RECEIVE] '+ this.#powerOffCommand(packet));
|
||||
break;
|
||||
|
||||
// Track power on
|
||||
case ('1'):
|
||||
this.logger('[RECEIVE] '+ this.#powerOnCommand(packet));
|
||||
break;
|
||||
|
||||
// New cab functions
|
||||
case ('F'):
|
||||
this.logger('[RECEIVE] '+ this.#cabFunctionCommand(packet));
|
||||
break;
|
||||
|
||||
// Legacy cab functions
|
||||
case ('f'):
|
||||
|
||||
this.logger('[RECEIVE] '+ this.#cabFunctionCommand(packet, true));
|
||||
break;
|
||||
|
||||
// Turnouts
|
||||
case ('T'): //Not fully finished
|
||||
this.logger('[RECEIVE] '+ this.#turnoutCommand(packet, this.turnoutEmulator))
|
||||
break
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} packet
|
||||
* @return {string}
|
||||
*/
|
||||
#cabControlCommand(packet) {
|
||||
const splitPacket = packet.split(" ");
|
||||
return 'T 1 ' + splitPacket[3] + ' ' + splitPacket[4].substring(0, splitPacket[4].length - 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} packet
|
||||
* @return {string}
|
||||
*/
|
||||
#powerOffCommand(packet) {
|
||||
return 'p0';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} packet
|
||||
* @return {string}
|
||||
*/
|
||||
#powerOnCommand(packet) {
|
||||
return 'p1';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} packet
|
||||
* @param {boolean} legacy
|
||||
* @return number
|
||||
*/
|
||||
#cabFunctionCommand(packet, legacy = false) {
|
||||
return NaN;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} packet
|
||||
* @param {TurnoutEmulator} turnoutEmulator
|
||||
* @return {string}
|
||||
*/
|
||||
#turnoutCommand(packet, turnoutEmulator = new TurnoutEmulator()) {
|
||||
const splitPacket = removeControlCharacters(packet).split(" ");
|
||||
|
||||
if (splitPacket.length === 4) {
|
||||
// Adds a Turnout
|
||||
return turnoutEmulator.addTurnout(new Turnout(packet))
|
||||
} else if (splitPacket.length === 2) {
|
||||
// Removes a Turnout
|
||||
return turnoutEmulator.removeTurnout(splitPacket[1])
|
||||
} else if (splitPacket.length === 1) {
|
||||
// Reads Turnouts
|
||||
return turnoutEmulator.turnouts
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TurnoutEmulator {
|
||||
/**
|
||||
* @type {[]}
|
||||
*/
|
||||
#turnouts = []
|
||||
|
||||
/**
|
||||
* @return {string|string[]}
|
||||
*/
|
||||
get turnouts() {
|
||||
if (!this.#turnouts.length) {
|
||||
return 'X'
|
||||
}
|
||||
|
||||
return this.#turnouts.map(turnout => `H ${turnout.id} ${turnout.address} ${turnout.subaddress} ${turnout.thrown}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {*} turnout
|
||||
* @return {string}
|
||||
*/
|
||||
addTurnout(turnout) {
|
||||
this.#turnouts = [...this.#turnouts, turnout]
|
||||
console.log(this.#turnouts);
|
||||
return '<O>';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} turnoutId
|
||||
* @return {string}
|
||||
*/
|
||||
removeTurnout(turnoutId) {
|
||||
this.#turnouts = this.#turnouts.filter(turnout => turnout.id !== turnoutId);
|
||||
console.log(this.#turnouts);
|
||||
return 'O';
|
||||
}
|
||||
}
|
||||
|
||||
class Turnout {
|
||||
constructor(packet) {
|
||||
let [_key, id, address, subaddress] = removeControlCharacters(packet).split(" ");
|
||||
|
||||
this.id = id
|
||||
this.address = address
|
||||
this.subaddress = subaddress
|
||||
this.thrown = 0
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user