Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

brscankeyd

A small daemon that makes the Scan key on networked Brother multi-function printers/scanners work on Linux. It registers your PC with the scanner over SNMP; when you press Scan → Scan to File / Image / OCR / E-mail on the device and pick a menu entry, the scanner notifies the PC and the daemon runs the script you configured for that entry (e.g. scan to a multi-page PDF or a JPG).

This is a modernised version of Frank Abelbeck's original brotherscankeyd:

  • No third-party Python modules. The old net-snmp (snmpset) and linuxfd dependencies are gone — the SNMP request is built with the standard library, and timers/signals use epoll timeouts and signal.set_wakeup_fd.
  • Runs straight from this directory — it finds its own .ini and .sh files without a system-wide install.
  • Single-instance lock, Ctrl+C to stop, scan folder configurable in the ini, and the bundled example scripts produce a multi-page PDF and a JPG.

Requirements

  • Python 3 (3.4+). No extra Python packages.
  • sane-backends — provides scanimage and the scanner backend.
    • For Brother network scanning, install Brother's brscan4 driver and register the scanner (see below). Many Brother models also work via sane-airscan (eSCL/WSD), but the bundled scripts use Brother-style option names, so brscan4 is recommended.
  • ImageMagick (convert) — used by both scan scripts.
  • pdftk — used by scan2pdf.sh only (for the odd/even merge feature).
  • xdg-user-dir (usually preinstalled) — used to locate your Pictures folder; optional, there is a ~/Pictures fallback.

On Debian/Ubuntu/Zorin:

sudo apt install sane-utils imagemagick pdftk
# brscan4: download the .deb from Brother's support site and install it, then:

Installation

1. Register the scanner with the brother4 backend

scan2pdf.sh/scan2image.sh talk to the scanner through SANE. After installing brscan4, register your device (one-time, needs root):

sudo brsaneconfig4 -a name=MyScanner model=MFC-1910W ip=192.168.1.31
  • model= must match a brscan4-supported model exactly.
  • ip= is your scanner's address.

Verify it is found — you should see a brother4: device:

scanimage -L
# device `brother4:net1;dev0' is a Brother MFC-1910W ...

The brother4:net1;dev0 string is what goes in the ini's dev = field.

2. Configure the daemon

Edit brscankeyd.ini (see Configuration below). The daemon looks for its config in this order:

  1. the file given with --config,
  2. /etc/brscankeyd.ini,
  3. brscankeyd.ini next to brscankeyd.py (i.e. this directory).

Script paths in the ini may be absolute or relative to the daemon's directory (so the bundled scan2pdf.sh / scan2image.sh work as-is).


Usage

Run it from this directory:

./brscankeyd.py --verbose start     # run in the foreground (Ctrl+C to stop)
./brscankeyd.py start               # same, but quiet (INFO level)
./brscankeyd.py stop                # stop a running instance (sends SIGTERM)
./brscankeyd.py daemon              # detach and run in the background
./brscankeyd.py config              # print help on the ini format
./brscankeyd.py license             # show license information

Options: --config CFG, --address HOST, --port PORT (default 54925), --syslog, --verbose.

Once started, press Scan on the device, choose Scan to File (or Image), and select an entry — a file appears in your scan folder. With multiple pages the scanner asks "scan another page?"; all pages are merged into one PDF.

Only one instance can run at a time (guarded by an exclusive file lock); a second start exits with "another brscankeyd process is already running".

Run automatically with systemd (user service)

A unit is bundled as brscankeyd.service. Symlink it into your user units and enable it:

mkdir -p ~/.config/systemd/user
ln -s "$PWD/brscankeyd.service" ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now brscankeyd.service

Alternatively, let systemd create the symlink for you with link (give it the absolute path to the unit in this folder):

systemctl --user link "$PWD/brscankeyd.service"
systemctl --user enable --now brscankeyd.service

Manage / inspect it:

systemctl --user status brscankeyd
systemctl --user restart brscankeyd        # after editing the ini
journalctl --user -u brscankeyd -f          # live logs
systemctl --user disable --now brscankeyd   # turn it off

Notes:

  • The service runs as you, so scans land in your home folder and it stops at logout. To keep it running while logged out: loginctl enable-linger $USER.
  • ExecStart uses an absolute path — update it (and daemon-reload) if you move this folder.
  • Don't run the service and a manual ./brscankeyd.py start at once; the second is refused by the single-instance lock.

Configuration

