Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
@beuluis/thermaltastic
Advanced tools
Control a Adafruit thermal printer over different adapters
Control a Adafruit thermal printer over different adapters. This library is very WIP.
·
Report Bug
·
Request Feature
·
I wanted to talk to a thermal printer over an api. I experimented with a esp32 and quickly came to its limits.
After investigating the Adafruit library and many many failed other attempts, I concluded that I can extract the heavy lifting to TypeScript and only run a light mqtt to serial implementation on the esp32.
To allow different 'streams' like mqtt I came up with the adapter concept.
So now you can utilize the versatile package landscape of NPM to generate bitmaps, wrap it in REST APIs and and and.
npm i @beuluis/thermaltastic
The next
dist-tag is kept in sync with the latest commit on main. So this contains always the latest changes but is highly unstable.
npm i @beuluis/thermaltastic@next
const printer = new Thermaltastic(adapter);
await printer.begin();
await printer.println('Hello World!');
The original library used a serial stream to send the bytes to the printer. In this implementation we use adapters to achieve this.
A adapter defines how the printer receives the bytes.
Send the to print bytes over mqtt.
:warning: You need the corresponding arduino MQTT client also listening: See ThermalMqttasticPrinter for more details.
You also need a MQTT broker. An example would be eclipse-mosquitto.
const adapter = new MqttasticAdapter({
mqttUrl: 'mqtt://localhost:1883',
mqttOptions: {
password: '12345678',
},
});
new Thermaltastic(adapter);
mqttOptions
is the option interface of the MQTT package. Please refer to this documentation on how to establish the connection.
For your own adapter you just need to implement the Adapter
interface.
export class MyAdapter implements Adapter {
public async begin() {}
public async write(...bytes: [number, number?, number?, number?]) {}
public async writeBytes(...bytes: [number, number?, number?, number?]) {}
}
Parameters get validated using zod. Please refer to this documentation on how the parameters get validated.
setTimes(dotPrintTime: number, dotFeedTime: number)
This method sets the times (in microseconds) for the paper to advance one vertical 'dot' when printing and when feeding.
z.number().int().nonnegative().parse(dotPrintTime);
z.number().int().nonnegative().parse(dotFeedTime);
printer.setTimes(10, 15);
print(message: string)
Prints the message.
await printer.print('Hello World!');
println(message: string)
Prints the message with a line break at the end.
await printer.println('Hello World!');
begin(firmware = 268)
Initializes the printer and set default values. Needs to be called before performing any operations!
z.number().int().nonnegative().parse(firmware);
await printer.begin();
reset()
Resets the printer!
await printer.begin();
setDefaults()
Resets all text formatting back to the defaults.
await printer.setDefaults();
test()
Prints a test.
await printer.test();
testPage()
Prints a test page.
await printer.testPage();
setBarcodeHeight(barcodeHeight = 50)
Sets the printing height of the barcode.
z.number().int().nonnegative().parse(barcodeHeight);
await printer.setBarcodeHeight(60);
printBarcode(text: string, type: Barcode)
Prints a barcode.
z.string().max(255).parse(text);
await printer.printBarcode('ADAFRUT', Barcode.CODE39);
normal()
Sets print mode to normal.
await printer.normal();
inverseOn()
Turn on inverse print mode.
await printer.inverseOn();
inverseOff()
Turn off inverse print mode.
await printer.inverseOff();
upsideDownOn()
Turn on upside down print mode.
await printer.upsideDownOn();
upsideDownOff()
Turn off upside down print mode.
await printer.upsideDownOff();
doubleHeightOn()
Turn on double height print mode.
await printer.doubleHeightOn();
doubleHeightOff()
Turn off double height print mode.
await printer.doubleHeightOff();
doubleWidthOn()
Turn on double width print mode.
await printer.doubleWidthOn();
doubleWidthOff()
Turn off double width print mode.
await printer.doubleWidthOff();
strikeOn()
Turn on strike print mode.
await printer.strikeOn();
strikeOff()
Turn off strike print mode.
await printer.strikeOff();
boldOn()
Turn on bold print mode.
await printer.boldOn();
boldOff()
Turn off bold print mode.
await printer.boldOff();
justify(value: 'C' | 'L' | 'R' = 'L')
Justifies the content.
await printer.justify('C');
feed(lines = 1)
Feeds lines of paper.
z.number().int().min(1).parse(lines);
await printer.feed(2);
feedRows(rows = 1)
Feeds rows of paper.
z.number().int().min(1).parse(rows);
await printer.feedRows(2);
flush()
Flush the printer.
await printer.flush(2);
setSize(value: 'L' | 'M' | 'S' = 'S')
Set the text size.
await printer.setSize('L');
setPrintDensity(density = 10, breakTime = 2)
Sets the printer density.
z.number().int().nonnegative().max(31).parse(density);
z.number().int().nonnegative().max(7).parse(breakTime);
await printer.setPrintDensity(11, 3);
underlineOn()
Turn on underline.
await printer.underlineOn();
underlineOff()
Turn off underline.
await printer.underlineOff();
printBitmap(width: number, height: number, bitmap: Uint8Array)
:warning: WIP
Prints a bitmap.
z.number().int().nonnegative().max(384).parse(width);
z.number().int().min(1).parse(height);
await printer.printBitmap(2, 2, new Uint8Array([0, 255, 255, 0]));
offline()
Take the printer offline. Print commands sent after this will be ignored until online
is called.
await printer.offline();
online()
Take the printer online.
await printer.online();
sleep()
Put the printer into a low-energy state immediately.
await printer.sleep();
sleepAfter(seconds: number)
Put the printer into a low-energy state after the given number of seconds.
z.number().int().min(1).parse(seconds);
await printer.sleepAfter(1);
wake()
Wake the printer from a low-energy state.
await printer.wake();
setMaxChunkHeight(value = 256)
Set maximum chunk height for bitmap printing.
z.number().int().min(1).parse(value);
printer.setMaxChunkHeight(200);
setCharset(value = 0)
Set maximum chunk height for bitmap printing. May only work in recent firmware.
z.number().int().nonnegative().max(15).parse(value);
printer.setCharset(10);
setCodePage(value = 0)
Select alternate characters for upper ASCII. May only work in recent firmware.
z.number().int().nonnegative().max(47).parse(value);
await printer.setCodePage(12);
tab()
Print a tab. May only work in recent firmware.
await printer.tab();
setFont(font: 'A' | 'B' = 'A')
Sets font type. May only work in recent firmware.
await printer.setFont('B');
setCharSpacing(spacing = 0)
Set character spacing. May only work in recent firmware.
z.number().int().nonnegative().parse(spacing);
await printer.setCharSpacing(10);
You can enable the debugging logger when you provide a logger to the constructor.
const printer = new Thermaltastic(adapter, {
logger: console,
});
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
git checkout -b feature/AmazingFeature
)git commit -m 'Add some AmazingFeature'
)git push origin feature/AmazingFeature
)Luis Beu - me@luisbeu.de
2023-07-10 - 0.1.0
@beuluis/thermal-mqttastic
to @beuluis/thermaltastic
FAQs
Control a Adafruit thermal printer over different adapters
The npm package @beuluis/thermaltastic receives a total of 0 weekly downloads. As such, @beuluis/thermaltastic popularity was classified as not popular.
We found that @beuluis/thermaltastic demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.