Merge branch 'display-threading'

This commit is contained in:
Florian Streibelt 2011-10-19 01:23:58 +02:00
commit 8fd3a73d0a
5 changed files with 598 additions and 57 deletions

291
client-barcode/display.py Normal file
View File

@ -0,0 +1,291 @@
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):
self.mutex_get()
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.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
self.mutex_release()
pass
#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")

View File

@ -7,6 +7,7 @@
from __future__ import print_function from __future__ import print_function
import freitagslib.network as net import freitagslib.network as net
from freitagslib.commands import BuyCommand, DepositCommand from freitagslib.commands import BuyCommand, DepositCommand
from freitagslib.encoding import asciify
import colorama import colorama
from colorama import Fore, Style from colorama import Fore, Style
@ -17,7 +18,13 @@ from decimal import Decimal
import os import os
import time import time
import urllib2 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_HINT = Fore.YELLOW + Style.BRIGHT
COLOR_ERROR = Fore.RED COLOR_ERROR = Fore.RED
@ -30,6 +37,24 @@ COLOR_MUCH = Fore.YELLOW + Style.BRIGHT
COLOR_RESET = Style.RESET_ALL 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(): def clear():
os.system('clear') os.system('clear')
@ -85,6 +110,30 @@ def error_page(error_message, hint_message=None):
delay('Weiter', delay_seconds) 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:
print(indent + '%s%4.2f Euro%s (plus %4.2f Euro Pfand) .' \
% (COLOR_MUCH, item.price, COLOR_RESET, item.deposit))
else:
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', 3)
class Status: class Status:
def __init__(self): def __init__(self):
self._reset() self._reset()
@ -97,6 +146,7 @@ class Status:
self.transfers = None self.transfers = None
def dump(self): def dump(self):
def sign(amount, plus='+'): def sign(amount, plus='+'):
return '-' if amount < 0 else plus return '-' if amount < 0 else plus
@ -108,9 +158,15 @@ class Status:
% ('', '', color(balance), sign(balance, plus), % ('', '', color(balance), sign(balance, plus),
abs(balance), COLOR_RESET)) 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): def show_item(position, diff, label, color):
print('%2d) %-40s %s%c %6.2f Euro%s' \ 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)) abs(diff), COLOR_RESET))
def show_bar(): def show_bar():
@ -119,6 +175,7 @@ class Status:
if self.logged_in(): if self.logged_in():
print('Eingeloggt als: %s%s%s' % (COLOR_SOME, self.login_name, COLOR_RESET)) print('Eingeloggt als: %s%s%s' % (COLOR_SOME, self.login_name, COLOR_RESET))
print() print()
myDisplay.write('\x0cHallo %-14s' % (self.login_name[:13]+"!") )
if self.transfers: if self.transfers:
initial_command, initial_balance = self.transfers[0] initial_command, initial_balance = self.transfers[0]
@ -137,6 +194,25 @@ class Status:
show_item(i, command.difference(), command.label(), COLOR_DEPOSIT) show_item(i, command.difference(), command.label(), COLOR_DEPOSIT)
i += 1 i += 1
show_bar() 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: if len(self.transfers) > 1:
show_total(self.balance - initial_balance, plus='+') show_total(self.balance - initial_balance, plus='+')
show_bar() show_bar()
@ -144,11 +220,13 @@ class Status:
if self.balance < 0: if self.balance < 0:
warn_balance() warn_balance()
myDisplay.write('\x0b\nKonto: %5.2f!' % (self.balance) )
print() print()
print(COLOR_MUCH + 'Committen nicht vergessen.' + COLOR_RESET) print(COLOR_MUCH + 'Committen nicht vergessen.' + COLOR_RESET)
else: else:
print('Kontostand beträgt: %s%.2f Euro%s' % (COLOR_MUCH, self.balance, COLOR_RESET)) 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: if self.balance < 0:
print() print()
warn_balance() warn_balance()
@ -156,6 +234,7 @@ class Status:
print(COLOR_MUCH + 'Bitte einloggen.' + COLOR_RESET) print(COLOR_MUCH + 'Bitte einloggen.' + COLOR_RESET)
print() print()
print('Scanne dazu deine ID-Karte mit dem Barcode-Leser.') print('Scanne dazu deine ID-Karte mit dem Barcode-Leser.')
myDisplay.display_screen("LOGIN","Bitte scanne Deinen login-Token! *** ")
print() print()
def logged_in(self): def logged_in(self):
@ -172,6 +251,10 @@ class Status:
self.balance = balance self.balance = balance
self.transfers = list() self.transfers = list()
def logout(self):
# Must not fail if not logged in
self._reset()
def commit(self): def commit(self):
assert(self.logged_in()) assert(self.logged_in())
@ -180,6 +263,7 @@ class Status:
try: try:
command.run(self.login_name) command.run(self.login_name)
except urllib2.HTTPError as e: 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)) error_page('FEHLER bei Kommunikation mit Server "%s"' % str(e))
break break
else: else:
@ -191,8 +275,8 @@ class Status:
self.dump() self.dump()
delay('Logout', 3) delay('Logout', 3)
# Logout self.logout()
self._reset()
def find(self, barcode): def find(self, barcode):
try: try:
@ -262,9 +346,11 @@ class Status:
error_page(_PRODUCT_FIRST) error_page(_PRODUCT_FIRST)
return return
if prev.includes_deposit(): 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()) error_page('FEHLER: Pfand für Produkt "%s" bereits aktiviert' % prev.item_name())
return return
if prev.deposit_value() <= 0: 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()) error_page('FEHLER: Produkt "%s" hat kein Pfand' % prev.item_name())
return return
before = prev.difference() before = prev.difference()
@ -302,14 +388,18 @@ class Status:
def print_prompt(): def print_prompt():
sys.stdout.write(">>> ") sys.stdout.write(">>> ")
sys.stdout.flush()
def handle(line, status): def handle(line, status):
if line == 'exit': if line == 'exit':
clear() clear()
myDisplay.write("\x0c")
myDisplay.terminate()
sys.exit(0) sys.exit(0)
if status.logged_in(): if status.logged_in():
myDisplay.setIdlemessage(" Comitten nicht vergessen! ***")
if line in CODES: if line in CODES:
call = CODES[line] call = CODES[line]
method = call[0] method = call[0]
@ -320,39 +410,72 @@ def handle(line, status):
item = status.find(line) item = status.find(line)
except urllib2.HTTPError as e: except urllib2.HTTPError as e:
if e.code == 404: # URL not found == item not found with REST 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) error_page('FEHLER: Aktion oder Ware "%s" nicht bekannt' % line)
else: else:
myDisplay.display_screen("Server error",'%20s' % str(e)[:20])
error_page('FEHLER bei Kommunikation mit Server "%s"' % str(e)) error_page('FEHLER bei Kommunikation mit Server "%s"' % str(e))
else: else:
status.buy(item) status.buy(item)
else: else:
myDisplay.setIdlemessage("Mir ist langweilig!")
try: try:
status.login(line) status.login(line)
except urllib2.HTTPError as e: except urllib2.HTTPError as e:
if e.code == 404: # URL not found == user unknown if e.code == 404: # URL not found == user unknown
error_page('FEHLER: Benutzer "%s" nicht bekannt' % line, # 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" ' \ hint_message='Ist in der WebApp unter "Einstellungen" ' \
'für Ihren Account Plugin "BarcodePlugin" ' \ 'für Ihren Account Plugin "BarcodePlugin" ' \
'als erlaubt markiert?') 'als erlaubt markiert?')
else: 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)) error_page('FEHLER bei Kommunikation mit Server "%s"' % str(e))
except urllib2.URLError as e: except urllib2.URLError as e:
error_page('FEHLER bei Kommunikation mit Server "%s"' % str(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(): def main():
colorama.init() colorama.init()
status = Status() 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("HINWEIS","Herzlich willkommen bei der Freitagsrunde! *** ")
time.sleep(5)
while True: while True:
clear() clear()
status.dump() status.dump()
print_prompt() print_prompt()
l = sys.stdin.readline() line = read_line(sys.stdin, timeout=3*60.0, timeout_func=status.logout)
if not l:
break
line = l.rstrip()
if line: if line:
myDisplay.write('\x0cBarcode:\n%20s' % line[:20])
handle(line, status) handle(line, status)
@ -360,4 +483,7 @@ if __name__ == '__main__':
try: try:
main() main()
except KeyboardInterrupt: except KeyboardInterrupt:
myDisplay.terminate()
myDisplay.write("\x1b\x40Goodbye!")
pass pass

View File

@ -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'))

View File

@ -2,3 +2,5 @@ CFLAGS=-g -Wall
ser: ser.c ser: ser.c
gcc -ggdb -Wall ser.c -o ser -lpthread gcc -ggdb -Wall ser.c -o ser -lpthread
#mipsel-linux-uclibc-gcc -o ser.mips ser.c -lpthread #mipsel-linux-uclibc-gcc -o ser.mips ser.c -lpthread
run: ser
./ser

View File

@ -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 <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */ #include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */ #include <unistd.h> /* UNIX standard function definitions */
@ -14,9 +20,13 @@
int fd; int fd;
int display_dirty=0;
int screensaver; int screensaver;
int brightness = 4; int brightness = 4;
int offset = 0;
char *fifo; char *fifo;
char *pausemsg = NULL;
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_t thread1; pthread_t thread1;
@ -42,30 +52,51 @@ initport (int fd)
return 1; return 1;
} }
//reset the display to defaults
char display_init[] = { 0x1b, 0x40 }; 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_off[] = { 0x1f, 0x43, 0x0 };
char display_cursor_on[] = { 0x1f, 0x43, 0x1 }; 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_on[] = { 0x1f, 0x45, 0x0 };
char display_off[] = { 0x1f, 0x45, 0xff }; char display_off[] = { 0x1f, 0x45, 0xff };
//Modes for new chars:
char display_overwrite[] = { 0x1f, 0x01 }; char display_overwrite[] = { 0x1f, 0x01 };
char display_vscroll[] = { 0x1f, 0x02 }; char display_vscroll[] = { 0x1f, 0x02 };
char display_hscroll[] = { 0x1f, 0x03 }; char display_hscroll[] = { 0x1f, 0x03 };
//clear and cursor home
char display_clear_screen[] = { 0x0c }; char display_clear_screen[] = { 0x0c };
// activate timer display in lower right corner.
// actual time has to be set via display_set_timer.
char display_time[] = { 0x1f, 0x55 }; 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)) #define DWC(c) display_write(c,sizeof(c))
//send a null terminated string:
#define SEND_TEXT(t) display_write(t,strlen(t)) #define SEND_TEXT(t) display_write(t,strlen(t))
//various commands
#define SEND_DISPLAY_INIT DWC(display_init) #define SEND_DISPLAY_INIT DWC(display_init)
#define SEND_CURSOR_OFF DWC(display_cursor_off) #define SEND_CURSOR_OFF DWC(display_cursor_off)
#define SEND_CURSOR_ON DWC(display_cursor_on) #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_SHOW_TIMER DWC(display_time)
#define SEND_MODE_OVERWRITE DWC(display_overwrite) #define SEND_MODE_OVERWRITE DWC(display_overwrite)
#define SEND_MODE_VSCROLL DWC(display_vscroll) #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_DISPLAY_ON DWC(display_on)
#define SEND_CLEAR DWC(display_clear_screen); #define SEND_CLEAR DWC(display_clear_screen);
// internal defines.
#define TIME_BASE 200000 #define TIME_BASE 200000
#define TB_TO_SECS(x) (x*1000000/TIME_BASE) #define TB_TO_SECS(x) (x*1000000/TIME_BASE)
#define TIME_CLOCK TB_TO_SECS(5) #define TIME_CLOCK TB_TO_SECS(65)
#define TIME_DIM TB_TO_SECS(30) #define TIME_DIM TB_TO_SECS(90)
#define TIME_OFF TB_TO_SECS(120) #define TIME_OFF TB_TO_SECS(520)
#define DEVICE "/dev/ttyUSB0" #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 #define LINELEN 20
void void
display_write (const void *buf, size_t count) display_write (const void *buf, size_t count)
{ {
@ -127,6 +160,14 @@ showtime (void)
display_write (msg, strlen (msg)); display_write (msg, strlen (msg));
} }
void
send_display_init(){
SEND_DISPLAY_INIT;
SEND_CURSOR_OFF;
SEND_DISPLAY_ON;
SEND_MODE_OVERWRITE;
}
void void
display_dim (short i) display_dim (short i)
{ {
@ -144,10 +185,7 @@ display_dim (short i)
char *d; char *d;
if (brightness == 0) if (brightness == 0)
{ {
SEND_CURSOR_OFF; send_display_init();
// turn display on again
SEND_DISPLAY_ON;
SEND_MODE_OVERWRITE;
char c[4] = { 0x1f, 0x58, 0x04, 0x00 }; char c[4] = { 0x1f, 0x58, 0x04, 0x00 };
l = 6; l = 6;
//c[5]=i; //c[5]=i;
@ -188,6 +226,12 @@ rthread (void *args)
{ {
screensaver = 0; screensaver = 0;
if (display_dirty) {
printf("DEBUG: resetting display\n");
send_display_init();
display_dirty=0;
}
display_dim (4);
if (pc == '\n') if (pc == '\n')
{ {
@ -198,7 +242,6 @@ rthread (void *args)
display_write (&c, 1); display_write (&c, 1);
} }
pc = c; pc = c;
display_dim (4);
} }
close (pipe); close (pipe);
} }
@ -208,18 +251,48 @@ void
sighandler (int sig) sighandler (int sig)
{ {
pthread_kill (thread1, 0); pthread_kill (thread1, 0);
send_display_init();
SEND_DISPLAY_INIT;
SEND_MODE_OVERWRITE;
SEND_CURSOR_OFF;
SEND_DISPLAY_OFF; SEND_DISPLAY_OFF;
close (fd); close (fd);
if (fifo) {unlink(fifo);} if (fifo)
{
unlink (fifo);
}
exit (0); exit (0);
//signal(sig, sighandler); //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 int
main (int argc, char **argv) main (int argc, char **argv)
@ -228,12 +301,15 @@ main (int argc, char **argv)
//TODO: arg parser! //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); devnode = strdup (DEVICE);
printf ("no device specified, using default %s\n", devnode); printf ("no device specified, using default %s\n", devnode);
}else{ }
else
{
devnode = strdup (argv[1]); devnode = strdup (argv[1]);
} }
fd = open (devnode, O_RDWR | O_NOCTTY | O_NDELAY); fd = open (devnode, O_RDWR | O_NOCTTY | O_NDELAY);
@ -250,9 +326,7 @@ main (int argc, char **argv)
initport (fd); initport (fd);
//init display, set, vertical scroll, cursor off //init display, set, vertical scroll, cursor off
SEND_DISPLAY_INIT; send_display_init();
SEND_MODE_OVERWRITE;
SEND_CURSOR_OFF;
pthread_create (&thread1, NULL, rthread, NULL); pthread_create (&thread1, NULL, rthread, NULL);
signal (SIGINT, sighandler); signal (SIGINT, sighandler);
@ -273,37 +347,43 @@ main (int argc, char **argv)
sleep (3); sleep (3);
screensaver = 0; screensaver = 0;
offset = 0; // offset for scrolltext in screensaver
while (1) while (1)
{ {
usleep (TIME_BASE); usleep (TIME_BASE);
//printf ("screensaver = %05d brightness: %d\n", screensaver, brightness);
if (screensaver < 10000) if (0 == (screensaver) % TB_TO_SECS (1))
{ {
//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++; screensaver++;
} }
if (screensaver == TIME_CLOCK) if (screensaver == TIME_CLOCK)
{ {
display_dirty=1;
showtime (); showtime ();
} }
if (screensaver == TIME_OFF) if (screensaver == TIME_OFF)
{ {
display_dirty=1;
display_dim (0); display_dim (0);
} }
//show a scroll text while the screensaver is active... //show a scroll text while the screensaver is active...
if ((screensaver > (TIME_CLOCK+10)) && (screensaver < TIME_OFF)){ 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); display_dirty=1;
int l = strlen(message); scrolltext();
if (l<LINELEN){
message = strncat(message, PAUSEMSG , LINELEN-l);
}
SEND_TEXT("\x0b");
SEND_TEXT(message);
free(message);
} }
//after some more seconds of inactivity dim display and finally turn off //after some more seconds of inactivity dim display and finally turn off