@ayan4m1/pulsar
Advanced tools
Comparing version 0.1.0 to 0.2.0
{ | ||
"name": "@ayan4m1/pulsar", | ||
"private": false, | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"description": "Record and play back sessions on a DNA device.", | ||
@@ -21,4 +20,4 @@ "author": "ayan4m1 <andrew@bulletlogic.com>", | ||
"dependencies": { | ||
"chartscii": "^1.3.2", | ||
"commander": "^12.0.0", | ||
"dotenv": "^16.4.5", | ||
"papaparse": "^5.4.1", | ||
@@ -25,0 +24,0 @@ "serialport": "^12.0.0", |
# Pulsar | ||
[](https://badge.fury.io/js/@ayan4m1%2Fpulsar) | ||
This is software to run scripted firing sequences on an Evolv DNA device. | ||
@@ -9,2 +11,4 @@ | ||
Install the current [Node.js LTS version](https://nodejs.org/en). | ||
> npm i -g @ayan4m1/pulsar | ||
@@ -16,2 +20,26 @@ | ||
TODO: Document CSV format, provide true usage examples. | ||
**TODO**: Proper usage examples! | ||
## Puff Files | ||
A .puff file is a CSV file like this: | ||
```csv | ||
# Lines starting with a hash are comments and are ignored | ||
# The next line sets wattage to 10 watts | ||
W,10 | ||
# The next line fires for 5 seconds | ||
F,5 | ||
# The next line waits for 7 seconds | ||
P,7 | ||
# Now a simple "wattage curve" for demonstration | ||
W,30 | ||
F,3 | ||
P,1 | ||
W,50 | ||
F,3 | ||
P,2 | ||
W,40 | ||
F,3 | ||
P,5 | ||
``` |
@@ -1,4 +0,5 @@ | ||
import { readFileSync, writeFileSync } from 'fs'; | ||
import Papa from 'papaparse'; | ||
import { resolve } from 'path'; | ||
import { program } from 'commander'; | ||
import { readFile, writeFile } from 'fs/promises'; | ||
@@ -15,3 +16,10 @@ import { getLogger } from '../modules/logging.js'; | ||
export default function (input, output) { | ||
program | ||
.argument('<input>', 'Input .csv file from EScribe (Record Puff)') | ||
.argument('<output>', 'Output .puff file') | ||
.parse(); | ||
try { | ||
const [input, output] = program.args; | ||
if (!input || !output) { | ||
@@ -23,3 +31,3 @@ log.error('Required arguments missing!'); | ||
log.info('Reading CSV...'); | ||
const { data } = Papa.parse(readFileSync(resolve(input), 'utf-8'), { | ||
const { data } = Papa.parse(await readFile(resolve(input), 'utf-8'), { | ||
header: true, | ||
@@ -31,6 +39,6 @@ skipEmptyLines: true | ||
let lastEndTime = 0; | ||
let lastTime = 0; | ||
let lastCurrent = 0; | ||
let lastPower = 0; | ||
let lastEndTime = 0, | ||
lastTime = 0, | ||
lastCurrent = 0, | ||
lastPower = 0; | ||
const commands = []; | ||
@@ -69,4 +77,7 @@ | ||
writeFileSync(output, commands.join('\n')); | ||
await writeFile(output, commands.join('\n')); | ||
log.info(`Wrote ${commands.length} commands to ${output}!`); | ||
} catch (error) { | ||
console.error(error); | ||
process.exit(1); | ||
} |
@@ -1,4 +0,5 @@ | ||
import { readFileSync } from 'fs'; | ||
import Papa from 'papaparse'; | ||
import { resolve } from 'path'; | ||
import { program } from 'commander'; | ||
import { readFile } from 'fs/promises'; | ||
import { SerialPort } from 'serialport'; | ||
@@ -15,3 +16,14 @@ | ||
export default function (path, { port }) { | ||
program | ||
.argument('<path>', 'CSV script') | ||
.requiredOption( | ||
'-p, --port <value>', | ||
'Serial port (e.g. "COM3" or /dev/ttyUSB0)' | ||
) | ||
.parse(); | ||
try { | ||
const [path] = program.args; | ||
const { port } = program.opts(); | ||
if (!path) { | ||
@@ -22,4 +34,7 @@ log.error('Required argument missing!'); | ||
log.info('Reading script...'); | ||
const { data } = Papa.parse(readFileSync(resolve(path), 'utf-8')); | ||
log.info('Reading puff data...'); | ||
const { data } = Papa.parse(await readFile(resolve(path), 'utf-8'), { | ||
comments: '#', | ||
skipEmptyLines: true | ||
}); | ||
@@ -51,4 +66,3 @@ log.info(`Read ${data.length} rows`); | ||
for (const row of data) { | ||
const [action, rawValue] = row; | ||
for (const [action, rawValue] of data) { | ||
const value = parseFloat(rawValue); | ||
@@ -76,2 +90,5 @@ | ||
}); | ||
} catch (error) { | ||
console.error(error); | ||
process.exit(1); | ||
} |
#!/usr/bin/env node | ||
import { Command } from 'commander'; | ||
import { program } from 'commander'; | ||
import { fileURLToPath } from 'url'; | ||
import { readFile } from 'fs/promises'; | ||
import { dirname, resolve } from 'path'; | ||
import convert from './commands/convert.js'; | ||
import run from './commands/run.js'; | ||
try { | ||
const __dirname = dirname(fileURLToPath(import.meta.url)); | ||
const commandDir = resolve(__dirname, 'commands'); | ||
const packageJsonPath = resolve(__dirname, '..', 'package.json'); | ||
const { description, version } = JSON.parse( | ||
await readFile(packageJsonPath, 'utf-8') | ||
); | ||
const program = new Command(); | ||
program.name('pulsar').version('0.1.0').description('Scripted DNA control'); | ||
program | ||
.command('run') | ||
.description('Run a script') | ||
.argument('<path>', 'CSV script') | ||
.requiredOption( | ||
'-p, --port <value>', | ||
'Serial port (e.g. "COM3" or /dev/ttyUSB0)' | ||
) | ||
.action(run); | ||
program | ||
.command('convert') | ||
.description('Converts an EScribe CSV to a script') | ||
.argument('<input>', 'Input CSV from EScribe') | ||
.argument('<output>', 'Output script') | ||
.action(convert); | ||
program.parse(); | ||
program | ||
.name('pulsar') | ||
.version(version) | ||
.description(description) | ||
.executableDir(commandDir) | ||
.command('run', 'Play back a .puff file', { | ||
executableFile: 'run.js' | ||
}) | ||
.command( | ||
'convert', | ||
'Convert an EScribe recorded puff .csv to a .puff file', | ||
{ | ||
executableFile: 'convert.js' | ||
} | ||
) | ||
.command('validate', 'Validate a .puff file', { | ||
executableFile: 'validate.js' | ||
}) | ||
.command('visualize', 'Produce an ASCII bar chart of a .puff file', { | ||
executableFile: 'visualize.js' | ||
}) | ||
.parseAsync(); | ||
} catch (error) { | ||
console.error(error); | ||
process.exit(1); | ||
} |
@@ -0,0 +0,0 @@ import winston from 'winston'; |
Sorry, the diff of this file is not supported yet
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
10760
9
271
44
8
+ Addedchartscii@^1.3.2
+ Addedchartscii@1.3.2(transitive)
+ Addedstyl3@1.4.0(transitive)
- Removeddotenv@^16.4.5
- Removeddotenv@16.4.7(transitive)