Create a scan station with scanbd (Raspbian)
Introduction and installation
The purpose of this documentation is to use a scanner without any user interface. A common use is to upload a PDF scanned file directly to Google Drive or Dropbox just by pressing scanner-buttons.
scanbd permits to trigger actions from the scanner buttons, it uses sane.
What make things a little bit trickier is that by polling the scanner, scanbd locks the device. As we also need to scan from local tools (like scanimage), we need to set a proxy that’s going to interrupt scandb from polling when needed. This is the job of scanbm, which monitors the network and give priority over scanbd to any local access to the scanner.
Thus, we need to :
- Set up the local sane configuration to only scan from the network (through scanbm)
- Configure scanbd to have access and poll the local scanner
As root:
apt-get update
apt-get install libconfuse-dev libsane-dev libudev-dev libusb-dev xinetd
The latest version of scanbd can be find here : https://sourceforge.net/projects/scanbd/files/releases/
# Download the latest version of **scanbd**.
wget https://sourceforge.net/projects/scanbd/files/releases/scanbd-1.4.4.tgz/download
# Uncompress
tar xvzf scanbd-1.4.4.tgz && cd 1.4.4
# Configure with the installation path in /etc/
./configure --disable-Werror
# install it
make
make install
# Add a dbus policy to authorize "saned" user to manage scanbd :
cp integration/scanbd_dbus.conf /etc/dbus-1/system.d/
# Add the init script to manage the daemon :
cp integration/scanbd.debian /etc/init.d/scanbd
scanbd is now installed but not yet configured.
Configure sane to scan from the network
The local configuration of sane is inside /etc/saned.d
/etc/sane.d/dll.conf
# /etc/sane.d/dll.conf - Configuration file for the SANE dynamic backend loader
#
# Backends can also be enabled by configuration snippets under
# /etc/sane.d/dll.d directory -- packages providing backends should drop
# a config file similar to dll.conf in this directory, named after the package.
#
# The next line enables the network backend; comment it out if you don't need
# to use a remote SANE scanner over the network - see sane-net(5) and saned(8)
net
dll.conf
contains only the net
backend.
/etc/sane.d/net.conf :
# This is the net backend config file.
## net backend options
# Timeout for the initial connection to saned. This will prevent the backend
# from blocking for several minutes trying to connect to an unresponsive
# saned host (network outage, host down, ...). Value in seconds.
connect_timeout = 3
## saned hosts
# Each line names a host to attach to.
# If you list "localhost" then your backends can be accessed either
# directly or through the net backend. Going through the net backend
# may be necessary to access devices that need special privileges.
localhost
At this point, scanbm is not yet configured, no scanner can be reached from the network. We need to set up scanbm along with scanbd to test the set up.
Configure scanbd to poll the local scanner
Identify the local scanner
By using lsusb, identify the productId (1909 here) :
pi:# lsusb
pi:# Bus 001 Device 005: ID 04a9:1909 Canon, Inc. CanoScan LiDE 110
With that productId, grep the correct configuration file (it depends of your scanner model, for me it is genesys.conf) :
pi:# grep 1909 /etc/sane.d/*conf
pi:# /etc/sane.d/genesys.conf:usb 0x04a9 0x1909
Copy the file inside your scanbd configuration folder:
cp /etc/sane.d/genesys.conf /usr/local/etc/scanbd/
cp /etc/sane.d/dll.conf /usr/local/etc/scanbd/
Edit /usr/local/etc/scanbd/dll.conf and replace net
with the correct scanner backend:
# /etc/sane.d/dll.conf - Configuration file for the SANE dynamic backend loader
#
# Backends can also be enabled by configuration snippets under
# /etc/sane.d/dll.d directory -- packages providing backends should drop
# a config file similar to dll.conf in this directory, named after the package.
#
# The next line enables the network backend; comment it out if you don't need
# to use a remote SANE scanner over the network - see sane-net(5) and saned(8)
genesys
Confirm that the local scanner is found by scanbd
Now we are ready to test :
scanbd -d7 -f
Avoid as much as you can to manipulate the env var SANE_CONFIG_DIR. It can break things, the default value is already configured in /usr/local/etc/scanbd/scanbd.conf and in the init script.
Output should be similar to :
scanbd: foreground
scanbd: reading config file /usr/local/etc/scanbd/scanbd.conf
scanbd: debug on: level: 7
scanbd: dropping privs to uid saned
scanbd: dropping privs to gid scanner
scanbd: group scanner has member:
scanbd: saned
scanbd: pi
scanbd: drop privileges to gid: 110
scanbd: Running as effective gid 110
scanbd: drop privileges to uid: 110
scanbd: Running as effective uid 110
scanbd: dbus_init
scanbd: dbus match type='signal',interface='org.freedesktop.Hal.Manager'
scanbd: SANE_CONFIG_DIR=/usr/local/etc/scanbd/sane.d
scanbd: sane version 1.0
scanbd: Scanning for local-only devices
scanbd: found device: genesys:libusb:001:005 Canon LiDE 110 flatbed scanner
The most important here isfound device
.
What if “found device” doesn’t appear ?
You should check again your configuration, especially the identification part of this documentation and clear any eventual SANE_CONFIG_DIR env var wrongly set by typing :
unset SANE_CONFIG_DIR
Configure xinetd to make scanbm listening on the network
Create /etc/xinetd.d/sane-port
which contains :
service sane-port
{
port = 6566
socket_type = stream
wait = no
user = saned
group = scanner
server = /usr/local/sbin/scanbm
server_args = scanbm -c /usr/local/etc/scanbd/scanbd.conf
disable = no
}
/!\ Double-check the path of scanbm with
which scanbm
Then, restart xinetd and start scanbd :
service xinetd restart
/etc/init.d/scanbd start
scanimage -L
should now display the scanner.
Most issues at this stage concern the permissions. Ensure that
scanimage -L
works when you are logged as saned by doingsudo -u saned -s
.If not, check USB permissions :
ls -al /dev/bus/usb/***
Trigger actions from the scanner buttons
Actions are located in /usr/local/etc/scanbd/scanbd.conf
.
I have 4 buttons that are scan, copy, email and file.
The default config file doesn’t include all actions per default, you will probably have to add the block manually. You can have less or more buttons depending of your scanner model.
For each action, we will set a custom path for the script option.
action scan {
filter = "^scan.*"
numerical-trigger {
from-value = 1
to-value = 0
}
desc = "Scan to file"
# script must be an relative path starting from scriptdir (see above),
# or an absolute pathname.
# It must contain the path to the action script without arguments
# Absolute path example: script = "/some/path/foo.script
script = "/home/pi/scan.sh"
}
Don’t forget to comment any other default action at the end of scanbd.conf :
# devices
# each device can have actions and functions, you can disable not relevant devices
#include(scanner.d/avision.conf)
#include(scanner.d/fujitsu.conf)
#include(scanner.d/hp.conf)
#include(scanner.d/pixma.conf)
#include(scanner.d/snapscan.conf)
#include(scanner.d/canon.conf)
You can now create your custom script to handle each action :
Each line relative to
/sys/class/leds/led0/trigger
are for controlling the LED to monitor what’s going on. You can do whatever you want,cat /sys/class/leds/led0/trigger
gives you all different pattern of lights.
/home/pi/scan.sh
#!/bin/bash
# don't forget to create the folder
scan_dir=/home/pi/scanned-files
datetime=`date +%F_%H%M%S`
echo none >/sys/class/leds/led0/trigger
case $SCANBD_ACTION in
scan)
filename=file-$datetime
logger -t "scanbd: $0" "$SCANBD_DEVICE $SCANBD_ACTION - scanning --resolution 150 --mode Color --depth 8 --format=tiff to $scan_dir/$filename.jpg"
echo timer >/sys/class/leds/led0/trigger
scanimage -d $SCANBD_DEVICE --resolution 150 --mode Color --depth 8 --format=tiff --brightness 5 --contrast 20 | convert tiff:- -compress jpeg $scan_dir/$filename.pdf
echo none >/sys/class/leds/led0/trigger
logger -t "scanbd: $0" "Finished scanning"
;;
email)
logger -t "scanbd: $0" "Emailing $scan_dir/file-*pdf"
echo heartbeat >/sys/class/leds/led0/trigger
# here are the lines to send the file
echo none >/sys/class/leds/led0/trigger
esac