Merge branch 'master' of git.someserver.de:k4ever
This commit is contained in:
commit
0ee86a1228
|
@ -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")
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2011 Sebastian Pipping <sebastian@pipping.org>
|
||||
# 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'))
|
|
@ -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
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
/*
|
||||
* Copyright (C) 2011 Florian Streibelt <florian@freitagsrunde.org>
|
||||
* Licensed under GPL v3 or later
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h> /* Standard input/output definitions */
|
||||
#include <string.h> /* String function definitions */
|
||||
#include <unistd.h> /* 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<LINELEN){
|
||||
spaces = LINELEN-offset; //anzahl spaces im ersten durchgang
|
||||
memset(message , ' ', spaces);
|
||||
}
|
||||
|
||||
strncpy (message+spaces, pausemsg + offset - LINELEN, LINELEN-spaces);
|
||||
|
||||
offset=(offset + 1) % (strlen(pausemsg)+LINELEN);
|
||||
if (offset==0){
|
||||
offset=LINELEN;
|
||||
}
|
||||
|
||||
int l = strlen (message);
|
||||
if (l < LINELEN)
|
||||
{
|
||||
message = strncat (message, pausemsg, LINELEN - l);
|
||||
}
|
||||
|
||||
SEND_TEXT ("\x0b");
|
||||
SEND_TEXT (message);
|
||||
free (message);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
char *devnode ;
|
||||
char *devnode;
|
||||
|
||||
//TODO: arg parser!
|
||||
fifo=strdup("/tmp/display");
|
||||
fifo = strdup ("/tmp/display");
|
||||
pausemsg = NULL ; //strdup("Bitte scanne Deine ID-Karte um Dich anzumelden *** ");
|
||||
|
||||
if (argc != 2)
|
||||
if (argc != 2)
|
||||
{
|
||||
devnode=strdup(DEVICE);
|
||||
printf ("no device specified, using default %s\n",devnode);
|
||||
}else{
|
||||
devnode=strdup(argv[1]);
|
||||
}
|
||||
devnode = strdup (DEVICE);
|
||||
printf ("no device specified, using default %s\n", devnode);
|
||||
}
|
||||
else
|
||||
{
|
||||
devnode = strdup (argv[1]);
|
||||
}
|
||||
fd = open (devnode, O_RDWR | O_NOCTTY | O_NDELAY);
|
||||
if (fd == -1)
|
||||
{
|
||||
|
@ -250,9 +326,7 @@ main (int argc, char **argv)
|
|||
initport (fd);
|
||||
|
||||
//init display, set, vertical scroll, cursor off
|
||||
SEND_DISPLAY_INIT;
|
||||
SEND_MODE_OVERWRITE;
|
||||
SEND_CURSOR_OFF;
|
||||
send_display_init();
|
||||
|
||||
pthread_create (&thread1, NULL, rthread, NULL);
|
||||
signal (SIGINT, sighandler);
|
||||
|
@ -273,38 +347,44 @@ main (int argc, char **argv)
|
|||
sleep (3);
|
||||
|
||||
screensaver = 0;
|
||||
offset = 0; // offset for scrolltext in screensaver
|
||||
|
||||
while (1)
|
||||
{
|
||||
usleep(TIME_BASE);
|
||||
//printf ("screensaver = %05d brightness: %d\n", screensaver, brightness);
|
||||
if (screensaver < 10000)
|
||||
usleep (TIME_BASE);
|
||||
|
||||
if (0 == (screensaver) % TB_TO_SECS (1))
|
||||
{
|
||||
screensaver++;
|
||||
//one-second event comes HERE:
|
||||
printf
|
||||
("debug: screensaver: %d time until clock: %d time until dim: %d time until off: %d\n",
|
||||
screensaver, TIME_CLOCK - screensaver, TIME_DIM - screensaver,
|
||||
TIME_OFF - screensaver);
|
||||
}
|
||||
|
||||
//printf ("screensaver = %05d brightness: %d\n", screensaver, brightness);
|
||||
if (screensaver < (TIME_CLOCK + TIME_OFF + TIME_DIM + 10)){
|
||||
screensaver++;
|
||||
}
|
||||
|
||||
if (screensaver == TIME_CLOCK)
|
||||
{
|
||||
display_dirty=1;
|
||||
showtime ();
|
||||
}
|
||||
if (screensaver == TIME_OFF)
|
||||
{
|
||||
display_dirty=1;
|
||||
display_dim (0);
|
||||
}
|
||||
|
||||
|
||||
//show a scroll text while the screensaver is active...
|
||||
if ((screensaver > (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<LINELEN){
|
||||
message = strncat(message, PAUSEMSG , LINELEN-l);
|
||||
}
|
||||
SEND_TEXT("\x0b");
|
||||
SEND_TEXT(message);
|
||||
free(message);
|
||||
}
|
||||
if ((screensaver > (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))
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2011 Andrew Karpow <andy@mail.tu-berlin.de>
|
||||
# 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)
|
||||
|
Loading…
Reference in New Issue