mirror of
https://github.com/jwetzell/aas-js.git
synced 2026-08-20 04:19:05 +00:00
initial commit
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
node: true,
|
||||
commonjs: true,
|
||||
es2021: true,
|
||||
},
|
||||
extends: ['airbnb', 'prettier'],
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
},
|
||||
rules: {
|
||||
'prefer-destructuring': 'off',
|
||||
'class-methods-use-this': 'off',
|
||||
'import/extensions': 'off',
|
||||
'import/no-relative-packages': 'off',
|
||||
'import/no-cycle': 'off',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
dist
|
||||
*.xml
|
||||
@@ -0,0 +1,2 @@
|
||||
*.md
|
||||
*.min.*
|
||||
@@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
trailingComma: 'es5',
|
||||
tabWidth: 2,
|
||||
semi: true,
|
||||
singleQuote: true,
|
||||
bracketSameLine: true,
|
||||
printWidth: 120,
|
||||
};
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"recommendations": ["esbenp.prettier-vscode"]
|
||||
}
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": true,
|
||||
"source.organizeImports": true
|
||||
}
|
||||
}
|
||||
Generated
+3412
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"name": "aas",
|
||||
"version": "0.0.0",
|
||||
"description": "collection of things related to All American Scoreboards 8000",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "npm run start --workspace packages/cli"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.51.0",
|
||||
"eslint-config-airbnb": "^19.0.4",
|
||||
"eslint-config-prettier": "^9.0.0",
|
||||
"prettier": "^3.0.3"
|
||||
},
|
||||
"workspaces": [
|
||||
"packages/lib",
|
||||
"packages/cli"
|
||||
]
|
||||
}
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { SerialPort } = require('serialport');
|
||||
const { Console, Packets } = require('aas-lib');
|
||||
const { writeFileSync } = require('fs');
|
||||
const { program } = require('commander');
|
||||
const packageInfo = require('./package.json');
|
||||
|
||||
program.name(packageInfo.name);
|
||||
program.version(packageInfo.version);
|
||||
program.description('Simple protocol router /s');
|
||||
program.option('-d, --device <serial port path>', 'serialport path');
|
||||
program.parse(process.argv);
|
||||
|
||||
const options = program.opts();
|
||||
if (!options.device) {
|
||||
console.error('app: no device specified');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const aasConsole = new Console();
|
||||
const port = new SerialPort({
|
||||
path: options.device,
|
||||
baudRate: 76800,
|
||||
});
|
||||
|
||||
port.on('error', (error) => {
|
||||
console.error('app: problem with serial port');
|
||||
console.error(error.message);
|
||||
});
|
||||
|
||||
// Switches the port into "flowing mode"
|
||||
port.on('data', (data) => {
|
||||
if (aasConsole) {
|
||||
aasConsole.update(data);
|
||||
writeFileSync('aa.json', JSON.stringify(aasConsole, null, 2));
|
||||
}
|
||||
});
|
||||
|
||||
port.write(Packets.START_LIVE);
|
||||
|
||||
process.on('SIGINT', () => {
|
||||
console.log('app: shutting down');
|
||||
port.write(Packets.STOP_LIVE);
|
||||
port.close();
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "aas-cli",
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"bin": "index.js",
|
||||
"scripts": {
|
||||
"start": "node index.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"aas-lib": "^0.1.0",
|
||||
"commander": "^11.1.0",
|
||||
"serialport": "^12.0.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
class Console {
|
||||
constructor() {
|
||||
this.sportInitialized = false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Buffer} buffer
|
||||
*/
|
||||
update(buffer) {
|
||||
switch (buffer.at(2)) {
|
||||
case 0x51:
|
||||
this.sport = 'basketball';
|
||||
this.parseBasketball(buffer);
|
||||
break;
|
||||
case 0x61:
|
||||
this.sport = 'football';
|
||||
throw new Error('Football is not implemented');
|
||||
case 0x70:
|
||||
this.sport = 'volleyball';
|
||||
throw new Error('Volleyball is not implemented');
|
||||
case 0x71:
|
||||
this.sport = 'baseball';
|
||||
throw new Error('Baseball is not implemented');
|
||||
case 0x16:
|
||||
this.sport = 'soccer';
|
||||
throw new Error('Soccer is not implemented');
|
||||
case 0x60:
|
||||
this.sport = 'wrestling';
|
||||
throw new Error('Wrestling is not implemented');
|
||||
case 0x40:
|
||||
this.sport = 'hockey';
|
||||
throw new Error('Hockey is not implemented');
|
||||
default:
|
||||
console.log(`unidentified sport data: ${buffer.toString('hex')}`);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Buffer} buffer
|
||||
*/
|
||||
parseBasketball(buffer) {
|
||||
const bufferHex = buffer.toString('hex');
|
||||
if (!this.sportInitialized) {
|
||||
this.time = {};
|
||||
|
||||
this.shotclock = {};
|
||||
|
||||
this.home = {};
|
||||
|
||||
this.guest = {};
|
||||
this.sportInitialized = true;
|
||||
}
|
||||
|
||||
this.time.minutes = bufferHex.substring(10, 12);
|
||||
this.time.seconds = bufferHex.substring(12, 14);
|
||||
this.time.tenths = bufferHex.substring(15, 16);
|
||||
|
||||
this.time.showTenths = bufferHex.at(8) === '1';
|
||||
this.time.display = `${this.time.minutes}:${this.time.seconds}`;
|
||||
|
||||
if (this.time.showTenths) {
|
||||
this.time.display += `.${this.time.tenths}`;
|
||||
}
|
||||
|
||||
this.shotclock.seconds = bufferHex.substring(16, 18);
|
||||
if (this.shotclock.seconds === 'aa') {
|
||||
this.shotclock.seconds = '00';
|
||||
}
|
||||
|
||||
this.shotclock.tenths = bufferHex.substring(19, 20);
|
||||
if (this.shotclock.tenths === 'a') {
|
||||
this.shotclock.tenths = '0';
|
||||
}
|
||||
|
||||
this.shotclock.display = `${this.shotclock.seconds}.${this.shotclock.tenths}`;
|
||||
|
||||
const seqNum = bufferHex.substring(20, 22);
|
||||
if (seqNum === '11') {
|
||||
const homeBinaryInfo = buffer.at(12).toString(2).padStart(8, '0');
|
||||
const guestBinaryInfo = buffer.at(14).toString(2).padStart(8, '0');
|
||||
|
||||
this.home.score = parseInt(bufferHex.substring(22, 24), 10);
|
||||
if (homeBinaryInfo[0] === '1') {
|
||||
this.home.score += 100;
|
||||
}
|
||||
this.guest.score = parseInt(bufferHex.substring(26, 28), 10);
|
||||
if (guestBinaryInfo[0] === '1') {
|
||||
this.guest.score += 100;
|
||||
}
|
||||
|
||||
this.home.poss = homeBinaryInfo[7] === '1';
|
||||
this.guest.poss = guestBinaryInfo[7] === '1';
|
||||
|
||||
this.home.doubleBonus = homeBinaryInfo[3] === '1';
|
||||
this.home.bonus = homeBinaryInfo[4] === '1';
|
||||
|
||||
this.guest.doubleBonus = guestBinaryInfo[3] === '1';
|
||||
this.guest.bonus = guestBinaryInfo[4] === '1';
|
||||
|
||||
this.home.fouls = parseInt(bufferHex.substring(32, 34), 10);
|
||||
this.guest.fouls = parseInt(bufferHex.substring(34, 36), 10);
|
||||
|
||||
this.home.timeouts = parseInt(bufferHex.substring(40, 41), 10);
|
||||
this.guest.timeouts = parseInt(bufferHex.substring(41, 42), 10);
|
||||
|
||||
this.period = parseInt(bufferHex.substring(31, 32), 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
Console,
|
||||
Packets: {
|
||||
START_LIVE: Buffer.from([
|
||||
...[0xfb, 0xb1, 0, 0, 0, 0, 0x54],
|
||||
...[0xfb, 0xc1, 0, 0, 0, 0, 0x44],
|
||||
...[0xfb, 0xb1, 0, 0, 0, 0, 0x54],
|
||||
]),
|
||||
STOP_LIVE: Buffer.from([...[0xfb, 0xc0, 0, 0, 0, 0, 0x45], ...[0xfb, 0xb0, 0, 0, 0, 0, 0x55]]),
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "aas-lib",
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"devDependencies": {},
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
}
|
||||
Reference in New Issue
Block a user