Blog

cups-lpd - A way to generate PDF documents with older equipment

What I mean by this title is, that my Tektronix TDS3012B oscilloscope (With floppy drive and Ethernet) is now able to produce nice PDF documents. Before you had to use the floppy drive to get the pictures out of the oscilloscope.

I'm sure that this description is helpful for other people with older equipment or legacy software. The requirement is, that the equipment has a network interface and can somehow print to a standard Unix printer (LPD).

The central program in this setup is called cups-lpd. This program acts as a LPD server and forwards the print-jobs as CUPS client to the already running CUPS server.

This guide is divided into three parts, the common stuff, then the integration into the boot process on your computer (which is different for Sys-V/init and systemd) and then the configuration of the oscilloscope as an example use case.

Install and create the common stuff

I assume here that you already have a working CUPS printing server on your computer, that a virtual PDF printer exist and that the printer is named PDF (To install a CUPS-PDF printer you can follow this how-to).

We use a shell script here to pass additional options to cups-lpd and to do some post-processing on the PDFs (just copy and rename in this case). The CUPS-PDF back-end has also a mechanism to achieve this, but I wanted to limit the post-processing only to LPD print-jobs.

1. Create the destination folder and adjust the access rights (The cups server is running as user lp on debian. Change this if your distribution handle this differently):

sudo mkdir /var/spool/PDF
sudo chown lp /var/spool/PDF && chmod 777 /var/spool/PDF

2. Copy the following shell script (cups-lpd.sh) to the path /usr/local/bin and make it executable:

sudo cp <path to your file>cups-lpd.sh /usr/local/bin/
sudo chmod +x /usr/local/bin/cups-lpd.sh
cups-lpd.sh
#! /bin/sh

# Receive the print data and let it forward it to the PDF printer:
/usr/lib/cups/daemon/cups-lpd -o job-sheets=none,none -o document-format=application/octet-stream

cupspdffolder=/var/spool/cups-pdf/ANONYMOUS
outputfolder=/var/spool/PDF


# Wait until the print-job is finished and do some post-processing
logger -s "Wait until cups-lpd is finished"
while pgrep --exact cups-lpd >/dev/null 2>&1
do
     sleep 5
done 

sleep 5

logger -s "Cups-lpd finished, copy file to destination folder"

newfiles=$(find $cupspdffolder -atime -1 -type f)

for f in $newfiles 
do
	destname=$(basename $f .pdf)-$(date +%H-%M-%S_%d-%m-%Y).pdf
	/bin/cp $f $outputfolder/$destname
        /bin/chmod 666 $outputfolder/$destname
done

Configure inetd to start cups-lpd (Traditional init/Sys-V boot style)

If your system is using the traditional boot process using init and rc scripts. If you are unsure you can check it by running the following command. It will tell you the name of the program with the PID 0:

ps -p 1 -o "comm="

If it is init then follow with this part, if it is systemd use the description in the next chapter.

The program cups-lpd will be started only when it is needed. This is done by inetd, an internet super-server (sometimes xined is used). To enable our script you have to add this line to the file /etc/inetd.conf:

printer                stream tcp      nowait lp	/usr/local/bin/cups-lpd.sh cups-lpd.sh

If there is no such configuration file, it is highly possible that you first have to install inetd with the help of your package management.

After that, restart the inetd server:

sudo /etc/init.d/inetd restart

Now it's time to configure your older equipment or legacy software and test the cups-lpd setup.

Configure systemd to start cups-lpd (New Linux boot system)

Newer Linux installations use systemd to manage the boot process and a lot of other things. Systemd replaces the traditional System-V init system and the init scripts (anything that was in /etc/rc*.d/ and /etc/init.d/). If you are unsure you can check it by running the following command. It will tell you the name of the program with the PID 0:

ps -p 1 -o "comm="

If it is systemd then follow with this part, if it is init use the description in the chapter above.

With systemd there is no need for an additional internet super-server like inetd, systemd can handle that directly! Here is a detailed description: Socket unit configuration

