/
LocalPrinter.js
130 lines (108 loc) · 3.44 KB
/
LocalPrinter.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
import cron from 'node-cron'
import Printer from 'thermalprinter'
import { Gpio } from 'onoff'
import IssueGenerator from './IssueGenerator.js'
// https://github.com/xseignard/thermalPrinter
export default class LocalPrinter {
constructor({ deleteAfterPrint, issueTitle, schedule = [], button }) {
this.printer = null
this.config = {
deleteAfterPrint,
issueTitle,
schedule,
button
}
this.generator = new IssueGenerator(this.config)
this.generator.on('print', (filename) => this._print(filename))
this.setSchedule(schedule)
if (button.pin) {
this.btn = new Gpio(button.pin, 'in', 'rising', { debounceTimeout: 100 })
this.btn.watch((err, value) => this.createIssue(button.issueType));
if (button.ledPin) {
this.led = new Gpio(button.ledPin, 'out')
const iv = setInterval(_ => this.led.writeSync(this.led.readSync() ^ 1), 500);
}
}
process.on('SIGINT', _ => {
if (this.btn) this.btn.unexport();
if (this.led) this.led.unexport();
})
}
_flashLed(speed = 300) {
if (!this.led) return
this.ledIv = setInterval(_ => this.led.writeSync(this.led.readSync() ^ 1), speed);
}
_unflashLed() {
if (!this.ledIv) return
clearInterval(this.ledIv)
this.ledIv = null
this.led.writeSync(0)
}
async connect(serialPort) {
return new Promise((r, j) => {
console.log('[LocalPrinter] Waiting for serial port to be ready...')
this.serialPort = serialPort
this.serialPort.on('open', () => {
console.log('[LocalPrinter] Serial port is ready')
this.printer = new Printer(this.serialPort)
r()
})
this.serialPort.on('error', err => {
console.log(`[LocalPrinter] Serial port error: ${err.message}`)
})
})
}
addPlugin(plugin, opts) {
plugin.registerPrinter(this)
this.generator.addPlugin(plugin, opts)
}
clearSchedule() {
this.config.schedule
.filter(({ task }) => !!task)
.forEach(item => item.task.destroy())
}
setSchedule(issues) {
this.clearSchedule()
this.config.schedule = issues.map(({ pattern, issueType }) => {
const task = cron.schedule(pattern, () => this.createIssue(issueType))
return { pattern, issueType, task }
})
}
async start() {
this._flashLed(500)
console.log('[LocalPrinter] Starting...')
await this.generator.initialize()
console.log('[LocalPrinter] Running')
console.log(this.config.schedule.map(({ pattern, issueType }) => ` - ${issueType} issue at ${pattern}`).join('\n'))
this._unflashLed()
}
async createIssue(type = 'full') {
this._flashLed(200)
if (type === 'full') {
await this.generator.createIssue()
} else if (type === 'update') {
await this.generator.createUpdateIssue()
}
this._unflashLed()
}
// Handle GPIO for main button pushed, should create a full issue
async buttonPushed() {
await this.createIssue('full')
}
_actuallyPrint(filename) {
return new Promise((r, j) => {
if (!this.printer) {
console.log(`[LocalPrinter] Printer not connected, written to file: ${filename}`)
return r()
}
console.log(`[LocalPrinter] Printing ${filename}`)
this.printer.printImage(filename).print(r)
})
}
// Emitted by generator once file is ready
async _print(filename) {
await this._actuallyPrint(filename)
console.log('[LocalPrinter] Print completed')
// Do any more cleanup
}
}