commit e74970e44fbb91c7bf380974f3ac43ae3bdc31c3 Author: Will Bradley Date: Fri Jul 5 22:59:35 2019 -0700 Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..7582a78 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Open Access Control API + +This Ruby script listens to a USB serial port, parses console input, and parses serial information from the Open Access Control v4 (software 1.4) board. + +Right now it just does a 1:1 translation, later it will implement a JSON API. diff --git a/api.rb b/api.rb new file mode 100644 index 0000000..fa95f5c --- /dev/null +++ b/api.rb @@ -0,0 +1,213 @@ +require 'rubyserial' + +# 9600 baud, 8 data bits, and no parity +serial = Serial.new '/dev/ttyUSB0', 9600, 8, :none +@buffer = Queue.new + +def console_in(serial) + run = true + while run + # Get console input + cline = gets + unless cline.nil? + case cline + when /^d/ + serial.write("d\r") + when /^s (\d+)/ + serial.write("s #{$1}\r") + when /^m (\d+) ([\dA-F]+) (\d+)/ + serial.write("m #{$1} #{$2} #{$3}\r") + when /^a/ + serial.write("a\r") + when /^r (\d+)/ + serial.write("r #{$1}\r") + when /^o (\d+)/ + serial.write("o #{$1}\r") + when /^u/ + serial.write("u\r") + when /^l/ + serial.write("l\r") + when /^1/ + serial.write("1\r") + when /^2/ + serial.write("2\r") + when /^3/ + serial.write("3\r") + when /^9/ + serial.write("9\r") + when /^t (\d+) (\d+) (\d+) (\d+) (\d+) (\d+) (\d+)/ + serial.write("t #{$1} #{$2} #{$3} #{$4} #{$5} #{$6} #{$7}\r") + when /^e (\d+)/ + serial.write("e #{$1}\r") + when /^h (\d+)/ + serial.write("h #{$1}\r") + when /^?/ + serial.write("?\r") + end + end + end +end + +def serial_in(serial) + run = true + readbuffer = "" + + while run + # begin + # Get serial input char by char + sdata = serial.read(1) + # If we have data + unless sdata == "" + # Look for newlines + if /\n|\r/.match(sdata) + # Flush the existing buffer and reset + @buffer.push(readbuffer) + readbuffer = "" + else + # Append non-newlines to the buffer + readbuffer += sdata + end + end + # rescue Exception => e + # print e + # sline = nil + # end + end +end + +def parse_in + run = true + + while run + sline = @buffer.pop() + if sline != "" + case sline + when /(\d*) unlocked$/ # ends line + print ">Door #{$1} unlocked\n" + when /All Doors relocked/ + print ">All Doors relocked\n" + when /Door (\d*) locked$/ # ends line + print ">Door #{$1} locked\n" + when /User ([\dA-F]*) presented tag at reader (\d)/ + print ">User #{$1} presented tag at reader #{$2}\n" + when /User ([\dA-F]*) granted access at reader (\d)/ + print ">User #{$1} granted access at reader #{$2}\n" + when /User ([\dA-F]*) denied access at reader (\d)/ + print ">User #{$1} denied access at reader #{$2}\n" + when /Command ([\dA-F]*) entered at reader (\d)/ + print ">Command #{$1} entered at reader #{$2}\n" + when /Zone (\d?) sensor activated/ + print ">Zone #{$1} sensor activated\n" + when /User (\d?) unlocked door (\d)/ + print ">User #{$1} unlocked door #{$2}\n" + when /Door 1 locked for (\d+) bed time/ + print "Door 1 locked for #{$1} bed time\n" + when /User (\d+) locked out/ + print "User #{$1} locked out\n" + when /User (\d+) locked out/ + print "User #{$1} locked out\n" + when /Sensor (\d+) value:(\d+)/ + print "Sensor #{$1} value:#{$2}\n" + when /Alarm triggered/ + print "Alarm triggered\n" + when /Alarm level changed to (\d*)/ + print ">Alarm level changed to #{$1}\n" + when /Alarm armed level changed to (\d*)/ + print ">Alarm armed level changed to #{$1}\n" + when /User database erased/ + print "User database erased\n" + when /Invalid user modify attempted/ + print "Invalid user modify attempted\n" + when /User (\d*) successfully modified/ + print ">User #{$1} successfully modified\n" + when /Invalid user delete attempted/ + print "Invalid user delete attempted\n" + when /User deleted at position (\d*)/ + print "User deleted at position #{$1}\n" + when /User deleted at position (\d*)/ + print ">User deleted at position #{$1}\n" + when /User (\d+) authenticated/ + print "User #{$1} authenticated\n" + when /User not found/ + print "User not found\n" + when /Bad user number/ + print "Bad user number\n" + when /User dump started/ + print ">User dump started\n" + when /Invalid door number/ + print "Invalid door number\n" + when /Alarm armed state \(1=armed\):(\d*)/ + print ">Alarm armed state: #{$1}\n" + when /Alarm siren state \(1=activated\):(\d*)/ + print ">Alarm siren state: #{$1}\n" + when /Front door open state \(0=closed\):(\d*)/ + print ">Front door open state: #{$1}\n" + when /Roll up door open state \(0=closed\):(\d*)/ + print ">Roll up door open state: #{$1}\n" + when /Door 1 unlocked state\(1=locked\):(\d*)/ + print ">Door 1 unlocked state: #{$1}\n" + when /Door 2 unlocked state\(1=locked\):(\d*)/ + print ">Door 2 unlocked state: #{$1}\n" + when /^(\d+)\t+(\d+)\t+([\dA-Fa-f]+)$/ + print ">User #{$1} mask #{$2} tag #{$3}\n" # User dump info + when /Priveleged mode enabled./ + print ">Priveleged mode enabled.\n" + when /Priveleged mode disabled./ + print ">Priveleged mode disabled.\n" + when /Access Denied. Priveleged mode is not enabled./ + print ">Access Denied. Priveleged mode is not enabled.\n" + when /Valid commands are/ + print "?Valid commands are\n" # Help output + when /^\(/ + print "?"+sline+"\n" # Help output + when /^ / + print "?"+sline+"\n" # Help output + when /^[\d:]{5,8}\s+[\d\/]{5,8}\s+[A-Z]{3}\s+$/ + print ">"+sline+"\n" # Date output only + when /^Old time :([\d:]{5,8})\s+([\d\/]{5,8})\s+([A-Z]{3})\s+$/ + print ">Old time: #{$1} #{$2} #{$3}\n" + when /^New time :([\d:]{5,8})\s+([\d\/]{5,8})\s+([A-Z]{3})\s+$/ + print ">New time: #{$1} #{$2} #{$3}\n" + when /Reader1-0:(\d*)/ + print ">Reader1-0:#{$1}\n" # Status output + when /Reader1-1:(\d*)/ + print ">Reader1-1:#{$1}\n" # Status output + when /Reader2-0:(\d*)/ + print ">Reader2-0:#{$1}\n" # Status output + when /Reader2-1:(\d*)/ + print ">Reader2-1:#{$1}\n" # Status output + when /Zone 1:(\d*)/ + print ">Zone 1:#{$1}\n" # Status output + when /Zone 2:(\d*)/ + print ">Zone 2:#{$1}\n" # Status output + when /Zone 3:(\d*)/ + print ">Zone 3:#{$1}\n" # Status output + when /Zone 4:(\d*)/ + print ">Zone 4:#{$1}\n" # Status output + when /Zone TAMP:(\d*)/ + print ">Zone TAMP:#{$1}\n" # Status output + when /Relays and LEDs ([a-z]*)/ + print ">Relays and LEDs #{$1}\n" # Status output + when /Relays and LEDs ([a-z]*)/ + print ">Relays and LEDs #{$1}\n" # Status output + when /UserNum: Usermask: TagNum:/ + # print nothing, we don't care + when /Pass: / + # print nothing, we don't care + when /^\d+$/ + # print nothing, we don't care + else + print "ERR: UNKNOWN: "+sline.inspect+"\n" # Error output + end + end + end +end + +puts "> Started threads at #{Time.now}" +t1 = Thread.new{console_in(serial)} +t2 = Thread.new{serial_in(serial)} +t3 = Thread.new{parse_in} +t1.join +t2.join +t3.join +puts "> End threads at #{Time.now}" \ No newline at end of file