How to use a Radeon graphics card on Debian 9

I have previously blogged about Radeon graphics cards on different Debian installs.

ATI has now released a new free driver which works brilliantly on Debian. In the past, Debian users had to choose between using the community-provided free software driver, or the proprietary one. Generally the proprietary driver was more feature-rich, but the free driver worked more reliably across upgrades. So now, you can safely ignore old guides and start using it.

Here’s how:

Upgrade

Make sure you are on Debian 9 (Stretch) or newer.

These steps apply to a fresh install.

Identify

You should use lspci to confirm that you have an ATI card.

$ lspci | grep Radeon
01:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Tahiti XT [Radeon HD 7970/8970 OEM / R9 280X]

Install firmware

You need to install a package called firmware-linux-free to get the driver working at all. If you want decent graphics performance, you will need firmware-linux-nonfree as well, which involves adding non-free sources:

nano /etc/apt/sources.list

Add the words “contrib non-free” to the end of your mirror:

deb http://.../debian/debian/ stretch main contrib non-free

Add the packages:

apt-get update
apt-get install firmware-linux-free firmware-linux-nonfree

And reboot:

reboot

What, that’s it?

Well, yes, for a fresh install that’s it. If your install is old, you might also have to remove old drivers or install the xserver-xorg-video-amdgpu and xserver-xorg-video-ati packages (in my case, these were already installed).

The Debian Wiki AtiHowto contains some more detailed information, most of which is not relevant for a simple desktop setup.

How to assemble a Linux software RAID array on a different computer

With Linux software RAID, if you ever toast your computer, you can retrieve the disks and open up the array on a different computer.

They appear as “Linux Software RAID Member” in the disk utility.

Simply install mdadm, and scan for arrays:

$ sudo apt-get install mdadm
$ sudo mdadm --assemble --scan
mdadm: /dev/md/0 has been started with 2 drives.

The array will then appear as a new disk, which can be formatted, mounted, or cloned via the usual tools.

Crowd-sourced POS printer compatibility site is online

 

Point-of-sale (POS) printers are all different, so the implementation of the more advanced ESC/POS  features varies considerably between vendors and models.

Some months ago I extracted compatibility information out of the escpos-php library, so that it could be used by the python-escpos team as well. We’re still in the early stages, but both of these projects now have similar compatibility features.

You can the new shared database on GitHub as receipt-print-hq/escpos-printer-db, and I’m beginning to add it to some printing projects that need it.

Today I’m blogging a few screen captures from the new web viewer for this database that has come out today, hosted here (source code here).

escpos-printer-db landing page

escpos-printer-db landing page

Character encodings

escpos-printer-db character encoding list

escpos-printer-db character encoding list

escpos-printer-db character encoding detail

escpos-printer-db character encoding detail

Vendors

escpos-printer-db vendor list

escpos-printer-db vendor list

escpos-printer-db vendor detail

escpos-printer-db vendor detail

Printer profiles

escpos-printer-db printer profile list

escpos-printer-db printer profile list

escpos-printer-db printer profile detail

escpos-printer-db printer profile detail

Tech used

I’ve used materialize.css with backbone.js and jQuery. This is the first time I’ve attempted using materialize – I’m normally a bootstrap.css user.

The back-end data is generated with Python, but the actual site is served as a single-page application, with static JSON files hosting the data.

escpos-php 1.6 released

Another update to the open source receipt printing library escpos-php has been released today. For composer users, it is available as mike42/escpos-php

This is expected to be the final release in the 1.x series. Newer versions will drop support for some end-of-life PHP versions.

The v1.6 release notes detail the changes and lists 13 additional printers tested out by the user base.

Please direct any bug reports to the issue tracker on GitHub. The escpos-php tag on this blog has some tips and examples.

I’ll also call out some related projects that I’ve been involved with, which you should consider contributing to if you are working with thermal receipt printers:

  • escpos-printer-db – Crowd-sourced database of printer features. Add your printer for better support in open source drivers!
  • escpos-tools – Tools to work with ESC/POS binary, including text or image extraction, HTML conversion.
  • chrome-raw-print – A browser plugin to access local printers from a web-page.

mdcheckr: Practical testing for Markdown files

If you are a continuous integration enthusiast, you might be annoyed by preventable errors in project documentation.

I recently found a broken link in one project’s documentation, and a syntax error in an example on another project. I quickly wrote up a simple tool to detect this type of issue, solving the problem for me.

