Created
August 16, 2016 12:26
-
-
Save bitmorse/31daa3ada45a64fcdf0850f702c7941a to your computer and use it in GitHub Desktop.
Revisions
-
bitmorse created this gist
Aug 16, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,263 @@ import serial import sys import wiringpi from time import sleep import Adafruit_Nokia_LCD as LCD import Adafruit_GPIO.SPI as SPI from simplemysql import SimpleMysql from threading import Thread from PIL import Image from PIL import ImageDraw from PIL import ImageFont from slackclient import SlackClient def pretty_date(time=False): """ Get a datetime object or a int() Epoch timestamp and return a pretty string like 'an hour ago', 'Yesterday', '3 months ago', 'just now', etc """ from datetime import datetime now = datetime.now() if type(time) is int: diff = now - datetime.fromtimestamp(time) elif isinstance(time,datetime): diff = now - time elif not time: diff = now - now second_diff = diff.seconds day_diff = diff.days if day_diff < 0: return '' if day_diff == 0: if second_diff < 10: return "just now" if second_diff < 60: return str(second_diff) + " seconds ago" if second_diff < 120: return "a minute ago" if second_diff < 3600: return str(second_diff / 60) + " minutes ago" if second_diff < 7200: return "an hour ago" if second_diff < 86400: return str(second_diff / 3600) + " hours ago" if day_diff == 1: return "Yesterday" if day_diff < 7: return str(day_diff) + " days ago" if day_diff < 31: return str(day_diff / 7) + " weeks ago" if day_diff < 365: return str(day_diff / 30) + " months ago" return str(day_diff / 365) + " years ago" def notify_octanis_slack(name): token = "xoxp-..." # found at https://api.slack.com/web#authentication sc = SlackClient(token) print sc.api_call( "chat.postMessage", channel='#random', text="Somebody checked in at Hackuarium. ", username='Hackuarium Checkpoint', icon_emoji=':key:' ) def notify_hackuarium_slack(name): token = "xoxp-..." # found at https://api.slack.com/web#authentication sc = SlackClient(token) print sc.api_call( "chat.postMessage", channel='#_random', text="Somebody arrived at Hackuarium!", username='Hackuarium Checkpoint', icon_emoji=':wave:' ) def reset_rfid_reader(): wiringpi.digitalWrite(18, 0) sleep(0.1) wiringpi.digitalWrite(18, 1) def setup_display(disp): # Clear display. disp.clear() disp.display() # Create blank image for drawing. # Make sure to create image with mode '1' for 1-bit color. image = Image.new('1', (LCD.LCDWIDTH, LCD.LCDHEIGHT)) # Get drawing object to draw on image. draw = ImageDraw.Draw(image) draw.rectangle((0,0,LCD.LCDWIDTH,LCD.LCDHEIGHT),outline=255,fill=255) return draw,image def render(disp,image): # Display image. disp.image(image) disp.display() def welcome_msg(disp,font): draw,image = setup_display(disp) draw.text((10,5), 'Welcome to', font=font) draw.text((8,15), 'Hackuarium!', font=font) draw.text((0,32), 'Check in here.', font=font) render(disp,image) def success_msg(disp, name, font): draw,image = setup_display(disp) draw.text((0,5), 'Welcome back,', font=font) draw.text((0,30), name + " <3", font=font) render(disp,image) def failure_msg(disp, id, font): draw,image = setup_display(disp) draw.text((0,5), 'Whooooooo', font=font) draw.text((0,12), 'are you?', font=font) draw.text((0,19), 'Who, who,', font=font) draw.text((0,28), 'who, who?', font=font) render(disp,image) def log_swipe(db,mifare_card_id,authorised): db.insert("logs", {"mifare_card_id": mifare_card_id, "authorised":authorised}) db.commit() def is_card_authorised(db, id): user = db.getOne("users", ["name","groups"], ("mifare_card_id LIKE %s",[id])) if user: print("Found user:"+ user.name) return 1,user else: return 0,None def cycle_checkins_today(db,disp,font): #query db for checkins today logs = db.getAll("logs",["mifare_card_id", "timestamp"],("timestamp >= DATE_ADD(NOW(), INTERVAL -12 HOUR)",[])) if logs: i=0 previous_id=None while(i<len(logs)): id = logs[i].mifare_card_id if previous_id != id: timestamp = logs[i].timestamp authorised, user = is_card_authorised(db,id) if authorised: draw,image = setup_display(disp) draw.text((0,5), user.name, font=font) draw.text((0,14), 'checked in', font=font) draw.text((0,22), pretty_date(timestamp), font=font) render(disp,image) sleep(10) previous_id = id i+=1 authorised=0 def rfid_reader(db, ser, disp, font): #rfid reader requires a reset after every card read *rolls eyes* reset_rfid_reader() welcome_msg(disp,font) line = "" while True: for c in ser.read(): line += c if c == '\n': if "Series Number:" in line: id = line.split(':', 1)[1].rstrip() authorised,user = is_card_authorised(db,id) if(authorised): success_msg(disp, user.name, font) if("octanis" in user.groups): notify_octanis_slack(user.name) if("hackuarium" in user.groups): notify_hackuarium_slack(user.name) print("Authorised id:"+id) else: failure_msg(disp, id,font) print("Unauthorised id:"+id) log_swipe(db,id,authorised) ser.reset_input_buffer() reset_rfid_reader() line = "" break db.close() ser.close() def slideshow(db, disp, font): while(1): welcome_msg(disp,font) sleep(6) cycle_checkins_today(db,disp,font) # MAIN DEFINITIONS # Raspberry Pi software SPI config: SCLK = 11 DIN = 10 DC = 23 RST = 24 CS = 8 RFID_RESET = 18 DISPLAY_CONTRAST=60 def main(): #setup reset pin wiringpi.wiringPiSetupGpio() wiringpi.pinMode(RFID_RESET, 1) # Software SPI usage (defaults to bit-bang SPI interface): disp = LCD.PCD8544(DC, RST, SCLK, DIN, CS) disp.begin(contrast=DISPLAY_CONTRAST) #mysql setup db = SimpleMysql( host=" ", db=" ", user=" ", passwd=" ", keep_alive=False # try and reconnect timedout mysql connections? ) #rfid serial port setup ser = serial.Serial( port='/dev/ttyAMA0',\ baudrate=115200,\ parity=serial.PARITY_NONE,\ stopbits=serial.STOPBITS_ONE,\ bytesize=serial.EIGHTBITS,\ timeout=None) #display font font = ImageFont.truetype(sys.path[0]+'/PixelOperator8.ttf',8) print("connected to: " + ser.portstr) #start threads t1 = Thread(target=rfid_reader, args=(db,ser,disp,font)) t1.start() sleep(3) t2 = Thread(target=slideshow, args=(db,disp,font)) t2.start() if __name__ == "__main__": main()