In our case we have to create two files: cups-lpd.socket and cups-lpd@.service (ListenStream means a TCP socket and 515 is the TCP port used by LPD):

cups-lpd.socket
[Unit]
Description=cups-lpd - receive print jobs and report printer status to lpd clients 

[Socket]
ListenStream=515
BindIPv6Only=both
Accept=true

[Install]
WantedBy=sockets.target
cups-lpd@.service
[Unit]
Description=cups-lpd - receive print jobs and report printer status to lpd clients 
After=network.target

[Service]
User=lp
ExecStart=/usr/local/bin/cups-lpd.sh
StandardInput=socket

1. Copy this two files to the path /etc/systemd/system/:

cd <path to your files>
sudo cp cups-lpd.socket cups-lpd@.service /etc/systemd/system/

2. Activate this service so that it is started during boot (Like “Add to runlevel” in the older days). For this you have to enable it:

sudo systemctl enable cups-lpd.socket

3. To start it right away to test your setup, type this:

sudo systemctl start cups-lpd.socket

Or if something went wrong or you changed your configuration file you can also restart your new systemd service:

sudo systemctl restart cups-lpd.socket

Now it's time to configure your older equipment or legacy software and test the cups-lpd setup.

Configure a Textronix TDS30**B

I own a TDS3012B but this description should be true for the whole series (TDS3054B, TDS3014B and so on).

1. Go to the menu: UtilitySystem I/OEthernet Printer Settings
Ethernet printer settings with configured network printer

2. Press Add Printer and enter the needed information. Printer Name is essential, it is the name of the desired printer from the CUPS server! (My virtual PDF printer is named PDF)
Add your CUPS PDF printer to your device

3. Go to the menu: UtilitySystem Hard Copy Select as hard copy format EPS Color and for port Ethernet
Configure the desired behaviour of the //Print// button

Links:
Description of the line printer daemon (LPD) protocol
Manual page for the cups-lpd deamon
Details about systemd socket configuration files for network sockets or file system FIFOs controlled and supervised by systemd

2015/07/29 21:37 · dogbert

Unbekannte infrarot Codes ausmessen

Es gibt ja diverse Geräte die eine Fernbedienung haben die mit infrarotem Licht funktionieren. Am bekanntesten wohl das Fernsehgerät aber auch Klimaanlagen oder Modellhelikopter.

Wenn man diese Geräte selber ansteuern möchte oder ein Geräte baut das von einer schon vorhandenen Fernbedienung gesteuert werden soll, muss man herausfinden was die Fernbedienung genau aussendet. Das fängt an bei der Modulationsfrequenz, da normalerweise eine Amplitudenmodulation verwendet wird um unempfindlich gegenüber Störquellen (Sonnenlicht etc.) zu sein.

Was man machen kann, ist die Fernbedienung zu öffnen und an den Anschlüssen der Sende-LED ein Oszilloskop an zu hängen, was aber etwas unschön ist (Meistens geht ein Teil der Gehäuseverriegelung kaputt beim öffnen…). Besser wäre es aussen direkt das infrarote Licht zu messen.

Das geht erstaunlich einfach, ich brauchte nur etwas lange um eine passende Anleitung zu finden. Darum verlinke ich sie hier auch, in der Hoffnung das nun andere schneller finden :-)

‘Silver bullet’ – the Oscilloscope Infrared Receiver

Im wesentlichen braucht man einfach eine Infrarot-Diode, wie sie zum Senden benutzt wird, mit der passenden Wellenlänge und einen 22 kΩ Widerstand parallel dazu. Die Infrarot-Diode funktioniert hier wie z. B. eine Solarzelle, wandelt also das eintreffende Licht in elektrische Energie um. Um anständige Messungen zu haben muss ich bei meiner Infrarot-Diode das Oszilloskop auf 200 mV/div einstellen.

Meine Version des InfrarotempfängersBeispielmessung eines unbekannten Codes einer Infrarot-Fernbedienung

2015/07/20 22:51 · dogbert
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International