staging.inyokaproject.org

Scanner-Tastendrücke in einem bestimmten Zeitraum zählen (scanbuttond)

Status: Gelöst | Ubuntu-Version: Ubuntu 14.04 (Trusty Tahr)
Antworten |

Heinrich_Schwietering Team-Icon

Wikiteam
(Themenstarter)
Avatar von Heinrich_Schwietering

Anmeldungsdatum:
12. November 2005

Beiträge: 11335

Hi!

Mit deinen Änderungen klappt es jetzt gut, allerdings muss ich recht gelassen die Tasten drücken, so etwas im Sekundentakt - sobald ich zu schnell werde, werden Tasten verpasst... Dazu hab ich auch das timeout verlängert, sonst ist das Skript beim 5. Druck wieder bei eins 🙄. Mal sehen, ob ich das mit einer Yad-Abfrage puffern kann... Ist dann allerdings nicht ganz so komfortabel.

Besten Dank an dich, seahawk1986, für die Skripte! Wäre es für dich OK, wenn ich das in scanbuttond als Anwendungsbeispiel mit aufnehme (natürlich mit Namensnennung 😉 )?

so long
hank

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Heinrich Schwietering schrieb:

Hi!

Mit deinen Änderungen klappt es jetzt gut, allerdings muss ich recht gelassen die Tasten drücken, so etwas im Sekundentakt - sobald ich zu schnell werde, werden Tasten verpasst... Dazu hab ich auch das timeout verlängert, sonst ist das Skript beim 5. Druck wieder bei eins 🙄. Mal sehen, ob ich das mit einer Yad-Abfrage puffern kann... Ist dann allerdings nicht ganz so komfortabel.

Ok, dann ist fragt scanbuttond den Tastenstatus sehr langsam ab - das ist mit einem kurzen Timeout dann natürlich unpraktisch... Hilft es eventuell scanbuttond mit einem kürzeren Polling-Delay (z.B. 0,1 Sekunden: "-p 100000") zu starten?

Besten Dank an dich, seahawk1986, für die Skripte! Wäre es für dich OK, wenn ich das in scanbuttond als Anwendungsbeispiel mit aufnehme (natürlich mit Namensnennung 😉 )?

Ja, das kannst du gerne machen.

Heinrich_Schwietering Team-Icon

Wikiteam
(Themenstarter)
Avatar von Heinrich_Schwietering

Anmeldungsdatum:
12. November 2005

Beiträge: 11335

Hi!

Also in die rc.local

scanbuttond -f -p 100000

schreiben?

Ich hab gerade nochmal Rechte-Probleme... Weil scanbuttond als root läuft, startet auch der Drucker als root, und damit bekomme ich keine Druckvorscvhauu... Bastele noch ein wenig, mal sehen, was da besser geht (vielleicht läuft das ganze ja auch über user saned).

so long
hank

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Das Paket für scanbuttond bringt einen eigenen SysVinit-Job in '/etc/init.d/scanbuttond' mit - wenn du den in /etc/default/scanbuttond aktivierst, kannst du ihm in der Variable DAEMON_OPTS in der erstgenannten Datei noch Startparameter mitgeben (leider ist das Start-Skript so gestaltet, dass es die Variable nicht aus der /etc/default/scanbuttond übernehmen kann.

Dann läuft der Dienst auch erst mal unter dem User saned statt root - und du könntest den User sogar auf deinen Haupt-User abändern und falls du einen GUI-Dialog in zweiten Skript generierst, solltest du da noch die DISPLAY-Variable passend setzen:

export DISPLAY=:0

Wenn der Service speziell für einen angemeldeten Benutzer gestartet werden soll und GUI-Dialoge angezeigt werden sollen, bietet es sich IMHO an den Dienst in den Autostart der Desktop-Situng zu packen.

Heinrich_Schwietering Team-Icon

Wikiteam
(Themenstarter)
Avatar von Heinrich_Schwietering

Anmeldungsdatum:
12. November 2005

Beiträge: 11335

Hi!

Da versuche ich mich schon einige Zeit daran... Habe jetzt also in etc/default/scanbuttond mich als Benutzer eingetragen, RUN_AS_USER=heinrich und export DISPLAY=:0 ans Ende geschrieben. Gleichzeitig habe ich in der rc.local den EIntrag zu scanbuttond -f -p 100000 wieder rausgenommen...

Mal sehen, ob das jetzt hinhaut...

so long
hank

EDIT: Ergebnis: der Scanner startet nicht, in der Folge entsprechende Fehlermeldung, dass das tiff nicht gefunfden wird, mit langer Fehler-Meldung dazu... ABer mir fällt gerade auf, dass ich das mit DAEMON_OPTS nicht gemacht habe - was genau sollte ich denn da reinschreiben?

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Deine /etc/default/scanbuttond sollte ja in etwa so aussehen:

# Set to yes to start scanbuttond
RUN=yes

# Set to the user scanbuttond should run as
RUN_AS_USER=heinrich

# Disable logging of "no supported devices found" in /var/log/daemon.log
QUIET_LOG=0

Der relevante Teil für die DAEMON_OPTS wäre ab Zeile 37 in der /etc/init.d/scanbuttond:

DAEMON_OPTS="-p 100000"
if [ "${QUIET_LOG}" = 1 ]
then
  DAEMON_OPTS="${DAEMON_OPTS} --quiet"
fi

Und wenn der Scanner nicht startet könnte man ggf. mal die Ausgabe des Scan-Befehls aus dem Skript auf stderr in eine Datei umleiten und schauen, woran es hakt:

scanbefehl 2> /tmp/scan.err

Heinrich_Schwietering Team-Icon

Wikiteam
(Themenstarter)
Avatar von Heinrich_Schwietering

Anmeldungsdatum:
12. November 2005

Beiträge: 11335

Hi!

Jetzt hab ich in der etc/default/scanbuttond

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Defaults for the scanbuttond initscript, from scanbuttond

# Set to yes to start scanbuttond
RUN=yes

# Set to the user scanbuttond should run as
RUN_AS_USER=heinrich

#RUN_AS_USER=root

# Disable logging of "no supported devices found" in /var/log/daemon.log
QUIET_LOG=1

in /etc/inid.d/scannbuttond

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

#! /bin/sh
#
### BEGIN INIT INFO
# Provides:          scanbuttond
# Required-Start:    $syslog $local_fs $remote_fs
# Required-Stop:     $syslog $local_fs $remote_fs
# Should-Start:      dbus avahi
# Should-Stop:       dbus avahi
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: Scanner buttons events daemon
# Description:       scanbuttond associates actions to scanner
#                    buttons
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/scanbuttond
NAME=scanbuttond
DESC="Scanner buttons events daemon"

test -x $DAEMON || exit 0

RUN=yes
RUN_AS_USER=heinrich
QUIET_LOG=1

# Include scanbuttond defaults if available
if [ -f /etc/default/scanbuttond ] ; then
    . /etc/default/scanbuttond
fi

if [ "x$RUN" != "xyes" ] ; then
    echo "$NAME disabled; edit /etc/default/scanbuttond"
    exit 0
fi

DAEMON_OPTS="-p 100000"
if [ "${QUIET_LOG}" = 1 ]
then
  DAEMON_OPTS="${DAEMON_OPTS} --quiet"
fi

set -e

Aber der Scanner startet nicht... Also im Termional das hier eingegeben:

scanimage --format tiff --mode Lineart --resolution 300 -l 0 -t 0 -x 210mm -y 297mm > test.tiff 2> /tmp/scan.err

Ergebnis:

scanimage: open of device genesys:libusb:002:003 failed: Device busy

oh, ich glaub, ich gebs auf...

ALs ich eben in rc.local

scanbuttond -f -p 100000

stehn hatte, ist jedenfalls der Scanner gestartet, aber der Druckauftrag schgien als root zu laufen, jedenfalls habe ich keine Druckvorschau in Turboprint bekommen, und das wollte ich eigentlich erreichen...

so long
hank

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Heinrich Schwietering schrieb:

Aber der Scanner startet nicht... Also im Termional das hier eingegeben:

scanimage --format tiff --mode Lineart --resolution 300 -l 0 -t 0 -x 210mm -y 297mm > test.tiff 2> /tmp/scan.err

Ergebnis:

scanimage: open of device genesys:libusb:002:003 failed: Device busy

device busy heißt ja, jemand anderes greift gerade auf den Scanner zu - lief zu dem Zeitpunkt noch ein anderes Programm, das den Scanner genutzt hat?

oh, ich glaub, ich gebs auf...

ALs ich eben in rc.local

scanbuttond -f -p 100000

stehn hatte, ist jedenfalls der Scanner gestartet, aber der Druckauftrag schgien als root zu laufen, jedenfalls habe ich keine Druckvorschau in Turboprint bekommen, und das wollte ich eigentlich erreichen...

Versuch scanbuttond mal ohne das init-Skript über den Autostart in der Desktop-Session zu starten, dann sollten sowohl der User als auch die Umgebungsvariablen passen.

Heinrich_Schwietering Team-Icon

Wikiteam
(Themenstarter)
Avatar von Heinrich_Schwietering

Anmeldungsdatum:
12. November 2005

Beiträge: 11335

Hi!

Es läuft definitiv kein anderes Programm, was den Scanner belegen könnte...

Zum zweiten Vorschlag: Hab ich ja gemacht, aber dann bekomme ich in turboprint keine Vorschau...

Ich versuch jetzt noch mal, sowohl in /etc/default/scanbuttoned als auch in der init.d/scanbuttond mich als Benutrzer einzutragen.

so long
hank

EDIT klappt nicht besser. Aber wenn ich den Turboprint-monitor mit Root-Rechten starte, bekomme ich auch eine Vorschau angezeigt... 🙄 Das sollte doch lösbar sein... Kann ich in der rc.local beim scanbuttond-Befehl noch etwas mitgeben, dass mich als Benutzer festlegt, auch für den lpr-Befehl? Oder im Skript, was den Scanner startet und den Druckbefehl ausführt?

EDIT2 Vielleicht sollte ich es mal mit scanbd versuchen, das scheint etwas taufrischer zu sein als scanbuttond ...

Heinrich_Schwietering Team-Icon

Wikiteam
(Themenstarter)
Avatar von Heinrich_Schwietering

Anmeldungsdatum:
12. November 2005

Beiträge: 11335

Hi!

Scheine die Lösung gefunden zu haben: Wenn ich beim lpr-Befehl explizit -U heinrich angebe, funktioniert es, der Auftrag wird ordnungsgemäß auf der BEnutzerebene ausgeführt...

😎

so long
hank

EDIT Allerdings behauptet scanimage beim dritten Versuch dann doch wieder, dass der Scanner anderweitig beschäftigt sei... 🙄

EDIT2 Als kruder Workaround hab ich jetzt nach jedem Scanbefehl noch ein

scanimage -L 2>&1 > /dev/null |:

ins Skript geschrieben. Aus irgendwelchen mir nicht nachvollziehbaren Gründen scheint der Scanbefehl den Scanner nicht wieder "freizugeben", mit einem neuen scanimage-Befehl scheint es dann aber zu klappen... Mal sehen, wie lange 😬

Heinrich_Schwietering Team-Icon

Wikiteam
(Themenstarter)
Avatar von Heinrich_Schwietering

Anmeldungsdatum:
12. November 2005

Beiträge: 11335

Hi!

Das Problem mit dem "device busy" existiert weiterhin, manchmal will der Scanner einfach nicht starten, obwohl da nix ist, was das device belegt. Meist hilft dann ein nochmaliges Starten des ganzen Prozesses. Ich wollte jetzt ein yad-Fenster mit einer entsprechenden Meldung öffnen, allerdings startet yad nicht,

(yad:3894): Gtk-WARNING **: cannot open display: :0

... ich bekomme ich es nicht hin, die DISPLAY-Variable erfolgreich einzusetzen.

Ich starte scannbuttond inzwischen wieder über die rc.local, aber auch wenn ich dort ein export DISPLAY=:0 drinstehen habe - yad will nicht...

Was mache ich falsch?

so long
hank

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11278

Öffne mal in deiner Desktop-Session eine Shell und schau dir den Inhalt der DISPLAY-Variable an:

echo $DISPLAY

Unter welchem Benutzer läuft scanbuttond jetzt? Standardmäßig Lässt der X-Server ja keine "fremden" Fenster zu, mit

xhost +local:

kannst du allen lokalen Nutzern erlauben auf deinen X-Server zuzugreifen.

Heinrich_Schwietering Team-Icon

Wikiteam
(Themenstarter)
Avatar von Heinrich_Schwietering

Anmeldungsdatum:
12. November 2005

Beiträge: 11335

Hi!

seahawk1986 schrieb:

Öffne mal in deiner Desktop-Session eine Shell und schau dir den Inhalt der DISPLAY-Variable an:

echo $DISPLAY
echo $DISPLAY
:0

Unter welchem Benutzer läuft scanbuttond jetzt? Standardmäßig Lässt der X-Server ja keine "fremden" Fenster zu, mit

xhost +local:

kannst du allen lokalen Nutzern erlauben auf deinen X-Server zuzugreifen.

Scanbuttond hat in den scanbuttond-Dateien RUN_AS_USER=heinrich stehen... Warum das "fremde" Fenster sein sollen, ist mir nicht so ganz klar... Ich nehm' scanbuttond jetzt mal aus der rc.local raus und starte es über die /etc/default/scanbuttond. Mal sehen, was passiert. Wo müsste denn

xhost +local:

aufgenommen werden? Vielleicht hat yad ja auch eine Option, es unter einem bestimmten Benutzer laufen zu lassen, so wie lpr? - Ich finde in der man-page zu yad gerade dies hier: --parent-win=XID. Es gibt dann auch noch die Umgebungsvariable YAD_XID, Erklärung ist mir aber nicht ganz klar:

This  variable sets to the value of current dialog's X Window ID
and accessible in all dialog children. This variable is not  set
in  print  and notification dialogs, and in a dialogs which acts
as a notebook children.

😬

so long
hank

EDIT SO, jetzt scheint es zu klappen, yad startet tatsächlich...

Nur warum jetzt die Temporär-Datei nicht mehr gelöscht werden kann, ist mir nicht so ganz klar:

rm: cannot remove '.tiff': Permission denied

Heinrich_Schwietering Team-Icon

Wikiteam
(Themenstarter)
Avatar von Heinrich_Schwietering

Anmeldungsdatum:
12. November 2005

Beiträge: 11335

Hi!

So, jetzt läuft es einigermaßen, habe auch geklärt, was es mit dem nicht löschbarem tempfilr auf sich hatte: Ich hatte in buttonpressed.sh die Variable $TEMPFILE nicht mit an das Verarbeitungsskript übergeben... 😕

Das Skript sieht jetzt so aus:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/bin/bash

TIMEOUT=5 # count button presses after n seconds and take appropriate actions

PID_FILE=/tmp/scanbutton.pid
echo $$ > $PID_FILE  # create a file with our pid

declare -a BTN_PRESSED
BTN_PRESSED+=($(date +%s))

function cleanup {
    rm -f "$PID_FILE"
}

function check_runtime {
    if [[ ${BTN_PRESSED[0]} -lt $(date +%s -d "$TIMEOUT seconds ago") ]]; then
        return 1  # the oldest timestamp is older than $TIMEOUT
    else
        return 0
    fi
}

function scan_color {
#	echo "$SCANCOLOR"
	if [[ "$SCANCOLOR" == "BW" ]]; then
	scanimage --format tiff --mode Lineart --swcrop=yes --threshold 35 --resolution 300 -l 0 -t 0 -x 210mm -y 297mm > ${TMPFILE}.tiff 2> /tmp/scanimage.txt #scannt das Bild ein und speichert es als tiff (hier in Graustufen und Auflösung 300dpi) 
	elif [[ "$SCANCOLOR" == "GR" ]]; then
	scanimage --format tiff --mode Gray --swcrop=yes --swdeskew=yes --custom-gamma=yes --gamma-table 30000 --resolution 300 -l 0 -t 0 -x 210mm -y 297mm > ${TMPFILE}.tiff 2> /tmp/scanimage.txt
	elif [[ "$SCANCOLOR" == "CL" ]]; then
	scanimage --format tiff --mode Color --swcrop=yes --resolution 300 -l 4 -t 2 -x 210mm -y 297mm > ${TMPFILE}.tiff 2> /tmp/scanimage.txt
	fi
}

function print_tiff {
	tiff2ps -c -z -w 8.27 -h 11.69 ${TMPFILE}.tiff | lpr -U "$USER"
	echo "Scan sent to printer, ~~~`date +%Y%m%d`-`date +%H%M%S`"
	rm -f ${TMPFILE}.tiff #2>&1 > /dev/null |: #temporäre Datei wird gelöscht
}

function check_device {
	CHECK=`cat "/tmp/scanimage.txt"`
 	if [[ $CHECK != "" ]] ; then
		$(DISPLAY=:0 yad --on-top --center --timeout=10 --title="Device busy..." --text="Ooops - Problem mit der Scannerfreigabe! Versuche Neustart in 5 Sekunden!")
		echo "device problem `date +%Y%m%d`-`date +%H%M%S`"
		echo "$CHECK"
#		echo "$SCANCOLOR"
		sleep 3
		killall scanimage #2>&1 > /dev/null |:
		sleep 3
		if [[ "$SCANCOLOR" == "BW" ]]; then
			scanimage --format tiff --mode Lineart --swcrop=yes --threshold 35 --resolution 300 -l 0 -t 0 -x 210mm -y 297mm > ${TMPFILE}.tiff 2> /tmp/scanimage.txt
			elif [[ "$SCANCOLOR" == "GR" ]]; then
			scanimage --format tiff --mode Gray --swcrop=yes --swdeskew=yes --custom-gamma=yes --gamma-table 30000 --resolution 300 -l 0 -t 0 -x 210mm -y 297mm > ${TMPFILE}.tiff 2> /tmp/scanimage.txt
			elif [[ "$SCANCOLOR" == "CL" ]]; then
			scanimage --format tiff --mode Color --swcrop=yes --resolution 300 -l 4 -t 2 -x 210mm -y 297mm > ${TMPFILE}.tiff 2> /tmp/scanimage.txt
		fi
		CHECK1=`cat "/tmp/scanimage.txt"`
 		if [[ $CHECK1 != "" ]] ; then
			$(DISPLAY=:0 yad --on-top --center --timeout=10 --title="Device busy..." --text="Weiterhin Problem mit der Scannerfreigabe! \nAbbruch! Meldung: \n`echo $CHECK1`!")
			echo "device problem `date +%Y%m%d`-`date +%H%M%S`"
			echo "$CHECK1"
			exit 0
		fi
		echo "Scan completed, ~~~`date +%Y%m%d`-`date +%H%M%S`"
		tiff2ps -c -z -w 8.27 -h 11.69 ${TMPFILE}.tiff | lpr -U "$USER"
		echo "Scan sent to printer, ~~~`date +%Y%m%d`-`date +%H%M%S`"
		killall scanimage #2>&1 > /dev/null |:
		rm -f ${TMPFILE}.tiff #2>&1 > /dev/null |: #temporäre Datei wird gelöscht
		rm -f /tmp/scanimage.txt
		exit 0
	fi 
}


trap 'cleanup; exit 0' SIGTERM SIGINT
trap cleanup EXIT
trap "BTN_PRESSED+=($(date +%s));" SIGUSR1

killall scanimage #2>&1 > /dev/null |:

while check_runtime; do
    sleep 0.11  # if the button presses have a shorter delta t, then reduce this value
done

echo "~~~`date +%Y%m%d`-`date +%H%M%S`"
echo "Button has been pressed at ${BTN_PRESSED[@]}"
#$(DISPLAY=:0 gedit /tmp/scanbutton.log)
case ${#BTN_PRESSED[@]} in
1) echo "action #1, b/w-copy A4"
TMPFILE=$1
SCANCOLOR=BW
scan_color
check_device
echo "Scan completed, ~~~`date +%Y%m%d`-`date +%H%M%S`"
print_tiff
 ;;
2) echo "action #2 Grayscale-copy A4"
TMPFILE=$1
SCANCOLOR=GR
scan_color
check_device
echo "Scan completed, ~~~`date +%Y%m%d`-`date +%H%M%S`"
print_tiff
 ;;
3) echo "action #3, Color-copy A4"
TMPFILE=$1
SCANCOLOR=CL
scan_color
check_device
echo "Scan completed, ~~~`date +%Y%m%d`-`date +%H%M%S`"
print_tiff
 ;;
*) echo "too many button presses"
esac

killall scanimage 2>&1 > /dev/null |:

rm -f /tmp/scanimage.txt

Das Problem, dass scanimage immer mal wieder meldet:

scanimage: open of device genesys:libusb:002:003 failed: Device busy

konnte ich noch nicht ganz lösen - Manchmal klappt die im Skript verwurstete Möglichkeit, den Scanner nach ein paar Sekunden nochmal zu starten, manchmal aber auch nicht. Auch die Installation von libusb-1.0.20 hat keinen Erfolg gehabt, wobei ich allerdings gerade festgestellt habe, dass die libbus-trusty-Version libusb-0.1-4 weiterhin installiert ist - da weiß ich nicht, welche tatsächlich genutzt wird, hab jetzt eine Verknüpfung von libusb-0.1.so.4 auf die neue libusb-1.0.so.0.1.0 gelegt, mal sehen, ob es hilft...

so long
hank

EDIT (23.09.2015) scanbuttoned ist mit libusb-1.x nicht kompatibel, also auch dadurch keine Lösung des Problems in Sicht.

Heinrich_Schwietering Team-Icon

Wikiteam
(Themenstarter)
Avatar von Heinrich_Schwietering

Anmeldungsdatum:
12. November 2005

Beiträge: 11335

Hi!

So, jetzt geht es. Habe das ganze in scanbuttond - Mehrfachbelegung von Tasten verewigt. Mit usbreset lassen sich auch die "device busy" Meldungen verarbeiten, das Skript versucht dann, nach USB-Reset den Auftrag nochmal auszuführen.

so long
hank

Antworten |