Skip to content

Instantly share code, notes, and snippets.

@yummytech
Created July 11, 2013 16:36
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yummytech/5977037 to your computer and use it in GitHub Desktop.
Save yummytech/5977037 to your computer and use it in GitHub Desktop.
#----------------------------------------------------------------------
# Flomio, Inc. - Copyright 2011
# Author: Richard Grundy
# Date: 01/23/2011
#
# File: flomio_client.py
#
# Description: This Flomio Client enables the scanning of RFIDs
# via a COTS NFC Reader based on the NXP PN533 chipset. It leverages
# both the USB and PC/SC interfaces to talk to the readers depending
# on thier implementation. Successful scans are then reported to the
# cloud via the Flomio API v1.
#
# Version: 0.1
#----------------------------------------------------------------------
# To run this script you will only need:
# Python v2.6.6 (http://python.org/ftp/python/2.6.6/python-2.6.6.msi)
# (http://www.python.org/ftp/python/2.6.7/Python-2.6.7.tgz)
# and
# Pyscard module (http://sourceforge.net/projects/pyscard/files/pyscard/pyscard%201.6.12/pyscard-1.6.12.win32-py2.6.msi)
# (http://sourceforge.net/projects/pyscard/files/pyscard/pyscard%201.6.12/pyscard-1.6.12-py2.6-macosx10.6.mpkg.zip)
# and
# PyAudio module (http://people.csail.mit.edu/hubert/pyaudio/packages/pyaudio-0.2.4.py26.exe)
# (http://people.csail.mit.edu/hubert/pyaudio/packages/pyaudio-0.2.4.dmg)
# and
# NfcPy module (https://code.launchpad.net/~richard-p7/nfcpy/pcsc)
#----------------------------------------------------------------------
import sys, os
from flomio_api import *
sys.path.insert(0,os.path.abspath("flomio_libs"))
import nfc
import nfc.ndef
import nfc.ndef.Text
from time import sleep
from array import array
# for debugging purpose... place pdb.set_trace() in debug spot
import pdb
#--------------------------CONTSTANTS----------------------------------
# Twilio REST API version
API_VERSION = '1.0'
# FLomio AccountSid and AuthToken
# ACCOUNT_EMAIL = 'richard.grundy@gmail.com'
# ACCOUNT_SECRET = 'jLo6dOOWBhsF3TqqnGJgZLCadBBSPSxe'
# APP_SECRET = 'YOL9IRJ8j8WqgSzHyPT2OK7qZSuo3yjH'
ACCOUNT_EMAIL = 'patrick.deuley@gmail.com'
ACCOUNT_SECRET = 'w3gZszds3pkzHITZrXnc2UsJrS6FyC7b'
APP_SECRET = 'ptfeHIHOnLea289mVblbCdx7TUGhSd5u'
# Initialize Object ID's
TAG_UID = '' #retrieved from tag
READER_UID = '' #retrieved from reader SAM card
# Reader configurations
LED_GREEN = [0xFF,0x00,0x40,0x1E, # APDU to change LED to GREEN
0x04,0x00,0x00,0x00,
0x00]
LED_ORANGE = [0xFF,0x00,0x40,0x0F, # APDU to change LED to ORANGE
0x04,0x00,0x00,0x00,
0x00]
LED_RED = [0xFF,0x00,0x40,0x9D, # APDU to change LED to RED
0x04,0x00,0x00,0x00,
0x00]
LED_GREEN_BLINKING = [0xFF,0x00, # APDU for LED blinking GREEN (4s)
0x40,0xAE,0x04,0x01,
0x01,0x05,0x00]
LED_RED_SOLID = [0xFF,0x00,0x40, # APDU for LED solid RED (1s)
0x9D,0x04,0x04,0x00,
0x01,0x00]
LED_GREEN_SOLID = [0xFF,0x00, # APDU for LED solid GREEN (1s)
0x40,0xAE,0x04,0x04,
0x00,0x01,0x00]
GET_READER_UID = [0x80,0x14,0x00, # APDU for ACOS6 SAM card UID
0x00,0x08]
#----------------------------------------------------------------------
from threading import *
import thread
def timeout(timeout_time):
def get_function(f):
def get_args(*args):
def timeout_handler():
thread.interrupt_main()
t = Timer(timeout_time, timeout_handler)
t.start()
retval = f()
t.cancel()
return retval
return get_args
return get_function
try:
import pyaudio
import wave
except: # create an empty usb class and instantiate it
def PlaySound(wave_file):
return
else:
def PlaySound(wave_file):
""" Play a WAVE file. """
chunk = 1024
wf = wave.open(wave_file, 'rb')
p = pyaudio.PyAudio()
# open stream
stream = p.open(format =
p.get_format_from_width(wf.getsampwidth()),
channels = wf.getnchannels(),
rate = wf.getframerate(),
output = True)
# read data
data = wf.readframes(chunk)
# play stream
while data != '':
stream.write(data)
data = wf.readframes(chunk)
stream.close()
p.terminate()
class _Getch:
"""Gets a single character from standard input. Does not echo to the
screen."""
def __init__(self):
try:
self.impl = _GetchWindows()
except ImportError:
try:
self.impl = _GetchMacCarbon()
except AttributeError:
self.impl = _GetchUnix()
def __call__(self): return self.impl()
class _GetchUnix:
def __init__(self):
import tty, sys, termios # import termios now or else you'll get the Unix version on the Mac
def __call__(self):
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
class _GetchWindows:
def __init__(self):
import msvcrt
def __call__(self):
import msvcrt
return msvcrt.getch()
class _GetchMacCarbon:
"""
A function which returns the current ASCII key that is down;
if no ASCII key is down, the null string is returned. The
page http://www.mactech.com/macintosh-c/chap02-1.html was
very helpful in figuring out how to do this.
"""
def __init__(self):
import Carbon
Carbon.Evt #see if it has this (in Unix, it doesn't)
def __call__(self):
import Carbon
if Carbon.Evt.EventAvail(0x0008)[0]==0: # 0x0008 is the keyDownMask
return ''
else:
#
# The event contains the following info:
# (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]
#
# The message (msg) contains the ASCII char which is
# extracted with the 0x000000FF charCodeMask; this
# number is converted to an ASCII character with chr() and
# returned
#
(what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1]
return chr(msg & 0x000000FF)
#----------------------------------------------------------------------
#@timeout(5)
def main():
# Drop in the Scan API reserved only for the flomio_core library
ENDPOINTS['v1'].update({'create_scan':'%s/api/v1/scan/create/' % API_URL})
def create_scan(reader=None, tag=None):
"""
Reports a scan (reader+tag) to the Flomio platform
usage:
>>> flomio = Flomio('auston.bunsen@gmail.com','dkQNJN44gafujGf6LRLjtNYuk5PdhfzO','v1'])
>>> scan(reader='0x04DEEDEE33', tag='0x04FEEDBEE3')
"""
if not flomio.app_id: return {'status':'error', 'message':'not using a valid app object'}
if not reader or not tag: return {'status':'error', 'message':'missing a reader uuid or tag uuid'}
params = flomio._sign_request(flomio.app_secret, {'app_id':flomio.app_id, 'reader_uuid':reader, 'tag_uuid': tag})
response = flomio._request(uri=ENDPOINTS[flomio.version]['create_scan'], params=params, method='POST')
return json.loads(response)
# return response
# Create a Flomio REST account object using your Flomio account ID and token
flomio = 0 #Flomio(ACCOUNT_EMAIL,ACCOUNT_SECRET,"v1")
#flomio.app(APP_SECRET)
try:
#mode=str(raw_input("Barcode or NFC? (default \"nfc\")"))
mode="nfc"
except ValueError:
print "Not a string"
else:
if (mode=="barcode"):
while True:
# Create a new Checkin TAG_UID. Uses a HTTP POST
TAG_UID = str(raw_input("Please scan a tag\n"))
# print 'Press a key'
# inkey = _Getch()
# import sys
# for i in xrange(sys.maxint):
# k=inkey()
# if k!='':break
# TAG_UID = k
READER_UID = "0x3533D51272DD09"
print TAG_UID
d = {
'uuid' : TAG_UID,
'rf_addr' : READER_UID,
}
response = create_scan(reader=READER_UID, tag=TAG_UID)
print response
if response['status'] == 'error':
PlaySound('feud_strike.wav')
print response
else:
PlaySound('sonic_coin.wav')
print "Scan accepted!"
elif (mode is "") or (mode=="nfc"):
clf = nfc.ContactlessFrontend()
print "Please scan a tag"
while True:
tag = clf.poll()
if tag:
# Create a new Checkin TAG_UID. Uses a HTTP POST
TAG_UID = "0x"+array("B",tag.uid).tostring().encode("hex").upper()
READER_UID = "0x"+array("B",clf.dev.dev.dh.transmit(GET_READER_UID)[0]).tostring().encode("hex").upper()
READER_UID = READER_UID[:16]
print TAG_UID # +' '+ READER_UID
d = {
'uuid' : TAG_UID,
'rf_addr' : READER_UID,
}
#response = create_scan(reader=READER_UID, tag=TAG_UID)
#print response
#response = flo.resource(APP_SECRET)
#if response['status'] == 'error':
#PlaySound('feud_strike.wav')
clf.dev.dev.dh.transmit(LED_RED_SOLID) # Send reader the LED raw command
#print response
#else:
#clf.dev.dev.dh.transmit(LED_GREEN_BLINKING) # Send reader the LED raw command
PlaySound('sonic_coin.wav')
#print "Scan accepted!"
clf.dev.dev.dh.transmit(LED_GREEN) # Send reader the LED raw command
if __name__ == '__main__':
main()
# try:
# main()
# except:
# print "All done."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment