abusenius / insaned Goto Github PK
View Code? Open in Web Editor NEWSimple daemon for polling button presses on SANE scanners
License: GNU General Public License v2.0
Simple daemon for polling button presses on SANE scanners
License: GNU General Public License v2.0
Hey Alex,
great project, thank you for your effort!
I'm useing a fujitsu:fi-5110Cdj:116473
and insaned works fine with 13 sensors including the "Scan" and "Send to" buttons. But there is an additional button named "Function". This button increases the number of a 1-digt 7-segment Display in front of the scanner. The displayed number seems to be used by the Windows frontend for change the behavior of the scanner. But the value of "Function" is a sane-sensor too:
$ scanimage -A
[...]
Sensors:
[...]
--function <int> [1] [hardware]
Function character on screen
--double-feed[=(yes|no)] [no] [hardware]
Double feed detected
--error-code <int> [0] [hardware]
Hardware error code
--skew-angle <int> [0] [hardware]
Requires black background for scanning
insaned only shows sensors that reports a boolean status (like --double-feed
above).
Do you see a possibility to make sensors accessible that reports an integer? In that case it will be possible to select a function (like scanning single- or doubleside, color, bw ) at the panel of the device before pressing the scan button.
Thank you, and
Gruß Bernd
Works great! Thanks for writing this up. I was thinking about doing the same sort of thing but using kevent instead of polling, have you given that idea any thought before?
Hi...
When no scanner is attached, there is a segfault happening here:
Line 61 in 5a74d85
Backtrace:
Thread 1 "insaned" received signal SIGSEGV, Segmentation fault.
0x00007ffff3d89d70 in std::_Function_handler<void (), genesys::StaticInit<std::vector<genesys::Genesys_USB_Device_Entry, std::allocator<genesys::Genesys_USB_Device_Entry> > >::init<>()::{lambda()#1}>::_M_invoke(std::_Any_data const&) () from /usr/lib/sane/libsane-genesys.so.1
(gdb) bt
#0 0x00007ffff3d89d70 in std::_Function_handler<void (), genesys::StaticInit<std::vector<genesys::Genesys_USB_Device_Entry, std::allocator<genesys::Genesys_USB_Device_Entry> > >::init<>()::{lambda()#1}>::_M_invoke(std::_Any_data const&) () from /usr/lib/sane/libsane-genesys.so.1
#1 0x00007ffff3d76645 in genesys::run_functions_at_backend_exit() () from /usr/lib/sane/libsane-genesys.so.1
#2 0x00007ffff3d03bb6 in genesys::sane_exit_impl() () from /usr/lib/sane/libsane-genesys.so.1
#3 0x00007ffff3d03bf7 in sane_genesys_exit () from /usr/lib/sane/libsane-genesys.so.1
#4 0x00007ffff7f9641e in sane_dll_exit () from /usr/lib/libsane.so.1
#5 0x000055555555a7a4 in InsaneDaemon::~InsaneDaemon (this=0x55555556a760 <InsaneDaemon::mInstance>, __in_chrg=<optimized out>) at src/InsaneDaemon.cpp:61
#6 0x00007ffff7ac8db7 in __run_exit_handlers () from /usr/lib/libc.so.6
#7 0x00007ffff7ac8f5e in exit () from /usr/lib/libc.so.6
#8 0x00007ffff7ab1159 in __libc_start_main () from /usr/lib/libc.so.6
#9 0x000055555555762e in _start ()
So I modified the function like this, no idea if this is correct though:
diff --git a/src/InsaneDaemon.cpp b/src/InsaneDaemon.cpp
index db8ff1c..41bbd71 100644
--- a/src/InsaneDaemon.cpp
+++ b/src/InsaneDaemon.cpp
@@ -53,18 +53,18 @@ InsaneDaemon::InsaneDaemon()
InsaneDaemon::~InsaneDaemon() noexcept
{
+ SANE_Handle mHandle2 = mHandle;
log("Exiting...", 1);
close();
try {
- mHandle = nullptr;
- log("Calling sane_exit", 1);
- sane_exit();
-
+ if (mHandle2) {
+ log("Calling sane_exit", 1);
+ sane_exit();
+ }
+ log("Finished", 1);
::close(0);
::close(1);
::close(2);
-
- log("Finished", 1);
} catch (...) {
log("Error calling sane_exit!", 0);
}
Thanks for this, it's very helpful. It works just fine on Debian 8 running on a CHIP with a Canon Lide 210.
Hello,
I installed insaned on Linux because I would like to use my Fujitsu S1500, that works fine, but unfortunately only "scan" works for me, I would like to have it duplex scanned when it notices that there is a backside and I would like it as PDF.
Can anyone help me there ?
I don't know how to program the button like this, because I have no experience in programming.
I am not sure what is causing is. It usually happens after I install some unrelated updates with apt get upgrade.
Basically, insaned freezes the scanning tools.
When I try to run scanimage -A or any other command like that, which accesses the scanner, that command will hang forever and never finish. Rebooting the computer doesn't help.
The only way to fix the problem is to remove and then reinstall the insaned with dpkg.
So far it happened twice.
I can't tell you how to duplicate this, because I am not sure what exactly triggers this problem, but I don't have anything unusual installed on the computer, just run of the mill software from official ubuntu repos.
kubuntu 16.04 64bit
scanimage -L
device `plustek:libusb:001:006' is a Canon CanoScan D660U flatbed scanner
scanimage -A attached. Scanner is recognized, but I can't see any "Sensors".
Pressing the scanner's button does not do anything.
Some time ago (years) I got it working with scanbuttond, but not anymore with anything.
I would be fine if I got the button to start vuescan, simple scan or what ever scanning software gui.
scanimage.txt
Hey Alex
I didn't know how to just leave you a nice comment so I had to create an issue.
I also fought with scanbd for 2 days before giving up and finding your project. Once I had found the latest sane backends and gcc compiler it was really easy to build, install and get working.
If you want to open the wiki I could add an article about installing on RPi for you.
The one thing I'm really missing at the moment is the ability to use the scanner via the buttons and via a networked PC. I can do one or the other but not both at the same time. phpSANE gives me a nice web interface from any PC but it cannot work if insaned is using libsane. If you could fix this the program would be perfect!
Best wishes from England
Gary
Hello,
I installed the .deb package on Ubuntu 16.04 64b and then rebooted the PC, but the insaned won't autostart. I looked into systemmd at insaned.serivce file, and an entry for it has been created there, so I am not sure why it isn't autostarting.
If I start the service manually as "sudo /usr/bin/insaned" then it works fine.
My scanner (Lide 210) has a button to scan a multi-page document: load the first page, press the button. When it's done, place the second page, press the button again, and so on until you run out of pages. At the end, each scan gets put back together in a multi-page PDF.
I'd like to reimplement this functionality using insaned
. The twist is that I'm running it headless, so the only interface to the system is through the scanner buttons.
I was thinking of saving the individual scans in a separate directory from the one used when pressing the file
button. Each page is scanned separately, and I'll write a daemon watching that directory. If no new file has been added there after a set timeout, it will collect all the files and assemble them in one multi-page PDF.
However, this isn't ideal because if I get interrupted scanning the pages it will create an incomplete PDF. I'm also handwaving the daemon part, but I'm not sure how to go about it just yet.
Did you ever think about this use case? Any idea how else that could be done?
Hey Alex,
I checked out a Canon "CanoScan LIDE 20" with insaned and it doesn't work together. I think it's because of the unusual name of the buttons that contains a space in their name:
$ insaned -L
List of sensors for device 'plustek:libusb:001:008':
button 0 [no]
button 1 [no]
button 2 [no]
If I press a button, I expected a syslog entry of a missing script handler but there is no one.
Do you see a possibility to support these unusual names to use the scanner together with insaned?
Thank you, and
Gruß Bernd
Hi,
Apologies for spamming-up your issue list, but just wanted to thank you for insaned!
I'm running FreeBSD and have just bought a Fujitsu ScanSnap S1500. I've been struggling with scanbuttond and scanbd. My experiences mirror yours: scanbuttond didn't see the scanner and scanbd was a royal pain to set up. Even once I'd got it running, it would freeze whenever I shut the lid on the scanner (which turns it off).
I've still got to set up my event scripts, but here's what I've got so far with insaned on FreeBSD 11.1:
I cloned the insaned repository and optimistically ran make
. No dice - FreeBSD keeps its non-base libs and headers under /usr/local/lib and /usr/local/include.
I edited the Makefile to set CXXFLAGS and LDFLAGS as appropriate and used the more GNU-y gmake
instead of just make
. Success!
I then ran insaned
and it immediately saw my scanner and reported button events. Upon closing the lid (and thus disconnecting the scanner), insaned spewed a stream of errors about not being able to access the device.
So, to solve that, I'm using FreeBSD's hardware manager, devd
to launch insaned when the scanner connects and to kill insaned
when it disconnects.
Just in case it'll help anyone else, here's my /usr/local/etc/devd/insaned.conf
file:
notify 1 {
match "subsystem" "DEVICE";
match "type" "ATTACH";
match "cdev" "ugen[0-9]+.[0-9]+";
match "vendor" "0x04c5";
match "product" "0x11a2";
action "chown -L cups:saned /dev/$cdev && chmod -L 660 /dev/$cdev";
action "/usr/local/bin/insaned -e /usr/local/etc/insaned/";
};
notify 1 {
match "subsystem" "DEVICE";
match "type" "DETACH";
match "vendor" "0x04c5";
match "product" "0x11a2";
action "/usr/bin/killall -9 insaned";
};
The vendor/product IDs will need to be adjusted for other makes and models of scanner. Also, the chown
line may need the user/group names changing for other people's systems. This line adjusts the permissions on the newly-created device file to allow non-root users to access the scanner.
Thanks again, and I hope this helps some others!
The environments file says:
# event handler scripts are executed with privileges of this user
INSANED_USER=andreas
INSANED_GROUP=andreas
but they are not.
I have set INSANED_USER and INSANED_GROUP as above and I have a dummy event handler "copy" in place and it only contains this for testing:
#!/bin/bash
echo "Running as $(whoami)" >/tmp/copy.log
When pressing the copy button at the scanner the log file contains:
Running as root
Shouldn't this be "andreas"? I looked through the code but it does not seem, that INSANED_USER or INSANED_GROUP is picked up anywhere.
System: Linux Mint 19 Cinnamon
I wanted to get more verbose logging from insaned and provided more v's to INSANED_EXTRAOPTS like this:
INSANED_EXTRAOPTS="--sleep-ms=1000 --suspend-after-event -vv"
So for every 'v' the verbosity level is incremented. In the C++ code, most calls to InsaneDaemon::log(...) use log levels ranging from 0 to 2. But even with "-vv", none of these logs are printed to /var/log/insaned.log. Some of the log messages should be written when an scanner button event triggers. The default log file is used.
Another issue:
When placing "-vv" at the beginning of the INSANED_EXTRAOPTS string, the daemon fails during startup. Example:
INSANED_EXTRAOPTS="-vv --sleep-ms=1000 --suspend-after-event"
$ sudo systemctl restart insaned
Job for insaned.service failed because the control process exited with error code. See "systemctl status insaned.service" and "journalctl -xe" for details.
$ sudo systemctl status insaned
● insaned.service - SANE scanner button polling service
Loaded: loaded (/lib/systemd/system/insaned.service; enabled; vendor preset: enabled)
Active: inactive (dead) (Result: exit-code) since Mo 2018-07-09 11:09:56 CEST; 1min 31s ago
Process: 25017 ExecStart=/usr/bin/insaned -p /var/run/insaned/insaned.pid ${INSANED_EXTRAOPTS} (code=exited, status=1/FAILURE)
Main PID: 24999 (code=exited, status=1/FAILURE)
Jul 09 11:09:56 MYHOSTNAME systemd[1]: Failed to start SANE scanner button polling service.
Jul 09 11:09:56 MYHOSTNAME systemd[1]: insaned.service: Unit entered failed state.
Jul 09 11:09:56 MYHOSTNAME systemd[1]: insaned.service: Failed with result 'exit-code'.
Jul 09 11:09:56 MYHOSTNAME systemd[1]: insaned.service: Service hold-off time over, scheduling restart.
Jul 09 11:09:56 MYHOSTNAME systemd[1]: Stopped SANE scanner button polling service.
Jul 09 11:09:56 MYHOSTNAME systemd[1]: insaned.service: Start request repeated too quickly.
Jul 09 11:09:56 MYHOSTNAME systemd[1]: Failed to start SANE scanner button polling service.
Jul 09 11:09:58 MYHOSTNAME systemd[1]: Stopped SANE scanner button polling service.
Jul 09 11:09:58 MYHOSTNAME systemd[1]: insaned.service: Start request repeated too quickly.
Jul 09 11:09:58 MYHOSTNAME systemd[1]: Failed to start SANE scanner button polling service.
$ journalctl -xe
<snip>
-- Unit insaned.service has begun starting up.
Jul 09 11:09:56 MYHOSTNAME insaned[25017]: /usr/bin/insaned: invalid option -- ' '
Jul 09 11:09:56 MYHOSTNAME systemd[1]: insaned.service: Control process exited, code=exited status=1
Jul 09 11:09:56 MYHOSTNAME systemd[1]: Failed to start SANE scanner button polling service.
-- Subject: Unit insaned.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit insaned.service has failed.
--
-- The result is failed.
System: Linux Mint 19 Cinnamon
Hi,
thanks for the awesome work; scanbuttond is just a mess.
I got things to run smoothly on Raspbian on a Raspberry Pi 3 with a Canon DR-2010C document scanner.
I noticed one thing. If the scanner is disconnected from USB, insaned continues to run (so far no problem). But when the scanner is reconnected insaned doesn't continue to poll for button presses. I tried to run a script via udev to killall insaned and promptly restarting it when the device is connected as workaround. But that - even though it kinda worked very slowly - was not the best solution. I even dug around in the source but my C++/USB-fu was too small (something about wrong parameters...).
So I made a little Python daemon called 'insanecheck.py'
import usb.core
import subprocess
import psutil
import daemon
import time
import sys
scriptdir="/mnt/dms/"
vId=0x1083
pId=0x161b
def getinsanedpid():
prcs = psutil.process_iter(attrs=['pid', 'name'])
pid = 0
count = 0
for p in prcs:
if 'insaned' in p.info['name']:
pid = p.info['pid']
count += 1
return pid
# 1083:161b
def main():
last = 0
try:
while(1):
dev = usb.core.find(idVendor=vId, idProduct=pId)
#print "insaned pid " + str(getinsanedpid())
if dev is None:
if last == 1:
subprocess.call([scriptdir+'/disconnect.sh'])
last = 0
#print "Scanner removed"
else:
if last == 0:
if getinsanedpid() > 0:
subprocess.call([scriptdir+'/disconnect.sh'])
subprocess.call([scriptdir+'/connect.sh'])
last = 1
#print "Scanner reconnected..."
time.sleep(0.5)
except:
print "Unexpected error:", sys.exc_info()[0]
raise
if __name__ == "__main__":
with daemon.DaemonContext():
main()
Works a treat. disconnect.sh just does "killall insaned" and connect.sh starts insaned with all parameters. 500ms scan interval might be a little low but whatever. It does the trick for me and only took an hour or so to code.
So long, keep it up :)
I have written a small graphical tool that saves scanned documents in the users home directory. 3 people use this computer / scanner. How should I configure INSANED_USER / INSANED_GROUP ?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.