$ mdcheckr README.md
Checking README.md ..
- Code block starting line 21 (language: bash) [ OK ]
- Link https://travis-ci.org/receipt-print-hq/escpos-tools [ OK ]
- Link https://getcomposer.org/ [ OK ]
- Link doc/esc2text.md [ OK ]
- Link doc/esc2html.md [ OK ]
- Link doc/escimages.md [ OK ]
- Link CONTRIBUTING.md [ OK ]
- Link LICENSE.md [ OK ]
- Image https://travis-ci.org/receipt-print-hq/escpos-tools.svg?branch=master [ OK ]

I disregarded some existing “linter” tools. I don’t believe that it is necessarily productive for small projects to enforce a style-based quality gate for Markdown, but you may be able to configure these tools to be less pedantic. My goal here was to simply churn out a script which could reject objectively broken Markdown files.

I’ve posted this project to GitHub as mdcheckr. It is available as a package for Debian, Ubuntu, and RHEL/CentOS. Travis CI users may be interested to check out this pull request, where mdcheckr is added to the project’s build.

How to access a raw network printer as a file on Linux

I got this interesting question on my blog post ‘Setting up an Epson receipt printer‘:

Wondering if you had an idea on how to map a linux device to the netcat command so that I could “convert” the printer to be a local one? -Marco

I have previously written about the opposite use case: How to use a Raspberry Pi as a print server, where I used netcat to pass data to a local USB printer.

The setup

In this setup, I will assume that you have a working Ethernet printer, which accepts raw data on port 9100.

diagram

The aim is to make this appear as a file, so that you can print to it as if it were a local USB printer:

diagram2

Before you begin

Make sure you have netcat. It’s not used for the real setup, but you will need it for testing. There are a few versions of this tool around, the one used here is:

apt-get install netcat

Verify that your printer accepts text on port 9100 via netcat:

echo "Hello world" | nc -q 1 192.168.x.y 9100

Set up a fake printer on localhost, and leave it running:

nc -klp 9100

Now, test that your fake printer shows output when you send it:

echo "Hello world" | nc -q 1 127.0.0.1 9100

Why I’m not using..

/dev/tcp

If you search for how to redirect data to a TCP socket, a common suggestion is:

echo "Hello world" > /dev/tcp/127.0.0.1/9100

This is a bash built-in, so unless your use case involves printing from bash, read on.

CUPS

CUPS does not expose the printer as a file, which is the aim here. It also takes a few seconds to print, so we get much faster results if we remove CUPS from the loop and speak to the printer directly.

Use socat to move data

Socat is capable of making a FIFO file (‘pipe’), and writing this out over the network.

apt-get install socat

Redirect /tmp/my-printer to localhost:9100:

socat PIPE:/tmp/my-printer TCP:localhost:9100

Next, test that you can see the printer file and write to it. This line should appear on your local netcat “fake printer”:

echo "Hello world" > /tmp/my-printer

This file is a “pipe”, so it behaves very similarly to a character device.

If the connection is dropped, socat will exit, and the file will be deleted.

There are some big problems though:

  • If your printer is offline, and you try to print, you will create a regular file at “/tmp/my-printer”, breaking it.
  • This is not a self-restarting service, nor does it start on boot
  • Only the user who runs the command can print

Setting this up as a proper service

The usblp driver allows anybody from the lp group to print, so we will try to do something similar, and get a group-writable pipe:

$ ls /dev/usb/lp0  -Ahl
crw-rw---- 1 root lp 180, 0 Jun 12 12:51 /dev/usb/lp0

We don’t need to run socat as root, so make a new user called fileprint who is in the lp group.

useradd --groups lp fileprint

Add yourself to the lp group as well:

usermod -a -G lp mike

Next, write this systemd service file to /etc/systemd/system/fileprint.service

[Unit]
Description=fileprint
After=network.target

[Service]
User=fileprint
Group=lp
ExecStartPre=/usr/bin/mkfifo -m '0664' /var/run/fileprint/printer
ExecStart=/usr/bin/socat PIPE:/var/run/fileprint/printer TCP:127.0.0.1:9100
Restart=always
RuntimeDirectory=fileprint

What’s going on here?

  • Runs as user fileprint and group lp
  • Manages a runtime directory at /var/run/fileprint
  • Creates a pipe that is group-writeable at /var/run/fileprint/printer
  • Forwards traffic to 127.0.0.1:9100
  • Re-starts automatically

Load and start the service:

systemctl daemon-reload
systemctl start fileprint
systemctl status fileprint

Test out printing to your local netcat “fake printer”:

echo "Test" > /var/run/fileprint/printer

