udev-device-plug-handler: Handle Canon LiDE400

When this scanner is plugged in, we want to start `scanimage` in batch
mode with button support, scanning into a pre-defined directory. Since
plug and unplug might happen multiple times a day and batch mode
overwrites files with the same name, we use date and time to define
directory and filename.
MasterofJOKers 2 months ago
parent 0c2dd51ac1
commit 28901649dc

@ -1,5 +1,7 @@
#!/usr/bin/env python3
from datetime import datetime
import inspect
from pathlib import Path
import subprocess
from typing import Dict, List, Optional, Union
@ -96,6 +98,61 @@ class UsbLogitechG930(KnownDevice):
print("Handled Logitech G930 Headset")
class CanonLIDE400(KnownDevice):
"""Represents our 2023-bought Canon flatbed scanner"""
UDEV_PROPS = {'PRODUCT': '4a9/1912/100'}
__process = None
def check_available() -> bool:
cmd = "lsusb | grep 'LiDE 400'"
cp = subprocess.run(cmd, shell=True, stdout=subprocess.DEVNULL)
return cp.returncode == 0
def handle_bind(device: Optional[pyudev.Device] = None) -> None:
if CanonLIDE400.__process is not None:
# in theory, uplugging the Scanner should have terminated/killed the process, but if something went wrong,
# we just try to kill it and proceed
now = datetime.now()
directory = Path('/srv/paperless/later/scanned/') / now.strftime('%Y-%m-%d')
# directory = Path('/home/joker/tmp/scanned/') / now.strftime('%Y-%m-%d')
# TODO read config from ~/.config/udev-device-plug-handler/
# How should that look like? Directory list of arguments? Would be easiest and we just default to something.
# Could be nice to read the directory from there, too.
cmd = [
'-d', 'pixma:04A91912_4B9054',
'-l', '0mm',
'-t', '0mm',
'-x', '210mm',
'-y', '297mm',
'--resolution', '300dpi',
# '-p', # progress
CanonLIDE400.__process = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, cwd=directory)
print("Handled Canon LiDE 400")
def handle_remove(device: pyudev.Device) -> None:
if CanonLIDE400.__process is not None:
p = CanonLIDE400.__process
except subprocess.TimeoutExpired:
print("Handled Canon LiDE 400 unplug")
@click.option('--debug', is_flag=True, help='Show all device changes instead of only handled.')
def main(debug: bool) -> None: