Saturday, January 3, 2009

More on the RFID updater

In the spirit of full disclosure, I thought I would describe a bit more of the internals of how the RFID Updater works for those who might be interested.

Here is what it actually looks like in Facebook:


This is generated by three different PHP files.

rfid_test.php - This one actually does the interaction with the serial port on my Gumstix to read the value of the most recent RFID card:


<?php
include "php_serial.class.php";
$tagfile = 'tag.txt';

// configure the serial port using php_serial.class.php
$serial = new phpSerial;
$serial->deviceSet("/dev/ttyS2");
$serial->confBaudRate(9600);
$serial->confParity("none");
$serial->confCharacterLength(8);
$serial->confStopBits(1);
$serial->confFlowControl("none");
$serial->deviceOpen();

while(1){
$rfidTag = $serial->readPort();
if ($rfidTag != NULL) {
$filehandle = fopen($tagfile, "w");
$rfidTagTrim = trim($rfidTag, "\x02..\x03");
$rfidTagShort = substr($rfidTagTrim,7,5);
print("The shortened tag is $rfidTagShort\n");
fwrite($filehandle,$rfidTagShort);
fclose($filehandle);
if (strlen($rfidTagTrim) < 10) {
echo "oops";
}
}
usleep(1500000);
// $serial->flush;
}
?>


This writes the RFID tag number to a small file in the application directory. Note that this references the highly useful "php_serial.class.php" class which can be found at this location. I would be lost without the ability to interact with the serial port!

facebook_rfid.php - This presents the screen shown up above in Facebook and some basic info about me as a user and my last status. Most importantly, it calls up the "iFrame"!


<?php
// Copyright 2008 Chris Armour. All Rights Reserved.
//
// Application: RFID Updater
//
// RFID updater updates your status based on various RFID tokens set
//up in the system.
//

require_once 'facebook.php';

$appapikey = 'XXXXXXXXXXXXXXXXXXX';
$appsecret = 'XXXXXXXXXXXXXXXXXXX';
$facebook = new Facebook($appapikey, $appsecret);
$facebook->require_frame();
$user_id = $facebook->require_login();

echo "<img style='width: 49px; height: 50px; float: left;' alt='' src='http://gumstix.dlinkddns.com/rfid_update/rfid_components_large.gif'>";
echo "<h1> Radio Frequency ID Tag Status Updater</h1>";
echo "<br>";
echo "<br>";
echo "<br>";
echo "<fb:profile-pic uid='$user_id' linked='true' />";
echo "<p>Hello, <fb:name uid='$user_id' useyou='false'/>!</p>";
echo "<p>$user_id</p>";
echo "<p>Current status is: <fb:user-status uid='$user_id' linked='true'/></p>";
echo "<fb:prompt-permission perms='status_update'>Would you like to receive status updates from our application?</fb:prompt-permission>";
echo "<fb:prompt-permission perms='offline_access'>Do you want this application to have offline acceess?</fb:prompt-permission>";
echo "<fb:iframe src='http://gumstix.dlinkddns.com/rfid_update/run_script.php' style= 'width: 99%;height:350px' smartsize='false' frameborder='yes'>";
echo "</fb:iframe>";
?>


The interesting thing to note here is line "$facebook->require_frame();". This was actually MISSING from the sample application provided by Facebook and without it nothing worked! It took a while to figure this out.

run_script.php - Finally, the actual script that changes the darned status! This is what runs inside the "iFrame". Why did I do it this way? Because, the main application PHP script cannot run an auto-refresh. With no refresh, it never bothers to detect the new RFID card!! So, the solution is to have a window running an iFrame (which is basically a window running another web page) that then has an auto-refresh which checks the RFID tag file periodically to see if it has changed. If it changes, then it spits out a new Facebook update.

Here is the script:


<?php
// Copyright 2008 Chris Armour. All Rights Reserved.
//
// Application: This is the script that actually detects the stat change and updates the status.
//
// RFID updater updates your status based on various RFID tokens set
//up in the system.
//

$logfile = 'log.txt';
$tagfile = 'tag.txt';
$filehandle1 = fopen($logfile, "r");
$filehandle2 = fopen($tagfile, "r");
$old_state = fread($filehandle1, filesize($logfile));
$tag_num = fread($filehandle2, filesize($tagfile));
fclose($filehandle1);
fclose($filehandle2);
require_once 'facebook.php';
$appapikey = 'XXXXXXXXXXXXXXXXXXXX';
$appsecret = 'XXXXXXXXXXXXXXXXX';
$facebook = new Facebook($appapikey, $appsecret);


echo "<!DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>";
echo "<html>";
echo "<head>";
echo "<meta content='text/html; charset=ISO-8859-1' http-equiv='content-type'>";
echo "<meta http-equiv='refresh' content='10'>";
echo "</head>";
echo "<body>";
$csv = "588777472";


if ($tag_num == $old_state){
echo "<p>Place an RFID tag near the reader to update your status.<p>";
}
elseif ($tag_num != $old_state){
switch($tag_num){
case "51EAE":
$result = $facebook->api_client->Users_setStatus('is gone for a workout.',false);
echo "<p>Status changed to 51EAE - gone for a workout.</p>";
echo "<p>Return code is = $result</p>";
$result=$facebook->api_client->notifications_sendEmail($csv,"RFID Status now gone for a workout", "RFID Updater has changed your status to Gone for a workout","<b><i><u>RFID Updater has reset status to gone for a workout.</u></i></b>");
break;
case "A503F":
$result = $facebook->api_client->Users_setStatus('is not in the office',false);
echo "<p>Status changed to A503F - not in the office</p>";
echo "<p>Return code is = $result</p>";
$result=$facebook->api_client->notifications_sendEmail($csv,"RFID Status now not in the office", "RFID Updater has reset your status to not in the office","<b><i><u>RFID Updater has reset your status to not in the office.</u></i></b>");
break;
case "12B8F":
$result = $facebook->api_client->Users_setStatus('is at work.',false);
echo "<p>Status changed to 12B8F - at work</p>";
echo "<p>Return code is = $result</p>";
$result=$facebook->api_client->notifications_sendEmail($csv,"RFID Status is at work", "RFID Updater has reset your status to at work","<b><i><u>RFID Updater has reset your status to at work.</u></i></b>");
break;
case "48EEF":
$result = $facebook->api_client->Users_setStatus('is testing the RFID updater',false);
echo "<p>Status changed to 48EEF - testing</p>";
echo "<p>Return code is = $result</p>";
$result=$facebook->api_client->notifications_sendEmail($csv,"RFID Status now Testing", "RFID Updater has reset your status to testing","<b><i><u>RFID Updater has reset your status to testing.</u></i></b>");
break;
case "5BC0C":
$result = $facebook->api_client->Users_setStatus('is watching TV',false);
echo "<p>status changed to 5BC0C - watching TV</p>";
echo "<p>Return code is = $result</p>";
$result=$facebook->api_client->notifications_sendEmail($csv,"RFID Status now watching TV", "RFID Updater has reset your status to watching TV","<b><i><u>RFID Updater has reset your status to watching TV.</u></i></b>");
break;
default:
echo "<p>Card not read. Try again.</p>";
}
}
echo "</body>";
echo "</html>";

$old_state = $tag_num;
$filehandle3 = fopen($logfile, "w");
fwrite($filehandle3,$old_state);
fclose($filehandle3);

?>


No comments:

Post a Comment