Note that if you are not in the lp group (check with groups command), you should expect a permission error here — just the same as usblp.

Next, replace 127.0.0.1 with your real printer IP, reload systemd, and restart the service:

nano /etc/systemd/system/fileprint.service
systemctl daemon-reload
systemctl restart fileprint
systemctl status fileprint

Test it again, and your actual printer should print a line of text this time:

echo "Test" > /var/run/fileprint/printer

Finally, enable on boot:

systemctl enable fileprint

When the printer is unplugged, the /var/run/fileprint directory will vanish, so that you can see the missing printer as a “File Not Found” error — just the same as usblp.

Drawbacks

This will hold a connection open at all times, which (depending on your printer) may prevent other computers from using it.

The 5890 printer does not support barcodes

I haven’t been able to print barcodes on the 5890 model thermal receipt printer, and it looks like other developers can’t either.

The same printer is sold under a few names. As far as I can tell (mainly from bug reports to escpos-php), these are all the same printer, and could have this issue:

  • AGPtEK SC35-5890F
  • EC Line 5890
  • Gainscha GP-5890
  • HSPOS HS-589C
  • POS-5890
  • WinBond 5890
  • Zjiang ZJ-5890 or POS-5890

In my case, I have a Zjiang POS-5890C, which list the barcode command GS k in its documentation, but does not actually respond to the command.

Separately, a developer has contacted their vendor and confirmed that this is an error in the documentation.

A few bookmarks for reference:

How to test for barcode support in USB printers

Get yourself a Linux computer or VM, set up the printer with usblp, and run this command:

echo -e '\x1d\x6b\x04000\x00' > /dev/usb/lp0

This command prints a CODE39 barcode containing ‘000’ on printers which support barcodes, and prints garbage on printers which do not.

See also:

libgdx 3D particle effects in HTML

2017-03-flame

It is not immediately obvious in libgdx why the 3D particle effects don’t work in a HTML target. I’m sharing this snippet for future readers.

In short, the “reflection cache” that is created from the Java code does not include everything required, since many of the classes are only referenced at runtime, when the particle definition is loaded.

These class names are visible in the saved files from the 3D effects editor:

$ cat engine.p | fold -w 80
{unique:{billboardBatch:{class:com.badlogic.gdx.graphics.g3d.particles.ResourceD
ata$SaveData,data:{cfg:{class:com.badlogic.gdx.graphics.g3d.particles.batches.Bi
llboardParticleBatch$Config,mode:Screen}},indices:[0]}},data:[],assets:[{filenam
e:"pre_particle.png",type:com.badlogic.gdx.graphics.Texture}],resource:{class:co
....

At runtime, this message is displayed on the web page:

GwtApplication: exception: com.badlogic.gdx.utils.GdxRuntimeException: Could not submit AsyncTask: Error reading file: (filename)
com.badlogic.gdx.utils.GdxRuntimeException: Could not submit AsyncTask: Error reading file: (filename)
Could not submit AsyncTask: Error reading file: (filename)
Error reading file: (filename)
Couldn't find Type for class 'com.badlogic.gdx.graphics.g3d.particles.batches.BillboardParticleBatch$Config'

The reflection is documented on the libgdx Wiki here, and notes that-

  • *.gwt.xml files store this data
  • dependencies defined in the Java are loaded automatically
  • inner classes are also loaded automatically, no need to add them separately

With this in mind, I added the following two lines to the root element in a file called GdxDefinition.gwt.xml

<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.graphics.g3d.particles.batches.BillboardParticleBatch" />
<extend-configuration-property name="gdx.reflect.include" value="com.badlogic.gdx.graphics.g3d.particles.ParticleShader" />

This did the trick, and the 3D particle feature does indeed work in the libgdx HTML target.

How to add a proper Android Studio launcher on Linux

If you install Android Studio by extracting a Zip file on Linux, it will come without any launch icon. This post assumes that have extracted the install archive to /usr/local and run any recent version of Linux which has Gnome:

unzip android-studio-ide-145.3537/39-linux.zip -d /usr/local

Simply write the following text to ~/.local/share/applications/android-studio.desktop (change paths if your install location differs).

[Desktop Entry]
Comment=Android Studio
Terminal=false
Name=Android Studio
Exec=/usr/local/android-studio/bin/studio.sh
Type=Application
Icon=/usr/local/android-studio/bin/studio.png

Once you save the file, it will appear in your local applications like this:

2016-04-android-studio-icon

This can also be added graphically though the Alacarte menu editor if you have it installed.