brscankeyd.ini is an INI-style file.

[General] (optional)

[General]
first cycle = 3          ; seconds before the first SNMP registration
cycle       = 300        ; seconds between registration refreshes
buffer size = 4096       ; UDP read buffer size
hostname    = 192.168.1.111   ; this PC's IP the scanner should notify
                              ; (omit to auto-detect)
port        = 54925      ; UDP port the scanner notifies (Brother default)
scan dir    = ~/Afbeeldingen/Scans   ; where scans are saved (see below)

scan dir is optional. If set, the daemon exports it to the scan scripts as the SCANDIR environment variable. If unset, the scripts default to a Scans folder inside your XDG Pictures directory (e.g. ~/Afbeeldingen/Scans), falling back to ~/Pictures/Scans.

Device section

One section per scanner (any name that is not General and not a menu section):

[MFC-1910W]
ip  = 192.168.1.31
dev = brother4:net1;dev0     ; the SANE device from `scanimage -L`

Menu entries

Sections ending in FILE, IMAGE, OCR or EMAIL define the entries shown under the scanner's matching Scan to … menu. Each line is Entry name = /path/to/script [args…]. The daemon calls the script with the device's dev value as the first argument, followed by any args you list.

Prefix with DeviceName : to scope entries to one device; without a prefix the entries apply to every device.

[MFC-1910W : FILE]
PDF = scan2pdf.sh

[ MFC-1910W : IMAGE]
JPG = scan2image.sh 600     ; passed to the script as the resolution

(Leading/trailing spaces around section and entry names are ignored.)


The bundled scan scripts

Both write into $SCANDIR (created automatically) with a dated, auto-numbered filename, and accept the SANE device address as $1.

Script Output Notes
scan2pdf.sh multi-page PDF Uses scanimage --batch (ADF or glass). Source defaults to the ADF; override with SCANSOURCE=FlatBed. The optional odd/even/reversed args support manual double-sided scanning. Needs convert + pdftk.
scan2image.sh JPG Flatbed, color, quality 92. Optional 2nd arg = resolution (default 300 dpi). Needs convert.

Useful environment variables (set in the ini via scan dir, exported manually, or via Environment= in the systemd unit):

  • SCANDIR — output directory.
  • SCANSOURCE — scan source for scan2pdf.sh (e.g. FlatBed or Automatic Document Feeder(left aligned)).

You can point menu entries at your own scripts too — they just receive the device address as $1 plus whatever extra arguments you configure.


Credits

This is a modernised fork of brotherscankeyd by Frank Abelbeck frank.abelbeck@googlemail.com, originally released in 2016.

Frank stopped developing the original on 2020-12-07 and pointed users to its successor, brotherscankeyd2. All credit for the design and the original implementation goes to him; this fork only removes the third-party dependencies (net-snmp/linuxfd) and adapts the daemon to run from a local directory under systemd.

Changelog

2016-07-05: initial release as "works for me" version (except for the scan
            scripts scan2image.sh and scan2pdf.sh; they are still untested)
2016-07-10: switched to a unified output system (Python module logging and
            custom ConsoleHandler for coloured output); moved CONFIGFILE and
            PIDFILE to standard locations /etc and /var/run respectively
            (program tries both paths); scan2* scripts revisited, now seem to
            work; various bug fixes
2016-07-17: debugged program after first server trials; removed SEVERE scan
            script quoting errors, altered script calling procedure, introduced
            OpenRC init script
2016-07-25: moved SNMP requests into subprocess to avoid blocking the main loop
2016-08-06: fixed a script calling race condition (scanner not immediately ready
            for connects of scanimage/scanadt after issuing a notification) by
            introducing a two second delay
2017-06-24: removed pysnmp dependencies; SNMP requests are now sent with
            /usr/bin/snmpset (http://net-snmp.sourceforge.net/).
2017-07-02: fixed process management: replaced proc.kill() with proc.terminate()
2026-06-10: removed the net-snmp and linuxfd dependencies. SNMP SET requests are
            now encoded (BER/ASN.1) and sent over UDP with the standard library;
            periodic SNMP refresh is driven by epoll timeouts instead of
            linuxfd.timerfd; SIGTERM/SIGINT are caught via signal.set_wakeup_fd
            and a socketpair instead of linuxfd.signalfd.

License

GPLv3. Original program © 2016 Frank Abelbeck. See the COPYING file and run ./brscankeyd.py license.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages