diff --git a/client-barcode/display.py b/client-barcode/display.py new file mode 100644 index 0000000..509cd6a --- /dev/null +++ b/client-barcode/display.py @@ -0,0 +1,288 @@ +import serial +from thread import start_new_thread, allocate_lock +import time +import threading + +class Display(threading.Thread): + def __init__(self,portname="/dev/ttyUSB0"): + threading.Thread.__init__(self) + self.serialport=None + self.runme=True + self.idlemessage=None + self.portlock = allocate_lock() + self.portname=portname + self.brightness=5 + self.scroll_line1 = None + self.scroll_line2 = None + self.offset_line1 = 0 + self.offset_line2 = 0 + self.screensaver = Screensaver(self) + self.open_port() + + def __del__(self): + if (not self.screensaver == None): + self.screensaver = None + + if (not self.serialport == None): + self.serialport.close() + self.serialport=None + + def open_port(self): + try: + self.serialport = serial.Serial(self.portname,9600,timeout=2,rtscts=True, dsrdtr=True) + #print ("Initializing display on port:\n %s\n" % self.serialport ) + self.mutex_get() + self.cmd_reset() + self.mutex_release() + except Exception as e: + #print ("Exception opening serial port '%s' for display\n" % self.portname) + #print ("Ignoring and trying to open it again later\n") + #print (e) + self.serialport = None + + + #Helper-Function, scrolls text in a specific line. + def display_scroll_text(self,line,text): + if (line==1): #clear the line on invocation: + self.cmd("\x1f\x24\x01%c\x18" % chr(line) ) + self.scroll_line1 = text + self.offset_line1=0 + if (line==2): #clear the line on invocation: + self.cmd("\x1f\x24\x01%c\x18" % chr(line) ) + self.scroll_line2 = text + self.offset_line2=0 + + + def display_handle_scroll(self,line,text,offset): + if (text): + l = len(text) + if (l<21): + if (offset == 0): + self.cmd("\x1f\x24\x01%c%s" % (chr(line),text[offset:(20+offset)])) + offset=1 + else: + self.cmd("\x1f\x24\x01%c%s" % (chr(line),text[offset:(20+offset)])) + missing_chars=20+offset-l + if (missing_chars>0): + self.cmd(text[:missing_chars]) + offset=((offset+1)%l) + else: + offset=0 #reset offset + return offset + + + def run(self): + #print "Starting Display thread" + self.screensaver.start() + while(self.runme): + #print("display thread loop\n") + self.mutex_get() + #print("display got mutex and handles scroll\n") + self.offset_line1 = self.display_handle_scroll(1,self.scroll_line1,self.offset_line1) + self.offset_line2 = self.display_handle_scroll(2,self.scroll_line2,self.offset_line2) + self.mutex_release() + time.sleep(.5) + print "Exiting Display thread" + + + + + #Front-End Funtion to display a Screen + # with heading + def display_screen(self,title,message): + self.mutex_get() + + self.offset_line1=0 + self.offset_line2=0 + self.screensaver.idle_reset(); + self.cmd_brightness(5) + + if (len(title)<21): + self.scroll_line1=None + self.cmd("\x1f\x24\x01%c\x18%s" % (chr(1),'\xdb'*20) ) + if (len(title)<20): + pos=1+(20-len(title))/2 + else: + pos=1 + self.cmd("\x1f\x24%c%c%s" % (chr(pos),chr(1),title) ) + else: + self.display_scroll_text(1,title) + + self.display_scroll_text(2,message) + self.mutex_release() + + + + + def cmd_reset(self): + #reset the display + self.cmd("\x1b\x40") + + def cmd_cursor_show(self,on=True): + #show or hide the cursor + if (on): + self.cmd("\x1f\x43\x01") + else: + self.cmd("\x1f\x43\x00") + + def cmd_blink(self,rate=127): + self.cmd("\x1f\x45%c" % chr(rate)) + + + def cmd_brightness(self,level): + if (self.brightness==level): + return + #print("setting brightness to %i \n" %level) + if (level==0): #turn off: + self.cmd_display_on(False) + self.brightness = 0 + return + else: + if (self.brightness==0): #turn on, then set wanted brightness: + self.cmd_display_on(True) + self.brightness = level + self.cmd("\x1F\x58%c" % chr(level-1) ) + + def cmd_display_on(self,on=True): + # blink-command: + # where the last value defines the blink rate, + # with 0=always on, 255=always off + if (on): + if (not self.brightness==0): + return + #print("setting display to on: %s \n" % str(on)) + self.cmd_blink(0) + self.brightness=5 + else: + if (self.brightness==0): + return + #print("setting display to on: %s \n" % str(on)) + self.cmd_blink(255) + self.brightness=0 + + def cmd_curmode_overwrite(self): + self.cmd_curmode(1) + + def cmd_curmode_vscroll(self): + self.cmd_curmode(2) + + def cmd_curmode_hscroll(self): + self.cmd_curmode(3) + + def cmd_curmode(self,val=2): + self.cmd("\x1f%c" % chr(val)) + + def cmd_clear(self): + self.cmd("\x0c") + + + def cmd_time(self): + # activate timer display in lower right corner. + # actual time has to be set via display_set_timer. + self.cmd("\x1f\x55") + + def cmd_time_set(self,h=None,m=None): + if (h==None or m==None): + now = time.localtime() + h=now.tm_hour + m=now.tm_min + # configures hour and minutes of the internal clock and + # displays the time in the lower right corner. + # turns off when something gets written into the line. + # two bytes have to follow with hour and minute + self.cmd("\x1F\x54%c%c" % (chr(h),chr(m)) ) + self.cmd_curmode_hscroll() # makes the time more robust... + + def cmd(self,text): #for commands: do not reset screensaver timeout + self.write(text,False) + + def write(self,text,idle_reset=True): #for data: reset screensaver timeout + if (not self.serialport == None): + if (idle_reset): + self.screensaver.idle_reset(); + self.scroll_line1=None + self.scroll_line2=None + self.serialport.write(text) + else: + self.open_port() + + def setIdlemessage(self,text): + self.idlemessage=text + + def getIdlemessage(self): + return self.idlemessage + + def mutex_get(self): + self.portlock.acquire() + + def mutex_release(self): + self.portlock.release() + + def terminate(self): + self.runme=False + if (not self.screensaver == None): + self.screensaver.terminate() + self.screensaver = None + + +import threading +import time + +class Screensaver (threading.Thread): + def __init__(self,display): + threading.Thread.__init__(self) + self.display=display + self.runme=True + self.idlecounter=0 + self.timeout_dim=30 + self.timeout_message=60 + self.timeout_off=300 + self.mutex = allocate_lock() + threading.Thread.__init__(self) + + def run(self): + #print "Starting Screensaver thread" + while(self.runme): + self.mutex.acquire() + self._main_loop() + self.mutex.release() + time.sleep(.5) + #print "Exiting Screensaver thread" + + def terminate(self): + self.runme = False + + + def idle_reset(self): + self.mutex.acquire() + self.idlecounter=0 + self.display.cmd_brightness(5) + self.mutex.release() + + + def _main_loop(self): + if (self.idlecounter < self.timeout_off): + self.idlecounter+=1 + if (self.idlecounter>=self.timeout_dim and self.idlecounter <= (self.timeout_dim+7)): + x = (8-( self.idlecounter - self.timeout_dim))/2 + self.display.mutex_get() + self.display.cmd_brightness(1+x) + self.display.mutex_release() + return + + if (self.idlecounter==self.timeout_message): + self.display.mutex_get() + self.display.cmd_time_set() + self.display.scroll_line1 = self.display.getIdlemessage() + self.display.mutex_release() + return + + if (self.idlecounter==self.timeout_off): + self.display.mutex_get() + self.display.cmd_display_on(False) + self.display.mutex_release() + return + + def __del__(self): + print("bye") + diff --git a/client-barcode/freitagskasse.py b/client-barcode/freitagskasse.py index ae4886e..9958f60 100644 --- a/client-barcode/freitagskasse.py +++ b/client-barcode/freitagskasse.py @@ -7,6 +7,7 @@ from __future__ import print_function import freitagslib.network as net from freitagslib.commands import BuyCommand, DepositCommand +from freitagslib.encoding import asciify import colorama from colorama import Fore, Style @@ -17,7 +18,13 @@ from decimal import Decimal import os import time import urllib2 +import select +from display import Display +from thread import start_new_thread, allocate_lock +import time + +myDisplay=None COLOR_HINT = Fore.YELLOW + Style.BRIGHT COLOR_ERROR = Fore.RED @@ -30,6 +37,24 @@ COLOR_MUCH = Fore.YELLOW + Style.BRIGHT COLOR_RESET = Style.RESET_ALL +display_fifo = None + +scroll_line1 = None +scroll_line2 = None + + +offset_line1 = 0 +offset_line2 = 0 + +brightness = 5 +screensaver = 0 + +SCREENSAVER_DIM = 2* 20 +SCREENSAVER_TIMEOUT = 2* 120 +SCREENSAVER_OFF = 2* 10*60 + +lock = allocate_lock() + def clear(): os.system('clear') @@ -85,6 +110,33 @@ def error_page(error_message, hint_message=None): delay('Weiter', delay_seconds) +def item_info_page(item): + indent = 4 * ' ' + + clear() + print('Diese Ware heißt') + print() + print(indent + COLOR_SOME + item.name + COLOR_RESET) + print() + print('und kostet') + print() + if item.deposit > 0: + myDisplay.display_screen("PREISINFO","%s: %4.2f Euro (%4.2f Euro Pfand)" % (item.name,item.price,item.deposit)) + print(indent + '%s%4.2f Euro%s + %4.2f Euro Pfand = %s%4.2f Euro%s .' \ + % (COLOR_SOME, item.price, COLOR_RESET, item.deposit, + COLOR_MUCH, item.price + item.deposit, COLOR_RESET)) + else: + myDisplay.display_screen("PREISINFO","%s: %4.2f Euro" % (item.name,item.price)) + print(indent + '%s%4.2f Euro%s .' \ + % (COLOR_MUCH, item.price, COLOR_RESET)) + print() + print() + print(COLOR_MUCH + 'Zum Kaufen bitte einloggen.' + COLOR_RESET) + print() + + delay('Weiter', 6) + + class Status: def __init__(self): self._reset() @@ -97,6 +149,7 @@ class Status: self.transfers = None def dump(self): + def sign(amount, plus='+'): return '-' if amount < 0 else plus @@ -108,9 +161,15 @@ class Status: % ('', '', color(balance), sign(balance, plus), abs(balance), COLOR_RESET)) + def shorten(text, length): + if len(text) <= length: + return text + else: + return text[:length - 3] + '...' + def show_item(position, diff, label, color): print('%2d) %-40s %s%c %6.2f Euro%s' \ - % (position, label, color, sign(diff), + % (position, shorten(label, 40), color, sign(diff), abs(diff), COLOR_RESET)) def show_bar(): @@ -119,6 +178,7 @@ class Status: if self.logged_in(): print('Eingeloggt als: %s%s%s' % (COLOR_SOME, self.login_name, COLOR_RESET)) print() + myDisplay.write('\x0cHallo %-14s' % (self.login_name[:13]+"!") ) if self.transfers: initial_command, initial_balance = self.transfers[0] @@ -137,6 +197,25 @@ class Status: show_item(i, command.difference(), command.label(), COLOR_DEPOSIT) i += 1 show_bar() + + if isinstance(command, BuyCommand): + mycmd = 0; + if (command.includes_commodity()): + mycmd+=1; + if (command.includes_deposit()): + mycmd+=2; + if (mycmd==1): + mylabel=command.item_name() + if (mycmd==2): + mylabel="Pfand "+command.commodity_label()[:9] + if (mycmd==3): + mylabel=("%-13s" % (command.commodity_label()[:13]))+"+P" + myDisplay.write('\x0b%-15s %4.2f' % (asciify(mylabel)[:15],abs(command.difference()))); + myDisplay.write('\x0b\nSUMME: {%02i} %8.2f' % ((i-1),initial_balance - self.balance)); + else: + myDisplay.write('\x0b%-15s %4.2f' % (command.label()[:15],abs(command.difference()))); + myDisplay.write('\x0b\nSUMME: {%02i} %8.2f' % ((i-1),initial_balance - self.balance)); + if len(self.transfers) > 1: show_total(self.balance - initial_balance, plus='+') show_bar() @@ -144,11 +223,13 @@ class Status: if self.balance < 0: warn_balance() + myDisplay.write('\x0b\nKonto: %5.2f!' % (self.balance) ) print() print(COLOR_MUCH + 'Committen nicht vergessen.' + COLOR_RESET) else: print('Kontostand beträgt: %s%.2f Euro%s' % (COLOR_MUCH, self.balance, COLOR_RESET)) + myDisplay.display_screen("KONTOSTAND","%s: %.2f Euro" % (self.login_name,self.balance)) if self.balance < 0: print() warn_balance() @@ -156,6 +237,7 @@ class Status: print(COLOR_MUCH + 'Bitte einloggen.' + COLOR_RESET) print() print('Scanne dazu deine ID-Karte mit dem Barcode-Leser.') + myDisplay.display_screen("LOGIN","Bitte scanne Deinen Login-Token! *** ") print() def logged_in(self): @@ -172,14 +254,34 @@ class Status: self.balance = balance self.transfers = list() + def logout(self): + # Must not fail if not logged in + self._reset() + def commit(self): assert(self.logged_in()) + # Compress DepositCommands + dummy, initial_balance = self.transfers[0] + balance_before = initial_balance + compressed_deposit = DepositCommand(Decimal('0')) + others = list() + for (command, dummy) in list(self.transfers): + if isinstance(command, DepositCommand): + compressed_deposit.add(command) + else: + others.append((command, balance_before)) + balance_before += command.difference() + if compressed_deposit.difference() != 0: + others.append((compressed_deposit, balance_before)) + self.transfers = others + # Process command queue for (command, balance_backup) in list(self.transfers): try: command.run(self.login_name) except urllib2.HTTPError as e: + myDisplay.display_screen("Server error",'Server Error: %s' % str(e)) error_page('FEHLER bei Kommunikation mit Server "%s"' % str(e)) break else: @@ -191,8 +293,8 @@ class Status: self.dump() delay('Logout', 3) - # Logout - self._reset() + self.logout() + def find(self, barcode): try: @@ -262,9 +364,11 @@ class Status: error_page(_PRODUCT_FIRST) return if prev.includes_deposit(): + myDisplay.write('\x0cFEHLER: schon Pfand %20s' % prev.item_name()[:20]) error_page('FEHLER: Pfand für Produkt "%s" bereits aktiviert' % prev.item_name()) return if prev.deposit_value() <= 0: + myDisplay.write('\x0cFEHLER: Pfandfrei! %20s' % prev.item_name()[:20]) error_page('FEHLER: Produkt "%s" hat kein Pfand' % prev.item_name()) return before = prev.difference() @@ -302,11 +406,15 @@ class Status: def print_prompt(): sys.stdout.write(">>> ") + sys.stdout.flush() def handle(line, status): + myDisplay.setIdlemessage("Mir ist langweilig!") if line == 'exit': clear() + myDisplay.cmd_clear() + myDisplay.terminate() sys.exit(0) if status.logged_in(): @@ -320,39 +428,71 @@ def handle(line, status): item = status.find(line) except urllib2.HTTPError as e: if e.code == 404: # URL not found == item not found with REST + myDisplay.display_screen("FEHLER","Code ist unbekannt: '%s'" % ( line[:23])) error_page('FEHLER: Aktion oder Ware "%s" nicht bekannt' % line) else: + myDisplay.display_screen("Server error",'%20s' % str(e)[:20]) error_page('FEHLER bei Kommunikation mit Server "%s"' % str(e)) else: status.buy(item) else: try: status.login(line) + myDisplay.setIdlemessage(" Comitten nicht vergessen! ***") except urllib2.HTTPError as e: if e.code == 404: # URL not found == user unknown - error_page('FEHLER: Benutzer "%s" nicht bekannt' % line, - hint_message='Ist in der WebApp unter "Einstellungen" ' \ - 'für Ihren Account Plugin "BarcodePlugin" ' \ - 'als erlaubt markiert?') + # Try same code as a product + item = None + try: + item = status.find(line) + except urllib2.HTTPError as e: + pass + + if item is None: + myDisplay.display_screen("FEHLER","Nutzer ist unbekannt: '%s' *** " % line) + + error_page('FEHLER: Produkt oder Nutzer "%s" nicht bekannt' % line, + hint_message='Ist in der WebApp unter "Einstellungen" ' \ + 'für Ihren Account Plugin "BarcodePlugin" ' \ + 'als erlaubt markiert?') + else: + item_info_page(item) + else: + myDisplay.display_screen("FEHLER",'Server Error %20s' % str(e)[:20]) error_page('FEHLER bei Kommunikation mit Server "%s"' % str(e)) except urllib2.URLError as e: error_page('FEHLER bei Kommunikation mit Server "%s"' % str(e)) +def read_line(f, timeout, timeout_func): + ready_to_read, _, _ = select.select([f], [], [], timeout) + if ready_to_read: + return f.readline().rstrip() + else: + timeout_func() + return '' + + def main(): colorama.init() status = Status() + global scroll_line1,scroll_line2 + global myDisplay + myDisplay = Display("/dev/ttyUSB0") + myDisplay.start() + myDisplay.cmd_reset() + myDisplay.cmd_cursor_show(False) + + myDisplay.display_screen("Bitte Geduld","Initialisierung... ") while True: clear() status.dump() print_prompt() - l = sys.stdin.readline() - if not l: - break - line = l.rstrip() + line = read_line(sys.stdin, timeout=3*60.0, timeout_func=status.logout) if line: + myDisplay.write('\x0cRFID/Barcode:\n%20s' % line[:20]) handle(line, status) @@ -360,4 +500,8 @@ if __name__ == '__main__': try: main() except KeyboardInterrupt: + myDisplay.terminate() + myDisplay.cmd_reset() + myDisplay.cmd_cursor_show(False) pass + diff --git a/client-barcode/freitagslib/commands.py b/client-barcode/freitagslib/commands.py index 1782118..69a27ab 100644 --- a/client-barcode/freitagslib/commands.py +++ b/client-barcode/freitagslib/commands.py @@ -15,6 +15,10 @@ class DepositCommand(object): def difference(self): return self._difference + def add(self, deposit_command): + assert(isinstance(deposit_command, DepositCommand)) + self._difference += deposit_command._difference + def run(self, user_name): net.deposit(self._difference, net.DEPOSIT_CASH, user_name) diff --git a/client-barcode/freitagslib/encoding.py b/client-barcode/freitagslib/encoding.py new file mode 100644 index 0000000..00ee211 --- /dev/null +++ b/client-barcode/freitagslib/encoding.py @@ -0,0 +1,42 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2011 Sebastian Pipping +# Licensed under GPL v3 or later + +from __future__ import print_function + +def ensure_unicode(candidate, encoding='utf-8'): + if isinstance(candidate, basestring) \ + and not isinstance(candidate, unicode): + return unicode(candidate, encoding) + return candidate + + +def asciify(text): + _mapping = ( + ('ö', 'oe'), + ('Ö', 'Oe'), + ('ä', 'ae'), + ('Ä', 'Ae'), + ('ü', 'ue'), + ('Ü', 'Ue'), + ('ß', 'ss'), + ) + _mapping = dict(((ord(unicode(key, 'utf-8')), value) for key, value in _mapping)) + + def subst(unichar): + def fix(unichar): + if ord(unichar) > 127: + return unicode('?') + return unichar + + return _mapping.get(ord(unichar), fix(unichar)) + + unichars = ensure_unicode(text, 'utf-8') + unitext = ''.join(subst(e) for e in unichars) + return unitext.encode('ascii') + + +if __name__ == '__main__': + print(asciify('Schöfferhofer')) diff --git a/display-daemon/Makefile b/display-daemon/Makefile index d242e59..ceff071 100644 --- a/display-daemon/Makefile +++ b/display-daemon/Makefile @@ -2,3 +2,5 @@ CFLAGS=-g -Wall ser: ser.c gcc -ggdb -Wall ser.c -o ser -lpthread #mipsel-linux-uclibc-gcc -o ser.mips ser.c -lpthread +run: ser + ./ser diff --git a/display-daemon/ser.c b/display-daemon/ser.c index f9d6725..d01ab45 100644 --- a/display-daemon/ser.c +++ b/display-daemon/ser.c @@ -1,3 +1,9 @@ +/* + * Copyright (C) 2011 Florian Streibelt + * Licensed under GPL v3 or later + * + */ + #include /* Standard input/output definitions */ #include /* String function definitions */ #include /* UNIX standard function definitions */ @@ -14,9 +20,13 @@ int fd; +int display_dirty=0; int screensaver; int brightness = 4; +int offset = 0; char *fifo; +char *pausemsg = NULL; + pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; pthread_t thread1; @@ -42,30 +52,51 @@ initport (int fd) return 1; } - +//reset the display to defaults char display_init[] = { 0x1b, 0x40 }; -char display_showtime[] = { 0x1F, 0x54 }; + +//show or hide the cursor char display_cursor_off[] = { 0x1f, 0x43, 0x0 }; char display_cursor_on[] = { 0x1f, 0x43, 0x1 }; +// blink-command: +// where the last value defines the blink rate, +// with 0=always on, 255=always off char display_on[] = { 0x1f, 0x45, 0x0 }; char display_off[] = { 0x1f, 0x45, 0xff }; +//Modes for new chars: char display_overwrite[] = { 0x1f, 0x01 }; char display_vscroll[] = { 0x1f, 0x02 }; char display_hscroll[] = { 0x1f, 0x03 }; +//clear and cursor home char display_clear_screen[] = { 0x0c }; -char display_time[] = {0x1f,0x55}; +// activate timer display in lower right corner. +// actual time has to be set via display_set_timer. +char display_time[] = { 0x1f, 0x55 }; + +// configures hour and minutes of the internal clock and +// displays the time in the lower right corner. +// turns off when something gets written into the line. +// two bytes have to follow with hour and minute +char display_set_timer[] = { 0x1F, 0x54 }; + +// various commands for the display: +// send a command sequence from the heap(!) {sizeof used} +// only to be used within the macros presented below! #define DWC(c) display_write(c,sizeof(c)) + +//send a null terminated string: #define SEND_TEXT(t) display_write(t,strlen(t)) +//various commands #define SEND_DISPLAY_INIT DWC(display_init) #define SEND_CURSOR_OFF DWC(display_cursor_off) #define SEND_CURSOR_ON DWC(display_cursor_on) -#define SEND_DEFINE_TIMER DWC(display_showtime) +#define SEND_DEFINE_TIMER DWC(display_set_timer) #define SEND_SHOW_TIMER DWC(display_time) #define SEND_MODE_OVERWRITE DWC(display_overwrite) #define SEND_MODE_VSCROLL DWC(display_vscroll) @@ -74,19 +105,21 @@ char display_time[] = {0x1f,0x55}; #define SEND_DISPLAY_ON DWC(display_on) #define SEND_CLEAR DWC(display_clear_screen); +// internal defines. #define TIME_BASE 200000 #define TB_TO_SECS(x) (x*1000000/TIME_BASE) -#define TIME_CLOCK TB_TO_SECS(5) -#define TIME_DIM TB_TO_SECS(30) -#define TIME_OFF TB_TO_SECS(120) +#define TIME_CLOCK TB_TO_SECS(65) +#define TIME_DIM TB_TO_SECS(90) +#define TIME_OFF TB_TO_SECS(520) #define DEVICE "/dev/ttyUSB0" -#define PAUSEMSG "Hallo, bitte melde Dich am Barcodereader an, um das Kassensystem zu benutzen *** Angebot: Die Mate heute nur 0.75 *** " - + +// chars per line in our display: #define LINELEN 20 + void display_write (const void *buf, size_t count) { @@ -101,7 +134,7 @@ void display_putstring (char *s) { screensaver = 0; - SEND_TEXT(s); + SEND_TEXT (s); } @@ -127,6 +160,14 @@ showtime (void) display_write (msg, strlen (msg)); } +void +send_display_init(){ + SEND_DISPLAY_INIT; + SEND_CURSOR_OFF; + SEND_DISPLAY_ON; + SEND_MODE_OVERWRITE; +} + void display_dim (short i) { @@ -144,10 +185,7 @@ display_dim (short i) char *d; if (brightness == 0) { - SEND_CURSOR_OFF; - // turn display on again - SEND_DISPLAY_ON; - SEND_MODE_OVERWRITE; + send_display_init(); char c[4] = { 0x1f, 0x58, 0x04, 0x00 }; l = 6; //c[5]=i; @@ -188,6 +226,12 @@ rthread (void *args) { screensaver = 0; + if (display_dirty) { + printf("DEBUG: resetting display\n"); + send_display_init(); + display_dirty=0; + } + display_dim (4); if (pc == '\n') { @@ -198,7 +242,6 @@ rthread (void *args) display_write (&c, 1); } pc = c; - display_dim (4); } close (pipe); } @@ -208,34 +251,67 @@ void sighandler (int sig) { pthread_kill (thread1, 0); - - SEND_DISPLAY_INIT; - SEND_MODE_OVERWRITE; - SEND_CURSOR_OFF; + send_display_init(); SEND_DISPLAY_OFF; close (fd); - if (fifo) {unlink(fifo);} + if (fifo) + { + unlink (fifo); + } exit (0); //signal(sig, sighandler); } +void scrolltext(){ + + if (pausemsg){ + char *message = calloc (LINELEN + 1, sizeof (char)); + + int spaces=0; + + if (offset (TIME_CLOCK+10)) && (screensaver < TIME_OFF)){ - char *message = calloc(LINELEN+1,sizeof(char)); - strncpy(message,PAUSEMSG+((screensaver-TIME_CLOCK-1)%strlen(PAUSEMSG)),LINELEN); - int l = strlen(message); - if (l (TIME_CLOCK + 10)) && (screensaver < TIME_OFF)) + { + display_dirty=1; + scrolltext(); + } //after some more seconds of inactivity dim display and finally turn off if ((screensaver > TIME_DIM) && (brightness > 1)) diff --git a/rfid/rfid_keypresser.py b/rfid/rfid_keypresser.py new file mode 100755 index 0000000..819691c --- /dev/null +++ b/rfid/rfid_keypresser.py @@ -0,0 +1,56 @@ +#! /usr/bin/env python +# -*- coding: utf-8 -*- +# +# Copyright (C) 2011 Andrew Karpow +# Licensed under GPL v3 or later + +from smartcard.CardMonitoring import CardMonitor, CardObserver +from smartcard.util import toHexString +from threading import Condition +import subprocess + +# a simple card observer that prints inserted/removed cards +class printobserver(CardObserver): + + def update(self, observable, (addedcards, removedcards)): + for card in addedcards: + + SELECT_GUID= [0xFF, 0xCA, 0x00, 0x00, 0x00] + print "+Inserted: ", toHexString(card.atr) + + try: + card.connection = card.createConnection() + card.connection.connect() + + # Request UID - Unique Identifier + response, sw1, sw2 = card.connection.transmit(SELECT_GUID) + + except Exception as e: + print str(e) + continue + + # convert UID to hex-string and remove whitespaces + send= toHexString(response).replace(' ', '') + + try: + # Send UID to active window + subprocess.Popen(['xdotool', 'type', send+'\n']) + except OSError as e: + print str(e) + + for card in removedcards: + print "-Removed: ", toHexString(card.atr) + + +if __name__ == '__main__': + cardmonitor= CardMonitor() + cardobserver= printobserver() + cardmonitor.addObserver(cardobserver) + + try: + c= Condition() + c.acquire() + c.wait() + except KeyboardInterrupt as e: + cardmonitor.deleteObserver(cardobserver) +