-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
141 lines (131 loc) · 5.7 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
Gameboy Printer Emulator Server
Licensed under GPLv3
Copyright (C) 2023 KiwifruitDev
*/
// Import packages
const { SerialPort, ReadlineParser } = require('serialport');
const { execSync, exec } = require('child_process');
const fs = require('fs');
// Local imports
const gbp = require('./gbp_gameboyprinter2bpp.js');
// Config file
const config = require('./config.json');
// Connect USB serial interface from config.serialPort
const port = new SerialPort({
path: config.serialPort,
baudRate: config.baudRate
});
let curData = '';
let init = false;
// Pair with bluetooth device with bluetoothctl
if (config.bluetoothEnabled && !config.bluetoothPaired) {
if(!config.silent) console.log('Pairing with bluetooth device... Set bluetoothPaired to true in config.json to skip this step');
// Pair with bluetooth device
try {
// Delete bash script if it exists
if (fs.existsSync('./pair.sh')) fs.unlinkSync('./pair.sh');
// Write bash script to file
fs.writeFileSync('./pair.sh',
`#!/bin/bash\n`
+`{ printf 'scan on\\n\\n'; `
+`while ! grep -q '${config.bluetoothAddress}' <(bluetoothctl devices); `
+`do sleep 1; done; printf 'scan off\\n\\n'; printf 'pair ${config.bluetoothAddress}\\n\\n'; `
+`sleep 10; printf 'yes\\n\\n'; sleep 5; printf 'trust ${config.bluetoothAddress}\\n\\n'; `
+`sleep 2; printf 'quit\\n\\n'; } | bluetoothctl`);
// Make bash script executable
fs.chmodSync('./pair.sh', 0o777);
// Run bash script
execSync('./pair.sh');
// Delete bash script
fs.unlinkSync('./pair.sh');
// Load config file with fs
let configData = fs.readFileSync('./config.json');
// Parse config file as JSON
let configJSON = JSON.parse(configData);
// Set bluetoothPaired to true
configJSON.bluetoothPaired = true;
// Write config file
fs.writeFileSync('./config.json', JSON.stringify(configJSON, null, 4));
if(!config.silent) console.log('Paired with bluetooth device');
} catch (err) {
if(!config.silent) console.log('Error pairing with bluetooth device');
}
}
// Continuously parse data from serial port
const parser = port.pipe(new ReadlineParser());
parser.on('data', function (data) {
// Convert data to string
var dataString = data.toString();
// Empty data: return
if (dataString === '') return;
// DEBUG: Print data
if(!config.silent) console.log(`${(init ? 'INIT' : 'DATA')}: ${dataString}`);
// If init, just add it to curData
if (init) {
// Check for "// Timed Out"
if (dataString.includes('{"command":"INQY", "status":{"LowBat":0,"ER2":0,"ER1":0,"ER0":0,"Untran":0,"Full":1,"Busy":0,"Sum":0}}')) {
init = false;
dataString += `${dataString}\n`;
// Timestamp in format of YYYY-MM-DD_HH-MM-SS
const timestamp = new Date().toISOString().replace(/:/g, '-').replace('T', '_').split('.')[0];
for(let p = 0; p < config.palettes.length; p++) {
// Render image
const canvases = gbp.render(curData, config.palettes[p]);
for(let i = 0; i < canvases.length; i++) {
const stream = canvases[i].createPNGStream();
// Create output folder if it doesn't exist
if (!fs.existsSync('./output')) {
fs.mkdirSync('./output');
}
if (!fs.existsSync(`./output/${timestamp}`)) {
fs.mkdirSync(`./output/${timestamp}`);
}
// Write to file
const out = fs.createWriteStream(`./output/${timestamp}/${i}_${config.palettes[p]}.png`);
stream.pipe(out);
// If default, move to output folder
if (config.palettes[p] === config.defaultPalette) {
fs.rename(`./output/${timestamp}/${i}_${config.palettes[p]}.png`, `./output/${timestamp}_${i}.png`, (err) => {
if (err && !config.silent) console.log(err);
});
}
}
}
// Check if file exists
if (fs.existsSync(`./output/${timestamp}_0.png`)) {
// Initiate bluetooth transfer with config.bluetoothAddress using obexftp
if (config.bluetoothEnabled) {
try {
exec(`obexftp --nopath --noconn --uuid none --bluetooth ${config.bluetoothAddress} --channel ${config.obexPushChannel} --put ./output/${timestamp}_0.png`, (err, stdout, stderr) => {});
}
catch (err) {}
}
// If saveLocally is not enabled, delete the file after 20 seconds
if (!config.saveLocally) {
exec(`sleep 20 && rm ./output/${timestamp}_0.png && rm -r ./output/${timestamp}`);
}
}
// If folder is empty, delete it
if (fs.readdirSync(`./output/${timestamp}`).length === 0) {
fs.rmdir(`./output/${timestamp}`, (err) => {
if (err && !config.silent) console.log(err);
});
}
// If output folder is empty after 20 seconds, delete it
exec(`sleep 20 && rmdir ./output`);
return;
}
}
// Parse as json
else if(dataString.includes('"command":"INIT"')) {
init = true;
curData = '';
}
if (init) {
curData += `${dataString}\n`;
}
});
parser.on('error', function (err) {
if(!config.silent) console.log('Error: ', err.message);
});